[PATCH v2] net: stmmac: dwmac-rk: add rk3228-specific data
Add constants and callback functions for the dwmac on rk3228/rk3229 socs. As can be seen, the base structure is the same, only registers and the bits in them moved slightly. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- Changes in v2: - the "rk322x" is not clear to SoC decription, rename it to "rk3228" .../devicetree/bindings/net/rockchip-dwmac.txt |3 +- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 117 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 93eac7c..cccd945 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -3,7 +3,8 @@ Rockchip SoC RK3288 10/100/1000 Ethernet driver(GMAC) The device node has following properties. Required properties: - - compatible: Can be one of "rockchip,rk3288-gmac", "rockchip,rk3368-gmac" + - compatible: Can be one of "rockchip,rk3228-gmac", "rockchip,rk3288-gmac", + "rockchip,rk3368-gmac" - reg: addresses and length of the register sets for the device. - interrupts: Should contain the GMAC interrupts. - interrupt-names: Should contain the interrupt names "macirq". diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 0cd3ecf..25eb797 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -72,6 +72,122 @@ struct rk_priv_data { #define GRF_BIT(nr)(BIT(nr) | BIT(nr+16)) #define GRF_CLR_BIT(nr)(BIT(nr+16)) +#define RK3228_GRF_MAC_CON00x0900 +#define RK3228_GRF_MAC_CON10x0904 + +/* RK3228_GRF_MAC_CON0 */ +#define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) +#define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + +/* RK3228_GRF_MAC_CON1 */ +#define RK3228_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) +#define RK3228_GMAC_PHY_INTF_SEL_RMII \ + (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) +#define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) +#define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) +#define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) +#define RK3228_GMAC_SPEED_100M GRF_BIT(2) +#define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) +#define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) +#define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) +#define RK3228_GMAC_CLK_25M(GRF_BIT(8) | GRF_BIT(9)) +#define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) +#define RK3228_GMAC_RMII_MODE GRF_BIT(10) +#define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) +#define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) +#define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) +#define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) +#define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) + +static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, +RK3228_GMAC_PHY_INTF_SEL_RGMII | +RK3228_GMAC_RMII_MODE_CLR | +RK3228_GMAC_RXCLK_DLY_ENABLE | +RK3228_GMAC_TXCLK_DLY_ENABLE); + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, +RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | +RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); +} + +static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, +RK3228_GMAC_PHY_INTF_SEL_RMII | +RK3228_GMAC_RMII_MODE); + + /* set MAC to RMII mode */ + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); +} + +static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, +RK3228_GMAC_CLK_2_5M); + else if (speed == 100) + regmap_write(bsp_priv->grf, RK3228
Re: [PATCH] net: stmmac: dwmac-rk: add rk322x-specific data
Hi Heiko, On 2016年06月21日 17:43, Heiko Stübner wrote: devicetree names are normally expected to be real, aka no "x" as catchall. So I guess either just add compatibles for both the rk3228 and rk3229 which point to the same structure in the driver. (So driver-side can stay as it is below, just add a second compatible). OK, I try to just use "rockchip,rk3228-gmac" to point to "rk322x_ops" which is the same structure in MAC driver, and both rk3228 and rk3229 use it. Thanks -- - Xing Zheng
[PATCH] net: stmmac: dwmac-rk: add rk322x-specific data
Add constants and callback functions for the dwmac on rk322x socs. As can be seen, the base structure is the same, only registers and the bits in them moved slightly. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- .../devicetree/bindings/net/rockchip-dwmac.txt |3 +- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 117 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 93eac7c..5040ed4 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -3,7 +3,8 @@ Rockchip SoC RK3288 10/100/1000 Ethernet driver(GMAC) The device node has following properties. Required properties: - - compatible: Can be one of "rockchip,rk3288-gmac", "rockchip,rk3368-gmac" + - compatible: Can be one of "rockchip,rk322x-gmac", "rockchip,rk3288-gmac", + "rockchip,rk3368-gmac" - reg: addresses and length of the register sets for the device. - interrupts: Should contain the GMAC interrupts. - interrupt-names: Should contain the interrupt names "macirq". diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 0cd3ecf..7f045db 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -72,6 +72,122 @@ struct rk_priv_data { #define GRF_BIT(nr)(BIT(nr) | BIT(nr+16)) #define GRF_CLR_BIT(nr)(BIT(nr+16)) +#define RK322X_GRF_MAC_CON00x0900 +#define RK322X_GRF_MAC_CON10x0904 + +/* RK322X_GRF_MAC_CON0 */ +#define RK322X_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) +#define RK322X_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + +/* RK322X_GRF_MAC_CON1 */ +#define RK322X_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) +#define RK322X_GMAC_PHY_INTF_SEL_RMII \ + (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) +#define RK322X_GMAC_FLOW_CTRL GRF_BIT(3) +#define RK322X_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) +#define RK322X_GMAC_SPEED_10M GRF_CLR_BIT(2) +#define RK322X_GMAC_SPEED_100M GRF_BIT(2) +#define RK322X_GMAC_RMII_CLK_25M GRF_BIT(7) +#define RK322X_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) +#define RK322X_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) +#define RK322X_GMAC_CLK_25M(GRF_BIT(8) | GRF_BIT(9)) +#define RK322X_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) +#define RK322X_GMAC_RMII_MODE GRF_BIT(10) +#define RK322X_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) +#define RK322X_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) +#define RK322X_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) +#define RK322X_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) +#define RK322X_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) + +static void rk322x_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON1, +RK322X_GMAC_PHY_INTF_SEL_RGMII | +RK322X_GMAC_RMII_MODE_CLR | +RK322X_GMAC_RXCLK_DLY_ENABLE | +RK322X_GMAC_TXCLK_DLY_ENABLE); + + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON0, +RK322X_GMAC_CLK_RX_DL_CFG(rx_delay) | +RK322X_GMAC_CLK_TX_DL_CFG(tx_delay)); +} + +static void rk322x_set_to_rmii(struct rk_priv_data *bsp_priv) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON1, +RK322X_GMAC_PHY_INTF_SEL_RMII | +RK322X_GMAC_RMII_MODE); + + /* set MAC to RMII mode */ + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON1, GRF_BIT(11)); +} + +static void rk322x_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = _priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON1, +RK322X_GMAC_CLK_2_5M); + else if (speed == 100) + regmap_write(bsp_priv->grf, RK322X_GRF_MAC_CON1, +RK322X_GMAC_CLK_25M); + else if (speed == 1000) + regmap_write(bsp
Re: [PATCH RESEND] ethernet:arc: Move arc_emac_tx_clean() into arc_emac_tx() and disable tx interrut
On 2016年02月19日 19:13, Michael Niewoehner wrote: Am 19.02.2016 um 07:59 schrieb Shuyu Wei<s...@outlook.com>: Doing tx_clean() inside poll() may scramble the tx ring buffer if tx() is running. This will cause tx to stop working, which can be reproduced by simultaneously downloading two large files at high speed. Moving tx_clean() into tx() will prevent this. And tx interrupt is no longer needed now. Signed-off-by: Shuyu Wei<s...@outlook.com> Tested-by: Michael Niewoehner<li...@mniewoehner.de> Tested-by: Xing Zheng <zhengx...@rock-chips.com> Thanks. -- - Xing Zheng
Re: [RESEND PATCH v1 3/4] net: ethernet: arc: Add support emac for RK3036
OK, I think I will use named structures. Thanks. > 在 2016年1月1日,20:55,Arnd Bergmann <a...@arndb.de> 写道: > >> On Tuesday 29 December 2015 14:59:59 Florian Fainelli wrote: >>> On December 27, 2015 11:22:20 PM PST, Xing Zheng <zhengx...@rock-chips.com> >>> wrote: >>> The RK3036's GRFs offset are different with RK3066/RK3188, and need to >>> set >>> mac TX/RX clock before probe emac. >>> >>> Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> >>> --- >> >>> }; >>> >>> static const struct of_device_id emac_rockchip_dt_ids[] = { >>> - { .compatible = "rockchip,rk3066-emac", .data = >>> _rockchip_dt_data[0] }, >>> - { .compatible = "rockchip,rk3188-emac", .data = >>> _rockchip_dt_data[1] }, >>> + { .compatible = "rockchip,rk3036-emac", .data = >>> _rockchip_dt_data[0] }, >>> + { .compatible = "rockchip,rk3066-emac", .data = >>> _rockchip_dt_data[1] }, >>> + { .compatible = "rockchip,rk3188-emac", .data = >>> _rockchip_dt_data[2] }, >>> { /* Sentinel */ } >> >> Food for thought, you might want to use an enum here to index >> emac_rockchip_dt_data which would be less error prone if you add/remove >> entries in this structure. > > I would use named structures instead: > > static const struct emac_rockchip_soc_data emac_rk3066_emac_data = { >.grf_offset = 0x154, > }; > > static const struct of_device_id emac_rockchip_dt_ids[] = { >{ .compatible = "rockchip,rk3066-emac", .data = _rk3066_emac_data, >... > }; > >Armd > > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] net: ethernet: arc: Probe emac after set RMII clock
Hi David, Sorry, I missed the cover letter. I have added it and resent the patchset. Thanks. - Xing Zheng On 2015年12月28日 13:14, David Miller wrote: I only see 3 patches in this series. Furthermore, you failed to provide a proper "[PATCH 0/4] xxx" posting providing a high level description of what this series is doing, and how it is doing it, and why. Thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v1 1/4] net: ethernet: arc: Probe emac after set RMII clock
After enter arc_emac_probe, emac will get_phy_id, phy_poll_reset and other connecting PHY via mdiobus_read, so we need to set correct ref clock rate for emac before probe emac. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- drivers/net/ethernet/arc/emac_rockchip.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index c31c740..36e9eb1 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -164,10 +164,6 @@ static int emac_rockchip_probe(struct platform_device *pdev) } } - err = arc_emac_probe(ndev, interface); - if (err) - goto out_regulator_disable; - /* write-enable bits */ data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT; @@ -184,6 +180,13 @@ static int emac_rockchip_probe(struct platform_device *pdev) err = clk_set_rate(priv->refclk, 5000); if (err) dev_err(dev, "failed to change reference clock rate (%d)\n", err); + + err = arc_emac_probe(ndev, interface); + if (err) { + dev_err(dev, "failed to probe arc emac (%d)\n", err); + goto out_regulator_disable; + } + return 0; out_regulator_disable: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v1 0/4] Add support emac for the RK3036 SoC platform
Hi, We have supported the emac for RK3066/RK3188, but the RK3036 have some configuration different with them. We should let the driver of emac_rockchip compatible with other Rockchip SoCs. Xing Zheng (4): net: ethernet: arc: Probe emac after set RMII clock net: ethernet: arc: Keep emac compatibility for more Rockchip SoCs net: ethernet: arc: Add support emac for RK3036 ARM: dts: rockchip: Add support emac for RK3036 arch/arm/boot/dts/rk3036-evb.dts | 25 + arch/arm/boot/dts/rk3036-kylin.dts | 23 arch/arm/boot/dts/rk3036.dtsi| 32 +++ drivers/net/ethernet/arc/Kconfig |4 +- drivers/net/ethernet/arc/emac_rockchip.c | 86 -- 5 files changed, 140 insertions(+), 30 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH v1 2/4] net: ethernet: arc: Keep emac compatibility for more Rockchip SoCs
On the RK3066/RK3188, there was fixed GRF offset configuration to set emac and fixed DIV2 mac TX/RX clock. So, we need to easily set and fit to other SoCs (RK3036) which maybe have different GRF offset, and need adjust mac TX/RX clock. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- drivers/net/ethernet/arc/emac_rockchip.c | 66 -- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index 36e9eb1..d1a9c28 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -25,17 +25,13 @@ #include "emac.h" #define DRV_NAME"rockchip_emac" -#define DRV_VERSION "1.0" - -#define GRF_MODE_MII (1UL << 0) -#define GRF_MODE_RMII (0UL << 0) -#define GRF_SPEED_10M (0UL << 1) -#define GRF_SPEED_100M (1UL << 1) -#define GRF_SPEED_ENABLE_BIT (1UL << 17) -#define GRF_MODE_ENABLE_BIT(1UL << 16) +#define DRV_VERSION "1.1" struct emac_rockchip_soc_data { - int grf_offset; + unsigned int grf_offset; + unsigned int grf_mode_offset; + unsigned int grf_speed_offset; + bool need_div_macclk; }; struct rockchip_priv_data { @@ -44,23 +40,22 @@ struct rockchip_priv_data { const struct emac_rockchip_soc_data *soc_data; struct regulator *regulator; struct clk *refclk; + struct clk *macclk; }; static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) { struct rockchip_priv_data *emac = priv; + u32 speed_offset = emac->soc_data->grf_speed_offset; u32 data; int err = 0; - /* write-enable bits */ - data = GRF_SPEED_ENABLE_BIT; - switch(speed) { case 10: - data |= GRF_SPEED_10M; + data = (1 << (speed_offset + 16)) | (0 << speed_offset); break; case 100: - data |= GRF_SPEED_100M; + data = (1 << (speed_offset + 16)) | (1 << speed_offset); break; default: pr_err("speed %u not supported\n", speed); @@ -73,8 +68,14 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) } static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = { - { .grf_offset = 0x154 }, /* rk3066 */ - { .grf_offset = 0x0a4 }, /* rk3188 */ + { + .grf_offset = 0x154, .grf_mode_offset = 0, + .grf_speed_offset = 1, .need_div_macclk = 0 + }, /* rk3066 */ + { + .grf_offset = 0x0a4, .grf_mode_offset = 0, + .grf_speed_offset = 1, .need_div_macclk = 0 + }, /* rk3188 */ }; static const struct of_device_id emac_rockchip_dt_ids[] = { @@ -110,7 +111,7 @@ static int emac_rockchip_probe(struct platform_device *pdev) interface = of_get_phy_mode(dev->of_node); - /* RK3066 and RK3188 SoCs only support RMII */ + /* RK3036/RK3066/RK3188 SoCs only support RMII */ if (interface != PHY_INTERFACE_MODE_RMII) { dev_err(dev, "unsupported phy interface mode %d\n", interface); err = -ENOTSUPP; @@ -164,11 +165,12 @@ static int emac_rockchip_probe(struct platform_device *pdev) } } - /* write-enable bits */ - data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT; - - data |= GRF_SPEED_100M; - data |= GRF_MODE_RMII; + /* Set speed 100M */ + data = (1 << (priv->soc_data->grf_speed_offset + 16)) | + (1 << priv->soc_data->grf_speed_offset); + /* Set RMII mode */ + data |= (1 << (priv->soc_data->grf_mode_offset + 16)) | + (0 << priv->soc_data->grf_mode_offset); err = regmap_write(priv->grf, priv->soc_data->grf_offset, data); if (err) { @@ -181,6 +183,26 @@ static int emac_rockchip_probe(struct platform_device *pdev) if (err) dev_err(dev, "failed to change reference clock rate (%d)\n", err); + if (priv->soc_data->need_div_macclk) { + priv->macclk = devm_clk_get(dev, "macclk"); + if (IS_ERR(priv->macclk)) { + dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk)); + err = PTR_ERR(priv->macclk); + goto out_regulator_disable; + } + + err = clk_prepare_enable(priv->macclk); + if (err) { + dev_err(dev, "failed to enable mac clock (%d)\n", err); + goto out_regulator_disable; + } + + /* RMII TX/RX needs always a rate of 2
[PATCH 2/4] net: ethernet: arc: Keep emac compatibility for more Rockchip SoCs
On the RK3066/RK3188, there was fixed GRF offset configuration to set emac and fixed DIV2 mac TX/RX clock. So, we need to easily set and fit to other SoCs (RK3036) which maybe have different GRF offset, and need adjust mac TX/RX clock. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- drivers/net/ethernet/arc/emac_rockchip.c | 66 -- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index 36e9eb1..d1a9c28 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -25,17 +25,13 @@ #include "emac.h" #define DRV_NAME"rockchip_emac" -#define DRV_VERSION "1.0" - -#define GRF_MODE_MII (1UL << 0) -#define GRF_MODE_RMII (0UL << 0) -#define GRF_SPEED_10M (0UL << 1) -#define GRF_SPEED_100M (1UL << 1) -#define GRF_SPEED_ENABLE_BIT (1UL << 17) -#define GRF_MODE_ENABLE_BIT(1UL << 16) +#define DRV_VERSION "1.1" struct emac_rockchip_soc_data { - int grf_offset; + unsigned int grf_offset; + unsigned int grf_mode_offset; + unsigned int grf_speed_offset; + bool need_div_macclk; }; struct rockchip_priv_data { @@ -44,23 +40,22 @@ struct rockchip_priv_data { const struct emac_rockchip_soc_data *soc_data; struct regulator *regulator; struct clk *refclk; + struct clk *macclk; }; static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) { struct rockchip_priv_data *emac = priv; + u32 speed_offset = emac->soc_data->grf_speed_offset; u32 data; int err = 0; - /* write-enable bits */ - data = GRF_SPEED_ENABLE_BIT; - switch(speed) { case 10: - data |= GRF_SPEED_10M; + data = (1 << (speed_offset + 16)) | (0 << speed_offset); break; case 100: - data |= GRF_SPEED_100M; + data = (1 << (speed_offset + 16)) | (1 << speed_offset); break; default: pr_err("speed %u not supported\n", speed); @@ -73,8 +68,14 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) } static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = { - { .grf_offset = 0x154 }, /* rk3066 */ - { .grf_offset = 0x0a4 }, /* rk3188 */ + { + .grf_offset = 0x154, .grf_mode_offset = 0, + .grf_speed_offset = 1, .need_div_macclk = 0 + }, /* rk3066 */ + { + .grf_offset = 0x0a4, .grf_mode_offset = 0, + .grf_speed_offset = 1, .need_div_macclk = 0 + }, /* rk3188 */ }; static const struct of_device_id emac_rockchip_dt_ids[] = { @@ -110,7 +111,7 @@ static int emac_rockchip_probe(struct platform_device *pdev) interface = of_get_phy_mode(dev->of_node); - /* RK3066 and RK3188 SoCs only support RMII */ + /* RK3036/RK3066/RK3188 SoCs only support RMII */ if (interface != PHY_INTERFACE_MODE_RMII) { dev_err(dev, "unsupported phy interface mode %d\n", interface); err = -ENOTSUPP; @@ -164,11 +165,12 @@ static int emac_rockchip_probe(struct platform_device *pdev) } } - /* write-enable bits */ - data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT; - - data |= GRF_SPEED_100M; - data |= GRF_MODE_RMII; + /* Set speed 100M */ + data = (1 << (priv->soc_data->grf_speed_offset + 16)) | + (1 << priv->soc_data->grf_speed_offset); + /* Set RMII mode */ + data |= (1 << (priv->soc_data->grf_mode_offset + 16)) | + (0 << priv->soc_data->grf_mode_offset); err = regmap_write(priv->grf, priv->soc_data->grf_offset, data); if (err) { @@ -181,6 +183,26 @@ static int emac_rockchip_probe(struct platform_device *pdev) if (err) dev_err(dev, "failed to change reference clock rate (%d)\n", err); + if (priv->soc_data->need_div_macclk) { + priv->macclk = devm_clk_get(dev, "macclk"); + if (IS_ERR(priv->macclk)) { + dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk)); + err = PTR_ERR(priv->macclk); + goto out_regulator_disable; + } + + err = clk_prepare_enable(priv->macclk); + if (err) { + dev_err(dev, "failed to enable mac clock (%d)\n", err); + goto out_regulator_disable; + } + + /* RMII TX/RX needs always a rate of 2
[PATCH 1/4] net: ethernet: arc: Probe emac after set RMII clock
After enter arc_emac_probe, emac will get_phy_id, phy_poll_reset and other connecting PHY via mdiobus_read, so we need to set correct ref clock rate for emac before probe emac. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- drivers/net/ethernet/arc/emac_rockchip.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index c31c740..36e9eb1 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -164,10 +164,6 @@ static int emac_rockchip_probe(struct platform_device *pdev) } } - err = arc_emac_probe(ndev, interface); - if (err) - goto out_regulator_disable; - /* write-enable bits */ data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT; @@ -184,6 +180,13 @@ static int emac_rockchip_probe(struct platform_device *pdev) err = clk_set_rate(priv->refclk, 5000); if (err) dev_err(dev, "failed to change reference clock rate (%d)\n", err); + + err = arc_emac_probe(ndev, interface); + if (err) { + dev_err(dev, "failed to probe arc emac (%d)\n", err); + goto out_regulator_disable; + } + return 0; out_regulator_disable: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] net: ethernet: arc: Add support emac for RK3036
The RK3036's GRFs offset are different with RK3066/RK3188, and need to set mac TX/RX clock before probe emac. Signed-off-by: Xing Zheng <zhengx...@rock-chips.com> --- drivers/net/ethernet/arc/Kconfig |4 ++-- drivers/net/ethernet/arc/emac_rockchip.c |9 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig index 52a6b16..6890451 100644 --- a/drivers/net/ethernet/arc/Kconfig +++ b/drivers/net/ethernet/arc/Kconfig @@ -34,9 +34,9 @@ config EMAC_ROCKCHIP select ARC_EMAC_CORE depends on OF_IRQ && OF_NET && REGULATOR && HAS_DMA ---help--- - Support for Rockchip RK3066/RK3188 EMAC ethernet controllers. + Support for Rockchip RK3036/RK3066/RK3188 EMAC ethernet controllers. This selects Rockchip SoC glue layer support for the - emac device driver. This driver is used for RK3066/RK3188 + emac device driver. This driver is used for RK3036/RK3066/RK3188 EMAC ethernet controller. endif # NET_VENDOR_ARC diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index d1a9c28..2433eeb 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -69,6 +69,10 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = { { + .grf_offset = 0x140, .grf_mode_offset = 8, + .grf_speed_offset = 9, .need_div_macclk = 1 + }, /* rk3036 */ + { .grf_offset = 0x154, .grf_mode_offset = 0, .grf_speed_offset = 1, .need_div_macclk = 0 }, /* rk3066 */ @@ -79,8 +83,9 @@ static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = { }; static const struct of_device_id emac_rockchip_dt_ids[] = { - { .compatible = "rockchip,rk3066-emac", .data = _rockchip_dt_data[0] }, - { .compatible = "rockchip,rk3188-emac", .data = _rockchip_dt_data[1] }, + { .compatible = "rockchip,rk3036-emac", .data = _rockchip_dt_data[0] }, + { .compatible = "rockchip,rk3066-emac", .data = _rockchip_dt_data[1] }, + { .compatible = "rockchip,rk3188-emac", .data = _rockchip_dt_data[2] }, { /* Sentinel */ } }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html