[PATCH v2 12/16] net: dwc_eth_qos_rockchip: Add support for RK3576

Heiko Stuebner heiko at sntech.de
Mon Apr 14 22:01:07 CEST 2025


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 | 154 ++++++++++++++++++++++++++++-
 2 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index d4561784a6e..b1bc422f791 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1619,6 +1619,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 3a9c46a01ec..d646d3ebac8 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -260,6 +260,145 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
 	return 0;
 }
 
+/* VCCIO0_1_3_IOC */
+#define RK3576_VCCIO0_1_3_IOC_CON2		0x6408
+#define RK3576_VCCIO0_1_3_IOC_CON3		0x640c
+#define RK3576_VCCIO0_1_3_IOC_CON4		0x6410
+#define RK3576_VCCIO0_1_3_IOC_CON5		0x6414
+
+#define RK3576_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(15)
+#define RK3576_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(15)
+#define RK3576_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(7)
+#define RK3576_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(7)
+
+#define RK3576_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 8)
+#define RK3576_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 0)
+
+/* SDGMAC_GRF */
+#define RK3576_GRF_GMAC_CON0			0x0020
+#define RK3576_GRF_GMAC_CON1			0x0024
+
+#define RK3576_GMAC_RMII_MODE			GRF_BIT(3)
+#define RK3576_GMAC_RGMII_MODE			GRF_CLR_BIT(3)
+
+#define RK3576_GMAC_CLK_SELECT_IO		GRF_BIT(7)
+#define RK3576_GMAC_CLK_SELECT_CRU		GRF_CLR_BIT(7)
+
+#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(6) | GRF_CLR_BIT(5))
+#define RK3576_GMAC_CLK_RGMII_DIV5		\
+			(GRF_BIT(6) | GRF_BIT(5))
+#define RK3576_GMAC_CLK_RGMII_DIV50		\
+			(GRF_BIT(6) | GRF_CLR_BIT(5))
+
+#define RK3576_GMAC_CLK_RMII_GATE		GRF_BIT(4)
+#define RK3576_GMAC_CLK_RMII_NOGATE		GRF_CLR_BIT(4)
+
+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 offset_con;
+
+	offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
+				     RK3576_GRF_GMAC_CON0;
+
+	regmap_write(data->grf, offset_con, RK3576_GMAC_RGMII_MODE);
+
+	offset_con = data->id == 1 ? RK3576_VCCIO0_1_3_IOC_CON4 :
+				     RK3576_VCCIO0_1_3_IOC_CON2;
+
+	/* m0 && m1 delay enabled */
+	regmap_write(data->php_grf, offset_con,
+		     DELAY_ENABLE(RK3576, tx_delay, rx_delay));
+	regmap_write(data->php_grf, offset_con + 0x4,
+		     DELAY_ENABLE(RK3576, tx_delay, rx_delay));
+
+	/* m0 && m1 delay value */
+	regmap_write(data->php_grf, offset_con,
+		     RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
+		     RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
+	regmap_write(data->php_grf, offset_con + 0x4,
+		     RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
+		     RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
+
+	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 offset_con;
+
+	offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
+				     RK3576_GRF_GMAC_CON0;
+
+	regmap_write(data->grf, offset_con, RK3576_GMAC_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 val = 0, offset_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;
+	}
+
+	offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
+				     RK3576_GRF_GMAC_CON0;
+
+	regmap_write(data->grf, offset_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 val = data->clock_input ? RK3576_GMAC_CLK_SELECT_IO :
+				      RK3576_GMAC_CLK_SELECT_CRU;
+	u32 offset_con;
+
+	val |= enable ? RK3576_GMAC_CLK_RMII_NOGATE :
+			RK3576_GMAC_CLK_RMII_GATE;
+
+	offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
+				     RK3576_GRF_GMAC_CON0;
+
+	regmap_write(data->grf, offset_con, val);
+}
+
 #define RK3588_DELAY_ENABLE(id, tx, rx) \
 	(((tx) ? RK3588_GMAC_TXCLK_DLY_ENABLE(id) : RK3588_GMAC_TXCLK_DLY_DISABLE(id)) | \
 	 ((rx) ? RK3588_GMAC_RXCLK_DLY_ENABLE(id) : RK3588_GMAC_RXCLK_DLY_DISABLE(id)))
@@ -418,6 +557,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,
@@ -495,7 +646,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.47.2



More information about the U-Boot mailing list