[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