[U-Boot] [U-Boot, 6/6] rockchip: gmac_rockchip: Add gmac support for rv1108

Philipp Tomsich philipp.tomsich at theobroma-systems.com
Fri Oct 6 10:09:50 UTC 2017



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 at rock-chips.com>
> Acked-by: Philipp Tomsich <philipp.tomsich at 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 },
> 	{ }
> };
>
>


More information about the U-Boot mailing list