Message ID | 1506003867-34811-1-git-send-email-david.wu@rock-chips.com |
---|---|
State | Superseded |
Delegated to: | Philipp Tomsich |
Headers | show |
Series | Add gmac support for rk3399-evb and rv1108-evb | expand |
> The rv1108 mac only support rmii interface, so need to add the > set_rmii() ops. Use the phy current interface to set rmii or > rgmii ops. > > Signed-off-by: David Wu <david.wu@rock-chips.com> > --- > > drivers/net/gmac_rockchip.c | 67 +++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 65 insertions(+), 2 deletions(-) > Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
On Thu, 21 Sep 2017, David Wu wrote: > The rv1108 mac only support rmii interface, so need to add the > set_rmii() ops. Use the phy current interface to set rmii or > rgmii ops. > > Signed-off-by: David Wu <david.wu@rock-chips.com> > Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> See below for required changes. > --- > > drivers/net/gmac_rockchip.c | 67 +++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 65 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c > index 26f7a96..16b8c2b 100644 > --- a/drivers/net/gmac_rockchip.c > +++ b/drivers/net/gmac_rockchip.c > @@ -37,6 +37,7 @@ struct gmac_rockchip_platdata { > struct rk_gmac_ops { > int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata, > struct dw_eth_dev *priv); > + void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); > void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); > }; > > @@ -177,6 +178,40 @@ static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, > return 0; > } > > +static int rv1108_set_rmii_speed(struct gmac_rockchip_platdata *pdata, > + struct dw_eth_dev *priv) > +{ > + 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; > + } > + > + rk_clrsetreg(pdata->grf, > + 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_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; > @@ -292,6 +327,18 @@ 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) > +{ > + enum { > + RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), > + RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4, > + }; > + > + rk_clrsetreg(pdata->grf, > + 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); > @@ -325,8 +372,12 @@ static int gmac_rockchip_probe(struct udevice *dev) > pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + > data->grf_offset; > > - /* Set to RGMII mode */ > - ops->set_to_rgmii(pdata); > + if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RGMII) > + ops->set_to_rgmii(pdata); > + else if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RMII) > + ops->set_to_rmii(pdata); If we have multiple functions and some are optional (e.g. the set_to_rmii is only ever set to anything other than NULL for the RV1108), we need to check whether this is a valid function pointer and emit an error otherwise. With the current code, we'll end up in a SEGV/SYNC-ABORT eventually... Please protect dispatches through a function pointer, if these pointers could be NULL. > + else > + debug("NO interface defined!\n"); Looks like a case for a switch statement. > > return designware_eth_probe(dev); > } > @@ -392,6 +443,16 @@ const struct gmac_rockchip_driver_data rk3399_gmac_data = { > .grf_offset = 0xc214, > }; > > +const struct rk_gmac_ops rv1108_gmac_ops = { > + .fix_mac_speed = rv1108_set_rmii_speed, > + .set_to_rmii = rv1108_gmac_set_to_rmii, > +}; > + > +const struct gmac_rockchip_driver_data rv1108_gmac_data = { > + .ops = &rv1108_gmac_ops, > + .grf_offset = 0x900, > +}; > + > static const struct udevice_id rockchip_gmac_ids[] = { > { .compatible = "rockchip,rk3288-gmac", > .data = (ulong)&rk3288_gmac_data }, > @@ -399,6 +460,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { > .data = (ulong)&rk3368_gmac_data }, > { .compatible = "rockchip,rk3399-gmac", > .data = (ulong)&rk3399_gmac_data }, > + { .compatible = "rockchip,rv1108-gmac", > + .data = (ulong)&rv1108_gmac_data }, > { } > }; > >
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 26f7a96..16b8c2b 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -37,6 +37,7 @@ struct gmac_rockchip_platdata { struct rk_gmac_ops { int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata, struct dw_eth_dev *priv); + void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); }; @@ -177,6 +178,40 @@ static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, return 0; } +static int rv1108_set_rmii_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) +{ + 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; + } + + rk_clrsetreg(pdata->grf, + 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_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; @@ -292,6 +327,18 @@ 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) +{ + enum { + RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), + RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4, + }; + + rk_clrsetreg(pdata->grf, + 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); @@ -325,8 +372,12 @@ static int gmac_rockchip_probe(struct udevice *dev) pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + data->grf_offset; - /* Set to RGMII mode */ - ops->set_to_rgmii(pdata); + if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RGMII) + ops->set_to_rgmii(pdata); + else if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RMII) + ops->set_to_rmii(pdata); + else + debug("NO interface defined!\n"); return designware_eth_probe(dev); } @@ -392,6 +443,16 @@ const struct gmac_rockchip_driver_data rk3399_gmac_data = { .grf_offset = 0xc214, }; +const struct rk_gmac_ops rv1108_gmac_ops = { + .fix_mac_speed = rv1108_set_rmii_speed, + .set_to_rmii = rv1108_gmac_set_to_rmii, +}; + +const struct gmac_rockchip_driver_data rv1108_gmac_data = { + .ops = &rv1108_gmac_ops, + .grf_offset = 0x900, +}; + static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,rk3288-gmac", .data = (ulong)&rk3288_gmac_data }, @@ -399,6 +460,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { .data = (ulong)&rk3368_gmac_data }, { .compatible = "rockchip,rk3399-gmac", .data = (ulong)&rk3399_gmac_data }, + { .compatible = "rockchip,rv1108-gmac", + .data = (ulong)&rv1108_gmac_data }, { } };
The rv1108 mac only support rmii interface, so need to add the set_rmii() ops. Use the phy current interface to set rmii or rgmii ops. Signed-off-by: David Wu <david.wu@rock-chips.com> --- drivers/net/gmac_rockchip.c | 67 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-)