[U-Boot] [PATCH 0/6] Add gmac support for rk3399-evb and rv1108-evb

This serie of patches integrates the setup mac clock is internal or external, as well as the way for setting rmii or rgmii interface.
David Wu (6): rockchip: clk: Add mac clock set for rk3399 rockchip: dts: rk3399-evb: Change the tx/rx delay value for transmission quality rockchip: configs: Enable CONFIG_NET_RANDOM_ETHADDR for rk3288-evb net: gmac_rockchip: Define the gmac grf register struct at gmac_rockchip.c net: gmac_rockchip: Use the proerty of "clock_in_out" to set mac clock rockchip: gmac_rockchip: Add gmac support for rv1108
arch/arm/dts/rk3399-evb.dts | 4 +- configs/evb-rk3288_defconfig | 1 + drivers/clk/rockchip/clk_rk3399.c | 21 +++- drivers/net/gmac_rockchip.c | 234 ++++++++++++++++++++++++++++++++------ 4 files changed, 222 insertions(+), 38 deletions(-)

Assuming mac_clk is fed by an external clock, set clk_rmii_src clock select control register from IO for rgmii interface.
Signed-off-by: David Wu david.wu@rock-chips.com ---
drivers/clk/rockchip/clk_rk3399.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 105c499..03d7518 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -143,6 +143,14 @@ enum { ACLK_PERIHP_DIV_CON_SHIFT = 0, ACLK_PERIHP_DIV_CON_MASK = 0x1f,
+ /* CLKSEL_CON19 */ + MAC_DIV_CON_SHIFT = 8, + MAC_DIV_CON_MASK = GENMASK(10, 8), + RMII_EXTCLK_SHIFT = 4, + RMII_EXTCLK_MASK = BIT(4), + RMII_EXTCLK_SELECT_INT_DIV_CLK = 0, + RMII_EXTCLK_SELECT_EXT_CLK = BIT(4), + /* CLKSEL_CON21 */ ACLK_EMMC_PLL_SEL_SHIFT = 7, ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT, @@ -863,6 +871,16 @@ static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru, return set_rate; }
+static int rockchip_mac_set_clk(struct rk3399_cru *cru, + int periph, uint freq) +{ + /* Assuming mac_clk is fed by an external clock */ + rk_clrsetreg(&cru->clksel_con[19], RMII_EXTCLK_MASK, + RMII_EXTCLK_SELECT_EXT_CLK); + + return 0; +} + static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru) { u32 div, val; @@ -947,8 +965,7 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); break; case SCLK_MAC: - /* nothing to do, as this is an external clock */ - ret = rate; + ret = rockchip_mac_set_clk(priv->cru, clk->id, rate); break; case SCLK_I2C1: case SCLK_I2C2:

Assuming mac_clk is fed by an external clock, set clk_rmii_src clock select control register from IO for rgmii interface.
Signed-off-by: David Wu david.wu@rock-chips.com
drivers/clk/rockchip/clk_rk3399.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

Assuming mac_clk is fed by an external clock, set clk_rmii_src clock select control register from IO for rgmii interface.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
drivers/clk/rockchip/clk_rk3399.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
Reviewed-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

Give the mac controller the correct tx-delay and rx-delay value for the rgmii mode transmission. If they are not matched, there would be Ethernet packets lost, the net feature may not work.
Signed-off-by: David Wu david.wu@rock-chips.com ---
arch/arm/dts/rk3399-evb.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts index be0c6d9..13958b8 100644 --- a/arch/arm/dts/rk3399-evb.dts +++ b/arch/arm/dts/rk3399-evb.dts @@ -272,7 +272,7 @@ assigned-clock-parents = <&clkin_gmac>; pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - tx_delay = <0x10>; - rx_delay = <0x10>; + tx_delay = <0x28>; + rx_delay = <0x11>; status = "okay"; };

Give the mac controller the correct tx-delay and rx-delay value for the rgmii mode transmission. If they are not matched, there would be Ethernet packets lost, the net feature may not work.
Signed-off-by: David Wu david.wu@rock-chips.com
arch/arm/dts/rk3399-evb.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

Give the mac controller the correct tx-delay and rx-delay value for the rgmii mode transmission. If they are not matched, there would be Ethernet packets lost, the net feature may not work.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
arch/arm/dts/rk3399-evb.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

If the Ethernet address is not set, the network can't work, enable the random address config for default use.
Signed-off-by: David Wu david.wu@rock-chips.com ---
configs/evb-rk3288_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig index f09b769..461bd3e 100644 --- a/configs/evb-rk3288_defconfig +++ b/configs/evb-rk3288_defconfig @@ -33,6 +33,7 @@ CONFIG_SPL_PARTITION_UUIDS=y CONFIG_SPL_OF_CONTROL=y CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" CONFIG_ENV_IS_IN_MMC=y +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y CONFIG_SYSCON=y

If the Ethernet address is not set, the network can't work, enable the random address config for default use.
Signed-off-by: David Wu david.wu@rock-chips.com
configs/evb-rk3288_defconfig | 1 + 1 file changed, 1 insertion(+)
Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

If the Ethernet address is not set, the network can't work, enable the random address config for default use.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
configs/evb-rk3288_defconfig | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

If we include both the rk3288_grf.h and rv1108_grf.h, there is a number of compiling error for redefinition. So we define the reg structs of mac_grf at gmac_rockchip.c. Remove the rk**_grf.h files, give them own grf offset for their use.
Signed-off-by: David Wu david.wu@rock-chips.com ---
drivers/net/gmac_rockchip.c | 144 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 28 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 586ccbf..5f8f0cd 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -15,9 +15,6 @@ #include <asm/arch/periph.h> #include <asm/arch/clock.h> #include <asm/arch/hardware.h> -#include <asm/arch/grf_rk3288.h> -#include <asm/arch/grf_rk3368.h> -#include <asm/arch/grf_rk3399.h> #include <dm/pinctrl.h> #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" @@ -31,15 +28,37 @@ DECLARE_GLOBAL_DATA_PTR; */ struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata; + void *grf; int tx_delay; int rx_delay; };
struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); };
+struct gmac_rockchip_driver_data { + const struct rk_gmac_ops *ops; + unsigned int grf_offset; +}; + +struct rk3288_mac_grf { + u32 soc_con1; + u32 reserved; + u32 soc_con3; +}; + +struct rk3368_mac_grf { + u32 soc_con15; + u32 soc_con16; +}; + +struct rk3399_mac_grf { + u32 soc_con5; + u32 soc_con6; +};
static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { @@ -58,10 +77,18 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) return designware_eth_ofdata_to_platdata(dev); }
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3288_grf *grf; + struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; int clk; + enum { + RK3288_GMAC_CLK_SEL_SHIFT = 12, + RK3288_GMAC_CLK_SEL_MASK = GENMASK(13, 12), + RK3288_GMAC_CLK_SEL_125M = 0 << 12, + RK3288_GMAC_CLK_SEL_25M = 3 << 12, + RK3288_GMAC_CLK_SEL_2_5M = 2 << 12, + };
switch (priv->phydev->speed) { case 10: @@ -78,15 +105,15 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
return 0; }
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3368_grf *grf; + struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; int clk; enum { RK3368_GMAC_CLK_SEL_2_5M = 2 << 4, @@ -110,16 +137,22 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
return 0; }
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3399_grf_regs *grf; + struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; int clk; + enum { + RK3399_GMAC_CLK_SEL_MASK = GENMASK(6, 4), + RK3399_GMAC_CLK_SEL_125M = 0 << 4, + RK3399_GMAC_CLK_SEL_25M = 3 << 4, + RK3399_GMAC_CLK_SEL_2_5M = 2 << 4, + };
switch (priv->phydev->speed) { case 10: @@ -136,7 +169,6 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
return 0; @@ -144,9 +176,31 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3288_grf *grf; + struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; + enum { + RK3288_RMII_MODE_SHIFT = 14, + RK3288_RMII_MODE_MASK = BIT(14), + + RK3288_GMAC_PHY_INTF_SEL_SHIFT = 6, + RK3288_GMAC_PHY_INTF_SEL_MASK = GENMASK(8, 6), + RK3288_GMAC_PHY_INTF_SEL_RGMII = BIT(6), + }; + enum { + RK3288_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), + RK3288_RXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3288_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15), + + RK3288_TXCLK_DLY_ENA_GMAC_MASK = BIT(14), + RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3288_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(14), + + RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7, + RK3288_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7), + + RK3288_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, + RK3288_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), + };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, RK3288_GMAC_PHY_INTF_SEL_RGMII); @@ -164,7 +218,7 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3368_grf *grf; + struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; enum { RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), @@ -184,7 +238,6 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, RK3368_GMAC_PHY_INTF_SEL_RGMII); @@ -202,9 +255,24 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3399_grf_regs *grf; - - grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; + enum { + RK3399_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), + RK3399_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, + RK3399_GMAC_PHY_INTF_SEL_RMII = 4 << 9, + }; + enum { + RK3399_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), + RK3399_RXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3399_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15), + RK3399_TXCLK_DLY_ENA_GMAC_MASK = BIT(7), + RK3399_TXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3399_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7), + RK3399_CLK_RX_DL_CFG_GMAC_SHIFT = 8, + RK3399_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), + RK3399_CLK_TX_DL_CFG_GMAC_SHIFT = 0, + RK3399_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), + };
rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_PHY_INTF_SEL_MASK, @@ -224,8 +292,9 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 gmac_rockchip_driver_data *data = + (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev); + const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret;
@@ -238,6 +307,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret;
+ pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + + data->grf_offset; + /* Set to RGMII mode */ ops->set_to_rgmii(pdata);
@@ -248,14 +320,15 @@ static int gmac_rockchip_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev); - struct rk_gmac_ops *ops = - (struct rk_gmac_ops *)dev_get_driver_data(dev); + struct gmac_rockchip_driver_data *data = + (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev); + const struct rk_gmac_ops *ops = data->ops; int ret;
ret = designware_eth_init(priv, pdata->enetaddr); if (ret) return ret; - ret = ops->fix_mac_speed(priv); + ret = ops->fix_mac_speed((struct gmac_rockchip_platdata *)pdata, priv); if (ret) return ret; ret = designware_eth_enable(priv); @@ -279,23 +352,38 @@ const struct rk_gmac_ops rk3288_gmac_ops = { .set_to_rgmii = rk3288_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3288_gmac_data = { + .ops = &rk3288_gmac_ops, + .grf_offset = 0x248, +}; + const struct rk_gmac_ops rk3368_gmac_ops = { .fix_mac_speed = rk3368_gmac_fix_mac_speed, .set_to_rgmii = rk3368_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3368_gmac_data = { + .ops = &rk3368_gmac_ops, + .grf_offset = 0x43c, +}; + const struct rk_gmac_ops rk3399_gmac_ops = { .fix_mac_speed = rk3399_gmac_fix_mac_speed, .set_to_rgmii = rk3399_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3399_gmac_data = { + .ops = &rk3399_gmac_ops, + .grf_offset = 0xc214, +}; + static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,rk3288-gmac", - .data = (ulong)&rk3288_gmac_ops }, + .data = (ulong)&rk3288_gmac_data }, { .compatible = "rockchip,rk3368-gmac", - .data = (ulong)&rk3368_gmac_ops }, + .data = (ulong)&rk3368_gmac_data }, { .compatible = "rockchip,rk3399-gmac", - .data = (ulong)&rk3399_gmac_ops }, + .data = (ulong)&rk3399_gmac_data }, { } };

If we include both the rk3288_grf.h and rv1108_grf.h, there is a number of compiling error for redefinition. So we define the reg structs of mac_grf at gmac_rockchip.c. Remove the rk**_grf.h files, give them own grf offset for their use.
Signed-off-by: David Wu david.wu@rock-chips.com
drivers/net/gmac_rockchip.c | 144 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 28 deletions(-)
Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

On Thu, Sep 21, 2017 at 9:17 AM, David Wu david.wu@rock-chips.com wrote:
If we include both the rk3288_grf.h and rv1108_grf.h, there is a number of compiling error for redefinition. So we define the reg structs of mac_grf at gmac_rockchip.c. Remove the rk**_grf.h files, give them own grf offset for their use.
Signed-off-by: David Wu david.wu@rock-chips.com
drivers/net/gmac_rockchip.c | 144 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 28 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 586ccbf..5f8f0cd 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -15,9 +15,6 @@ #include <asm/arch/periph.h> #include <asm/arch/clock.h> #include <asm/arch/hardware.h> -#include <asm/arch/grf_rk3288.h> -#include <asm/arch/grf_rk3368.h> -#include <asm/arch/grf_rk3399.h>
You should also delete these header files as part of the patch.
#include <dm/pinctrl.h> #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" @@ -31,15 +28,37 @@ DECLARE_GLOBAL_DATA_PTR; */ struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata;
void *grf; int tx_delay; int rx_delay;
};
struct rk_gmac_ops {
int (*fix_mac_speed)(struct dw_eth_dev *priv);
int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
};
+struct gmac_rockchip_driver_data {
const struct rk_gmac_ops *ops;
unsigned int grf_offset;
+};
+struct rk3288_mac_grf {
u32 soc_con1;
u32 reserved;
u32 soc_con3;
+};
+struct rk3368_mac_grf {
u32 soc_con15;
u32 soc_con16;
+};
+struct rk3399_mac_grf {
u32 soc_con5;
u32 soc_con6;
+};
static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { @@ -58,10 +77,18 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) return designware_eth_ofdata_to_platdata(dev); }
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
struct rk3288_grf *grf;
struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; int clk;
enum {
RK3288_GMAC_CLK_SEL_SHIFT = 12,
RK3288_GMAC_CLK_SEL_MASK = GENMASK(13, 12),
RK3288_GMAC_CLK_SEL_125M = 0 << 12,
RK3288_GMAC_CLK_SEL_25M = 3 << 12,
RK3288_GMAC_CLK_SEL_2_5M = 2 << 12,
}; switch (priv->phydev->speed) { case 10:
@@ -78,15 +105,15 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk); return 0;
}
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
struct rk3368_grf *grf;
struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; int clk; enum { RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
@@ -110,16 +137,22 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk); return 0;
}
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
struct rk3399_grf_regs *grf;
struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; int clk;
enum {
RK3399_GMAC_CLK_SEL_MASK = GENMASK(6, 4),
RK3399_GMAC_CLK_SEL_125M = 0 << 4,
RK3399_GMAC_CLK_SEL_25M = 3 << 4,
RK3399_GMAC_CLK_SEL_2_5M = 2 << 4,
}; switch (priv->phydev->speed) { case 10:
@@ -136,7 +169,6 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk); return 0;
@@ -144,9 +176,31 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
struct rk3288_grf *grf;
struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf;
enum {
RK3288_RMII_MODE_SHIFT = 14,
RK3288_RMII_MODE_MASK = BIT(14),
RK3288_GMAC_PHY_INTF_SEL_SHIFT = 6,
RK3288_GMAC_PHY_INTF_SEL_MASK = GENMASK(8, 6),
RK3288_GMAC_PHY_INTF_SEL_RGMII = BIT(6),
};
enum {
RK3288_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
RK3288_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3288_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
RK3288_TXCLK_DLY_ENA_GMAC_MASK = BIT(14),
RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3288_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(14),
RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
RK3288_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
RK3288_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
RK3288_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
};
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, RK3288_GMAC_PHY_INTF_SEL_RGMII);
@@ -164,7 +218,7 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
struct rk3368_grf *grf;
struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; enum { RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
@@ -184,7 +238,6 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), };
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, RK3368_GMAC_PHY_INTF_SEL_RGMII);
@@ -202,9 +255,24 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
struct rk3399_grf_regs *grf;
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf;
enum {
RK3399_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
RK3399_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
RK3399_GMAC_PHY_INTF_SEL_RMII = 4 << 9,
};
enum {
RK3399_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
RK3399_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3399_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
RK3399_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
RK3399_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3399_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
RK3399_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
RK3399_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
RK3399_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
RK3399_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
}; rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_PHY_INTF_SEL_MASK,
@@ -224,8 +292,9 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 gmac_rockchip_driver_data *data =
(struct gmac_rockchip_driver_data *)dev_get_driver_data(dev);
const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret;
@@ -238,6 +307,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret;
pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) +
data->grf_offset;
/* Set to RGMII mode */ ops->set_to_rgmii(pdata);
@@ -248,14 +320,15 @@ static int gmac_rockchip_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev);
struct rk_gmac_ops *ops =
(struct rk_gmac_ops *)dev_get_driver_data(dev);
struct gmac_rockchip_driver_data *data =
(struct gmac_rockchip_driver_data *)dev_get_driver_data(dev);
const struct rk_gmac_ops *ops = data->ops; int ret; ret = designware_eth_init(priv, pdata->enetaddr); if (ret) return ret;
ret = ops->fix_mac_speed(priv);
ret = ops->fix_mac_speed((struct gmac_rockchip_platdata *)pdata, priv); if (ret) return ret; ret = designware_eth_enable(priv);
@@ -279,23 +352,38 @@ const struct rk_gmac_ops rk3288_gmac_ops = { .set_to_rgmii = rk3288_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3288_gmac_data = {
.ops = &rk3288_gmac_ops,
.grf_offset = 0x248,
+};
const struct rk_gmac_ops rk3368_gmac_ops = { .fix_mac_speed = rk3368_gmac_fix_mac_speed, .set_to_rgmii = rk3368_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3368_gmac_data = {
.ops = &rk3368_gmac_ops,
.grf_offset = 0x43c,
+};
const struct rk_gmac_ops rk3399_gmac_ops = { .fix_mac_speed = rk3399_gmac_fix_mac_speed, .set_to_rgmii = rk3399_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3399_gmac_data = {
.ops = &rk3399_gmac_ops,
.grf_offset = 0xc214,
+};
static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,rk3288-gmac",
.data = (ulong)&rk3288_gmac_ops },
.data = (ulong)&rk3288_gmac_data }, { .compatible = "rockchip,rk3368-gmac",
.data = (ulong)&rk3368_gmac_ops },
.data = (ulong)&rk3368_gmac_data }, { .compatible = "rockchip,rk3399-gmac",
.data = (ulong)&rk3399_gmac_ops },
.data = (ulong)&rk3399_gmac_data }, { }
};
-- 2.7.4
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On Thu, 21 Sep 2017, David Wu wrote:
If we include both the rk3288_grf.h and rv1108_grf.h, there is a number of compiling error for redefinition. So we define the reg structs of mac_grf at gmac_rockchip.c. Remove the rk**_grf.h files, give them own grf offset for their use.
The reg offset should not be open-coded in gmac_rockchip.c.
The issue of GRF-header having conflicting definitions was already discussed on the list, when I initially submitted the RK3368 support. The decision back then was as follows: 1/ The GRF files should not contain definitions that are private to the IOMUX (e.g. these should go into the pinctrl-driver), etc. 2/ As an intermediate step, we move some of this (i.e. the GMAC_CLK_SEL definitions into gmac_rockchip.c. 3/ The long-term solution will be to either create misc-devices that handle the 'set-to-rgmii' functionality and the 'GMAC_CLK_SEL' bits (although on those, modelling it via the clk-framework might be more appropriate).
Please clean up the affected GRF files that cause the conflicts (e.g. the RV1108) and extend the current implementation w/o open-coding a grf-offet.
Additional requested changes below.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
drivers/net/gmac_rockchip.c | 144 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 28 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 586ccbf..5f8f0cd 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -15,9 +15,6 @@ #include <asm/arch/periph.h> #include <asm/arch/clock.h> #include <asm/arch/hardware.h> -#include <asm/arch/grf_rk3288.h> -#include <asm/arch/grf_rk3368.h> -#include <asm/arch/grf_rk3399.h> #include <dm/pinctrl.h> #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" @@ -31,15 +28,37 @@ DECLARE_GLOBAL_DATA_PTR; */ struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata;
- void *grf; int tx_delay; int rx_delay;
};
struct rk_gmac_ops {
- int (*fix_mac_speed)(struct dw_eth_dev *priv);
- int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata,
void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);struct dw_eth_dev *priv);
};
+struct gmac_rockchip_driver_data {
- const struct rk_gmac_ops *ops;
- unsigned int grf_offset;
+};
+struct rk3288_mac_grf {
- u32 soc_con1;
- u32 reserved;
- u32 soc_con3;
+};
+struct rk3368_mac_grf {
- u32 soc_con15;
- u32 soc_con16;
+};
+struct rk3399_mac_grf {
- u32 soc_con5;
- u32 soc_con6;
+};
We really can't pollute the GMAC driver with these definitions. The actual values need to come out of the central GRF structure definition.
static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { @@ -58,10 +77,18 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) return designware_eth_ofdata_to_platdata(dev); }
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
- struct rk3288_grf *grf;
struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; int clk;
enum {
RK3288_GMAC_CLK_SEL_SHIFT = 12,
RK3288_GMAC_CLK_SEL_MASK = GENMASK(13, 12),
RK3288_GMAC_CLK_SEL_125M = 0 << 12,
RK3288_GMAC_CLK_SEL_25M = 3 << 12,
RK3288_GMAC_CLK_SEL_2_5M = 2 << 12,
};
switch (priv->phydev->speed) { case 10:
@@ -78,15 +105,15 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
return 0;
}
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
- struct rk3368_grf *grf;
- struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; int clk; enum { RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
@@ -110,16 +137,22 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
return 0;
}
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata,
struct dw_eth_dev *priv)
{
- struct rk3399_grf_regs *grf;
struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; int clk;
enum {
RK3399_GMAC_CLK_SEL_MASK = GENMASK(6, 4),
RK3399_GMAC_CLK_SEL_125M = 0 << 4,
RK3399_GMAC_CLK_SEL_25M = 3 << 4,
RK3399_GMAC_CLK_SEL_2_5M = 2 << 4,
};
switch (priv->phydev->speed) { case 10:
@@ -136,7 +169,6 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
return 0;
@@ -144,9 +176,31 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
- struct rk3288_grf *grf;
- struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf;
- enum {
RK3288_RMII_MODE_SHIFT = 14,
RK3288_RMII_MODE_MASK = BIT(14),
RK3288_GMAC_PHY_INTF_SEL_SHIFT = 6,
RK3288_GMAC_PHY_INTF_SEL_MASK = GENMASK(8, 6),
RK3288_GMAC_PHY_INTF_SEL_RGMII = BIT(6),
- };
- enum {
RK3288_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
RK3288_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3288_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
RK3288_TXCLK_DLY_ENA_GMAC_MASK = BIT(14),
RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3288_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(14),
RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
RK3288_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
RK3288_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
RK3288_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
- };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, RK3288_GMAC_PHY_INTF_SEL_RGMII);
@@ -164,7 +218,7 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
- struct rk3368_grf *grf;
- struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; enum { RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
@@ -184,7 +238,6 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, RK3368_GMAC_PHY_INTF_SEL_RGMII);
@@ -202,9 +255,24 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) {
- struct rk3399_grf_regs *grf;
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf;
enum {
RK3399_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
RK3399_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
RK3399_GMAC_PHY_INTF_SEL_RMII = 4 << 9,
};
enum {
RK3399_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
RK3399_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3399_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
RK3399_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
RK3399_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
RK3399_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
RK3399_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
RK3399_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
RK3399_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
RK3399_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
};
rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_PHY_INTF_SEL_MASK,
@@ -224,8 +292,9 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 gmac_rockchip_driver_data *data =
(struct gmac_rockchip_driver_data *)dev_get_driver_data(dev);
- const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret;
@@ -238,6 +307,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret;
- pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) +
data->grf_offset;
- /* Set to RGMII mode */ ops->set_to_rgmii(pdata);
@@ -248,14 +320,15 @@ static int gmac_rockchip_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev);
- struct rk_gmac_ops *ops =
(struct rk_gmac_ops *)dev_get_driver_data(dev);
struct gmac_rockchip_driver_data *data =
(struct gmac_rockchip_driver_data *)dev_get_driver_data(dev);
const struct rk_gmac_ops *ops = data->ops; int ret;
ret = designware_eth_init(priv, pdata->enetaddr); if (ret) return ret;
- ret = ops->fix_mac_speed(priv);
- ret = ops->fix_mac_speed((struct gmac_rockchip_platdata *)pdata, priv); if (ret) return ret; ret = designware_eth_enable(priv);
@@ -279,23 +352,38 @@ const struct rk_gmac_ops rk3288_gmac_ops = { .set_to_rgmii = rk3288_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3288_gmac_data = {
- .ops = &rk3288_gmac_ops,
- .grf_offset = 0x248,
+};
const struct rk_gmac_ops rk3368_gmac_ops = { .fix_mac_speed = rk3368_gmac_fix_mac_speed, .set_to_rgmii = rk3368_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3368_gmac_data = {
- .ops = &rk3368_gmac_ops,
- .grf_offset = 0x43c,
+};
const struct rk_gmac_ops rk3399_gmac_ops = { .fix_mac_speed = rk3399_gmac_fix_mac_speed, .set_to_rgmii = rk3399_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3399_gmac_data = {
- .ops = &rk3399_gmac_ops,
- .grf_offset = 0xc214,
The grf_offset really can not be hardcoded here.
+};
static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,rk3288-gmac",
.data = (ulong)&rk3288_gmac_ops },
{ .compatible = "rockchip,rk3368-gmac",.data = (ulong)&rk3288_gmac_data },
.data = (ulong)&rk3368_gmac_ops },
{ .compatible = "rockchip,rk3399-gmac",.data = (ulong)&rk3368_gmac_data },
.data = (ulong)&rk3399_gmac_ops },
{ }.data = (ulong)&rk3399_gmac_data },
};

Hi Philipp,
在 2017/10/6 18:06, Philipp Tomsich 写道:
On Thu, 21 Sep 2017, David Wu wrote:
If we include both the rk3288_grf.h and rv1108_grf.h, there is a number of compiling error for redefinition. So we define the reg structs of mac_grf at gmac_rockchip.c. Remove the rk**_grf.h files, give them own grf offset for their use.
The reg offset should not be open-coded in gmac_rockchip.c.
The issue of GRF-header having conflicting definitions was already discussed on the list, when I initially submitted the RK3368 support. The decision back then was as follows: 1/ The GRF files should not contain definitions that are private to the IOMUX (e.g. these should go into the pinctrl-driver), etc.
I'll try to move all the iomux definitions at GRF-header into pinctrl-driver, use pinctrl_request* interface to set iomux in some board.c file.
2/ As an intermediate step, we move some of this (i.e. the GMAC_CLK_SEL definitions into gmac_rockchip.c.
I still think the 'GMAC_CLK_SEL' bit set should be implemented at clk driver.
3/ The long-term solution will be to either create misc-devices that handle the 'set-to-rgmii' functionality and the 'GMAC_CLK_SEL' bits (although on those, modelling it via the clk-framework might be more appropriate).
Could you give me a example code for misc-devices?
Please clean up the affected GRF files that cause the conflicts (e.g. the RV1108) and extend the current implementation w/o open-coding a grf-offet.
Additional requested changes below.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
drivers/net/gmac_rockchip.c | 144 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 28 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 586ccbf..5f8f0cd 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -15,9 +15,6 @@ #include <asm/arch/periph.h> #include <asm/arch/clock.h> #include <asm/arch/hardware.h> -#include <asm/arch/grf_rk3288.h> -#include <asm/arch/grf_rk3368.h> -#include <asm/arch/grf_rk3399.h> #include <dm/pinctrl.h> #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" @@ -31,15 +28,37 @@ DECLARE_GLOBAL_DATA_PTR; */ struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata; + void *grf; int tx_delay; int rx_delay; };
struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + int (*fix_mac_speed)(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); };
+struct gmac_rockchip_driver_data { + const struct rk_gmac_ops *ops; + unsigned int grf_offset; +};
+struct rk3288_mac_grf { + u32 soc_con1; + u32 reserved; + u32 soc_con3; +};
+struct rk3368_mac_grf { + u32 soc_con15; + u32 soc_con16; +};
+struct rk3399_mac_grf { + u32 soc_con5; + u32 soc_con6; +};
We really can't pollute the GMAC driver with these definitions. The actual values need to come out of the central GRF structure definition.
static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { @@ -58,10 +77,18 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) return designware_eth_ofdata_to_platdata(dev); }
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3288_grf *grf; + struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; int clk; + enum { + RK3288_GMAC_CLK_SEL_SHIFT = 12, + RK3288_GMAC_CLK_SEL_MASK = GENMASK(13, 12), + RK3288_GMAC_CLK_SEL_125M = 0 << 12, + RK3288_GMAC_CLK_SEL_25M = 3 << 12, + RK3288_GMAC_CLK_SEL_2_5M = 2 << 12, + };
switch (priv->phydev->speed) { case 10: @@ -78,15 +105,15 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
return 0; }
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3368_grf *grf; + struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; int clk; enum { RK3368_GMAC_CLK_SEL_2_5M = 2 << 4, @@ -110,16 +137,22 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
return 0; }
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3399_gmac_fix_mac_speed(struct gmac_rockchip_platdata *pdata, + struct dw_eth_dev *priv) { - struct rk3399_grf_regs *grf; + struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; int clk; + enum { + RK3399_GMAC_CLK_SEL_MASK = GENMASK(6, 4), + RK3399_GMAC_CLK_SEL_125M = 0 << 4, + RK3399_GMAC_CLK_SEL_25M = 3 << 4, + RK3399_GMAC_CLK_SEL_2_5M = 2 << 4, + };
switch (priv->phydev->speed) { case 10: @@ -136,7 +169,6 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) return -EINVAL; }
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
return 0; @@ -144,9 +176,31 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3288_grf *grf; + struct rk3288_mac_grf *grf = (struct rk3288_mac_grf *)pdata->grf; + enum { + RK3288_RMII_MODE_SHIFT = 14, + RK3288_RMII_MODE_MASK = BIT(14),
+ RK3288_GMAC_PHY_INTF_SEL_SHIFT = 6, + RK3288_GMAC_PHY_INTF_SEL_MASK = GENMASK(8, 6), + RK3288_GMAC_PHY_INTF_SEL_RGMII = BIT(6), + }; + enum { + RK3288_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), + RK3288_RXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3288_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
+ RK3288_TXCLK_DLY_ENA_GMAC_MASK = BIT(14), + RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3288_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(14),
+ RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7, + RK3288_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
+ RK3288_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, + RK3288_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), + };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con1, RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, RK3288_GMAC_PHY_INTF_SEL_RGMII); @@ -164,7 +218,7 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3368_grf *grf; + struct rk3368_mac_grf *grf = (struct rk3368_mac_grf *)pdata->grf; enum { RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), @@ -184,7 +238,6 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), };
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); rk_clrsetreg(&grf->soc_con15, RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, RK3368_GMAC_PHY_INTF_SEL_RGMII); @@ -202,9 +255,24 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { - struct rk3399_grf_regs *grf;
- grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + struct rk3399_mac_grf *grf = (struct rk3399_mac_grf *)pdata->grf; + enum { + RK3399_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), + RK3399_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, + RK3399_GMAC_PHY_INTF_SEL_RMII = 4 << 9, + }; + enum { + RK3399_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), + RK3399_RXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3399_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15), + RK3399_TXCLK_DLY_ENA_GMAC_MASK = BIT(7), + RK3399_TXCLK_DLY_ENA_GMAC_DISABLE = 0, + RK3399_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7), + RK3399_CLK_RX_DL_CFG_GMAC_SHIFT = 8, + RK3399_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), + RK3399_CLK_TX_DL_CFG_GMAC_SHIFT = 0, + RK3399_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), + };
rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_PHY_INTF_SEL_MASK, @@ -224,8 +292,9 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 gmac_rockchip_driver_data *data = + (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev); + const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret;
@@ -238,6 +307,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret;
+ pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + + data->grf_offset;
/* Set to RGMII mode */ ops->set_to_rgmii(pdata);
@@ -248,14 +320,15 @@ static int gmac_rockchip_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev); - struct rk_gmac_ops *ops = - (struct rk_gmac_ops *)dev_get_driver_data(dev); + struct gmac_rockchip_driver_data *data = + (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev); + const struct rk_gmac_ops *ops = data->ops; int ret;
ret = designware_eth_init(priv, pdata->enetaddr); if (ret) return ret; - ret = ops->fix_mac_speed(priv); + ret = ops->fix_mac_speed((struct gmac_rockchip_platdata *)pdata, priv); if (ret) return ret; ret = designware_eth_enable(priv); @@ -279,23 +352,38 @@ const struct rk_gmac_ops rk3288_gmac_ops = { .set_to_rgmii = rk3288_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3288_gmac_data = { + .ops = &rk3288_gmac_ops, + .grf_offset = 0x248, +};
const struct rk_gmac_ops rk3368_gmac_ops = { .fix_mac_speed = rk3368_gmac_fix_mac_speed, .set_to_rgmii = rk3368_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3368_gmac_data = { + .ops = &rk3368_gmac_ops, + .grf_offset = 0x43c, +};
const struct rk_gmac_ops rk3399_gmac_ops = { .fix_mac_speed = rk3399_gmac_fix_mac_speed, .set_to_rgmii = rk3399_gmac_set_to_rgmii, };
+const struct gmac_rockchip_driver_data rk3399_gmac_data = { + .ops = &rk3399_gmac_ops, + .grf_offset = 0xc214,
The grf_offset really can not be hardcoded here.
+};
static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,rk3288-gmac", - .data = (ulong)&rk3288_gmac_ops }, + .data = (ulong)&rk3288_gmac_data }, { .compatible = "rockchip,rk3368-gmac", - .data = (ulong)&rk3368_gmac_ops }, + .data = (ulong)&rk3368_gmac_data }, { .compatible = "rockchip,rk3399-gmac", - .data = (ulong)&rk3399_gmac_ops }, + .data = (ulong)&rk3399_gmac_data }, { } };

If the mac clock if from the external IO, set clock rate with 0; If the mac clock if from the internal divider pll, set 50M for rmii mode and set 125M for rgmii.
Signed-off-by: David Wu david.wu@rock-chips.com ---
drivers/net/gmac_rockchip.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 5f8f0cd..26f7a96 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR; struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata; void *grf; + int clk_in; int tx_delay; int rx_delay; }; @@ -64,6 +65,8 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+ pdata->clk_in = dev_read_u32_default(dev, "clock_in_out", 1); + /* Check the new naming-style first... */ pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); @@ -294,6 +297,8 @@ static int gmac_rockchip_probe(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); struct gmac_rockchip_driver_data *data = (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev); + struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); + struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata; const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret; @@ -302,10 +307,20 @@ 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; + if (pdata->clk_in) { + /* + * Since mac_clk is fed by an external clock + * we can use 0 here. + */ + ret = clk_set_rate(&clk, 0); + if (ret) + return ret; + } else { + if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RGMII) + clk_set_rate(&clk, 125000000); + else + clk_set_rate(&clk, 50000000); + }
pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + data->grf_offset;

If the mac clock if from the external IO, set clock rate with 0; If the mac clock if from the internal divider pll, set 50M for rmii mode and set 125M for rgmii.
Signed-off-by: David Wu david.wu@rock-chips.com
drivers/net/gmac_rockchip.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

If the mac clock if from the external IO, set clock rate with 0; If the mac clock if from the internal divider pll, set 50M for rmii mode and set 125M for rgmii.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
drivers/net/gmac_rockchip.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
Reviewed-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com

On Thu, 21 Sep 2017, David Wu wrote:
If the mac clock if from the external IO, set clock rate with 0; If the mac clock if from the internal divider pll, set 50M for rmii mode and set 125M for rgmii.
If we do this, we really shouldn't treat the external clock any different. So we should request the speed we expect from the external clk and not just pass 0...
More below.
Signed-off-by: David Wu david.wu@rock-chips.com Acked-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
drivers/net/gmac_rockchip.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 5f8f0cd..26f7a96 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR; struct gmac_rockchip_platdata { struct dw_eth_pdata dw_eth_pdata; void *grf;
- int clk_in;
Please use an enum here to make it clear which value in INPUT and which one is OUTPUT.
int tx_delay; int rx_delay; }; @@ -64,6 +65,8 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) { struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
- pdata->clk_in = dev_read_u32_default(dev, "clock_in_out", 1);
The 'u32' seems to be wrong, relative to common usage: arch/arm/dts/rk3229-evb.dts: clock_in_out = "input"; arch/arm/dts/rk3288-evb.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-fennec.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-firefly.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-miqi.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-phycore-som.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-popmetal.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-rock2-som.dtsi: clock_in_out = "input"; arch/arm/dts/rk3288-tinker.dtsi: clock_in_out = "input"; arch/arm/dts/rk3368-geekbox.dts: clock_in_out = "input"; arch/arm/dts/rk3368-lion.dts: clock_in_out = "input"; arch/arm/dts/rk3368-px5-evb.dts: clock_in_out = "input"; arch/arm/dts/rk3368-sheep.dts: clock_in_out = "input"; arch/arm/dts/rk3399-evb.dts: clock_in_out = "input"; arch/arm/dts/rk3399-firefly.dts: clock_in_out = "input"; arch/arm/dts/rk3399-puma.dtsi: clock_in_out = "input";
Please remain consistent and test for a string here and for the string value. Also, we are missing documentation on the DTS binding in /doc: please add documentation there.
/* Check the new naming-style first... */ pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); @@ -294,6 +297,8 @@ static int gmac_rockchip_probe(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); struct gmac_rockchip_driver_data *data = (struct gmac_rockchip_driver_data *)dev_get_driver_data(dev);
- struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
- struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata; const struct rk_gmac_ops *ops = data->ops; struct clk clk; int ret;
@@ -302,10 +307,20 @@ 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;
- if (pdata->clk_in) {
/*
* Since mac_clk is fed by an external clock
* we can use 0 here.
*/
ret = clk_set_rate(&clk, 0);
In hindsight using '0' was a bad decision. We should always request the expected external clock rate here (so the clock driver could do some sanity checking).
if (ret)
return ret;
} else {
if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RGMII)
clk_set_rate(&clk, 125000000);
else
clk_set_rate(&clk, 50000000);
}
pdata->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF) + data->grf_offset;

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(-)
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(-)
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 },
};
participants (4)
-
David Wu
-
David.Wu
-
Joe Hershberger
-
Philipp Tomsich