[U-Boot] [PATCH v2 06/18] net: gmac_rockchip: Add support for the RV1108 GMAC

David Wu david.wu at rock-chips.com
Thu Nov 9 09:02:29 UTC 2017


The rv1108 GMAC only support rmii interface, so need to add the
set_rmii() ops. Use the phy current interface to set rmii or
rgmii ops. At the same time, need to set the mac clock rate of
rmii with 50M, the clock rate of rgmii with 125M.

Signed-off-by: David Wu <david.wu at rock-chips.com>
---

Changes in v2:
- Add check whether the set rgmii/rmii function is a valid function pointer
- Use current phy interface to set mac clock rate
- Clean the grf offset at gmac_rockchip.c

 drivers/net/gmac_rockchip.c | 89 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 82 insertions(+), 7 deletions(-)

diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index 586ccbf..22e3941 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -18,6 +18,7 @@
 #include <asm/arch/grf_rk3288.h>
 #include <asm/arch/grf_rk3368.h>
 #include <asm/arch/grf_rk3399.h>
+#include <asm/arch/grf_rv1108.h>
 #include <dm/pinctrl.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include "designware.h"
@@ -37,6 +38,7 @@ struct gmac_rockchip_platdata {
 
 struct rk_gmac_ops {
 	int (*fix_mac_speed)(struct dw_eth_dev *priv);
+	void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
 	void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
 };
 
@@ -142,6 +144,41 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
 	return 0;
 }
 
+static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
+{
+	struct rv1108_grf *grf;
+	int clk, speed;
+	enum {
+		RV1108_GMAC_SPEED_MASK		= BIT(2),
+		RV1108_GMAC_SPEED_10M		= 0 << 2,
+		RV1108_GMAC_SPEED_100M		= 1 << 2,
+		RV1108_GMAC_CLK_SEL_MASK	= BIT(7),
+		RV1108_GMAC_CLK_SEL_2_5M	= 0 << 7,
+		RV1108_GMAC_CLK_SEL_25M		= 1 << 7,
+	};
+
+	switch (priv->phydev->speed) {
+	case 10:
+		clk = RV1108_GMAC_CLK_SEL_2_5M;
+		speed = RV1108_GMAC_SPEED_10M;
+		break;
+	case 100:
+		clk = RV1108_GMAC_CLK_SEL_25M;
+		speed = RV1108_GMAC_SPEED_100M;
+		break;
+	default:
+		debug("Unknown phy speed: %d\n", priv->phydev->speed);
+		return -EINVAL;
+	}
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->gmac_con0,
+		     RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
+		     clk | speed);
+
+	return 0;
+}
+
 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
 {
 	struct rk3288_grf *grf;
@@ -221,11 +258,28 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
 		     pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
 }
 
+static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
+{
+	struct rv1108_grf *grf;
+
+	enum {
+		RV1108_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
+		RV1108_GMAC_PHY_INTF_SEL_RMII  = 4 << 4,
+	};
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->gmac_con0,
+		     RV1108_GMAC_PHY_INTF_SEL_MASK,
+		     RV1108_GMAC_PHY_INTF_SEL_RMII);
+}
+
 static int gmac_rockchip_probe(struct udevice *dev)
 {
 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
 	struct rk_gmac_ops *ops =
 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
+	struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
+	struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
 	struct clk clk;
 	int ret;
 
@@ -233,13 +287,27 @@ static int gmac_rockchip_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	/* Since mac_clk is fed by an external clock we can use 0 here */
-	ret = clk_set_rate(&clk, 0);
-	if (ret)
-		return ret;
-
-	/* Set to RGMII mode */
-	ops->set_to_rgmii(pdata);
+	switch (eth_pdata->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+		ret = clk_set_rate(&clk, 125000000);
+		if (IS_ERR_VALUE(ret))
+			return ret;
+		/* Set to RGMII mode */
+		if (ops->set_to_rgmii)
+			ops->set_to_rgmii(pdata);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		ret = clk_set_rate(&clk, 50000000);
+		if (IS_ERR_VALUE(ret))
+			return ret;
+		/* Set to RMII mode */
+		if (ops->set_to_rmii)
+			ops->set_to_rmii(pdata);
+		break;
+	default:
+		debug("NO interface defined!\n");
+		return -ENXIO;
+	}
 
 	return designware_eth_probe(dev);
 }
@@ -289,6 +357,11 @@ const struct rk_gmac_ops rk3399_gmac_ops = {
 	.set_to_rgmii = rk3399_gmac_set_to_rgmii,
 };
 
+const struct rk_gmac_ops rv1108_gmac_ops = {
+	.fix_mac_speed = rv1108_set_rmii_speed,
+	.set_to_rmii = rv1108_gmac_set_to_rmii,
+};
+
 static const struct udevice_id rockchip_gmac_ids[] = {
 	{ .compatible = "rockchip,rk3288-gmac",
 	  .data = (ulong)&rk3288_gmac_ops },
@@ -296,6 +369,8 @@ static const struct udevice_id rockchip_gmac_ids[] = {
 	  .data = (ulong)&rk3368_gmac_ops },
 	{ .compatible = "rockchip,rk3399-gmac",
 	  .data = (ulong)&rk3399_gmac_ops },
+	{ .compatible = "rockchip,rv1108-gmac",
+	  .data = (ulong)&rv1108_gmac_ops },
 	{ }
 };
 
-- 
2.7.4




More information about the U-Boot mailing list