[PATCH 19/20] net: dwc_eth_qos_rockchip: Add support for RK3576
Heiko Stuebner
heiko at sntech.de
Thu Nov 21 15:27:30 CET 2024
Add rk_gmac_ops and other special handling that is needed for GMAC to
work on RK3576.
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
drivers/net/dwc_eth_qos.c | 4 +
drivers/net/dwc_eth_qos_rockchip.c | 141 ++++++++++++++++++++++++++++-
2 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 2279481d935..1a05d285576 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1615,6 +1615,10 @@ static const struct udevice_id eqos_ids[] = {
.compatible = "rockchip,rk3568-gmac",
.data = (ulong)&eqos_rockchip_config
},
+ {
+ .compatible = "rockchip,rk3576-gmac",
+ .data = (ulong)&eqos_rockchip_config
+ },
{
.compatible = "rockchip,rk3588-gmac",
.data = (ulong)&eqos_rockchip_config
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
index 9fc8c686b88..7115fe49bd5 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -131,6 +131,132 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
return 0;
}
+#define RK3576_SDGMAC_GRF_GMAC0_CON 0x020
+#define RK3576_SDGMAC_GRF_GMAC1_CON 0x024
+
+#define RK3576_GMAC_CLK_RMII_MODE GRF_BIT(3)
+#define RK3576_GMAC_CLK_RGMII_MODE GRF_CLR_BIT(3)
+
+#define RK3576_GMAC_CLK_RMII_DIV2 GRF_BIT(5)
+#define RK3576_GMAC_CLK_RMII_DIV20 GRF_CLR_BIT(5)
+#define RK3576_GMAC_CLK_RGMII_DIV1 (GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
+#define RK3576_GMAC_CLK_RGMII_DIV5 (GRF_BIT(5) | GRF_BIT(6))
+#define RK3576_GMAC_CLK_RGMII_DIV50 (GRF_CLR_BIT(5) | GRF_BIT(6))
+
+/* FIXME-check: in TRM swapped compared to rk3588 */
+#define RK3576_GMAC_CLK_SELECT_IO GRF_BIT(7)
+#define RK3576_GMAC_CLK_SELECT_CRU GRF_CLR_BIT(7)
+
+#define RK3576_GMAC_CLK_GATE GRF_BIT(0)
+#define RK3576_GMAC_CLK_NOGATE GRF_CLR_BIT(0)
+
+#define RK3576_IOC_GRF_MISC_CON2 0x6408
+#define RK3576_IOC_GRF_MISC_CON3 0x640c
+#define RK3576_IOC_GRF_MISC_CON4 0x6410
+#define RK3576_IOC_GRF_MISC_CON5 0x6414
+
+#define RK3576_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
+#define RK3576_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
+#define RK3576_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7f, 8)
+#define RK3576_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
+#define RK3576_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
+#define RK3576_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7f, 0)
+
+static int rk3576_set_to_rgmii(struct udevice *dev,
+ int tx_delay, int rx_delay)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct rockchip_platform_data *data = pdata->priv_pdata;
+ u32 delay_con_m0, delay_con_m1, con, val;
+
+ con = (data->id == 1) ? RK3576_SDGMAC_GRF_GMAC1_CON :
+ RK3576_SDGMAC_GRF_GMAC0_CON;
+ regmap_write(data->grf, con, RK3576_GMAC_CLK_RGMII_MODE);
+
+ delay_con_m0 = data->id ? RK3576_IOC_GRF_MISC_CON4 :
+ RK3576_IOC_GRF_MISC_CON2;
+ delay_con_m1 = data->id ? RK3576_IOC_GRF_MISC_CON5 :
+ RK3576_IOC_GRF_MISC_CON3;
+
+ val = RK3576_GMAC_RXCLK_DLY_ENABLE | RK3576_GMAC_TXCLK_DLY_ENABLE;
+ val |= RK3576_GMAC_CLK_RX_DL_CFG(rx_delay);
+ val |= RK3576_GMAC_CLK_TX_DL_CFG(tx_delay);
+
+ regmap_write(data->php_grf, delay_con_m0, val);
+ regmap_write(data->php_grf, delay_con_m1, val);
+
+ return 0;
+}
+
+static int rk3576_set_to_rmii(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct rockchip_platform_data *data = pdata->priv_pdata;
+ u32 con;
+
+ con = (data->id == 1) ? RK3576_SDGMAC_GRF_GMAC1_CON :
+ RK3576_SDGMAC_GRF_GMAC0_CON;
+ regmap_write(data->grf, con, RK3576_GMAC_CLK_RMII_MODE);
+
+ return 0;
+}
+
+static int rk3576_set_gmac_speed(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct rockchip_platform_data *data = pdata->priv_pdata;
+ u32 con, val;
+
+ con = (data->id == 1) ? RK3576_SDGMAC_GRF_GMAC1_CON :
+ RK3576_SDGMAC_GRF_GMAC0_CON;
+
+ switch (eqos->phy->speed) {
+ case SPEED_10:
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
+ val = RK3576_GMAC_CLK_RMII_DIV20;
+ else
+ val = RK3576_GMAC_CLK_RGMII_DIV50;
+ break;
+ case SPEED_100:
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
+ val = RK3576_GMAC_CLK_RMII_DIV2;
+ else
+ val = RK3576_GMAC_CLK_RGMII_DIV5;
+ break;
+ case SPEED_1000:
+ if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
+ val = RK3576_GMAC_CLK_RGMII_DIV1;
+ else
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_write(data->grf, con, val);
+
+ return 0;
+}
+
+static void rk3576_set_clock_selection(struct udevice *dev, bool enable)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct rockchip_platform_data *data = pdata->priv_pdata;
+ u32 con, val;
+
+ con = (data->id == 1) ? RK3576_SDGMAC_GRF_GMAC1_CON :
+ RK3576_SDGMAC_GRF_GMAC0_CON;
+
+ val = data->clock_input ? RK3576_GMAC_CLK_SELECT_IO :
+ RK3576_GMAC_CLK_SELECT_CRU;
+
+ val |= enable ? RK3576_GMAC_CLK_NOGATE :
+ RK3576_GMAC_CLK_GATE;
+
+ regmap_write(data->grf, con, val);
+}
+
/* sys_grf */
#define RK3588_GRF_GMAC_CON7 0x031c
#define RK3588_GRF_GMAC_CON8 0x0320
@@ -274,6 +400,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = {
0x0, /* sentinel */
},
},
+ {
+ .compatible = "rockchip,rk3576-gmac",
+ .set_to_rgmii = rk3576_set_to_rgmii,
+ .set_to_rmii = rk3576_set_to_rmii,
+ .set_gmac_speed = rk3576_set_gmac_speed,
+ .set_clock_selection = rk3576_set_clock_selection,
+ .regs = {
+ 0x2a220000, /* gmac0 */
+ 0x2a230000, /* gmac1 */
+ 0x0, /* sentinel */
+ },
+ },
{
.compatible = "rockchip,rk3588-gmac",
.set_to_rgmii = rk3588_set_to_rgmii,
@@ -351,7 +489,8 @@ static int eqos_probe_resources_rk(struct udevice *dev)
goto err_free;
}
- if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
+ if (device_is_compatible(dev, "rockchip,rk3588-gmac") ||
+ device_is_compatible(dev, "rockchip,rk3576-gmac")) {
data->php_grf =
syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
if (IS_ERR(data->php_grf)) {
--
2.45.2
More information about the U-Boot
mailing list