[U-Boot] [U-Boot, v2, 06/18] net: gmac_rockchip: Add support for the RV1108 GMAC
Philipp Tomsich
philipp.tomsich at theobroma-systems.com
Sun Nov 26 14:36:26 UTC 2017
On Thu, 9 Nov 2017, David Wu wrote:
> 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>
> Acked-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com>
See below for requested changes.
> ---
>
> 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);
This avoids a crash, but shouldn't it handle the error (of no set_to_rgmii
being present? As of now, it will chain through into designware_eth_probe
and eventually return successful completion.
> + 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);
Same.
> + 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 },
> { }
> };
>
>
More information about the U-Boot
mailing list