From a23d354fff0b2b89331c952e50a78af8d4eee7ca Mon Sep 17 00:00:00 2001 From: Roger Chen <roger.chen@rock-chips.com> Date: Mon, 9 Nov 2015 21:04:35 +0800 Subject: [PATCH] net: rockchip: gmac: support RK3228 Change-Id: I1cf343d2d7768681b7ec2ad0d95484267d59b82b Signed-off-by: Roger Chen <roger.chen@rock-chips.com> --- arch/arm/boot/dts/rk3228-sdk.dts | 17 ++ arch/arm/boot/dts/rk3228.dtsi | 20 +++ drivers/net/ethernet/rockchip/gmac/stmmac.h | 3 +- .../ethernet/rockchip/gmac/stmmac_platform.c | 160 +++++++++++++++--- 4 files changed, 180 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/rk3228-sdk.dts b/arch/arm/boot/dts/rk3228-sdk.dts index ffcf00ef981c..f4d7e682d1a4 100755 --- a/arch/arm/boot/dts/rk3228-sdk.dts +++ b/arch/arm/boot/dts/rk3228-sdk.dts @@ -276,3 +276,20 @@ <0xb5 KEY_BACKSPACE>; }; }; + +&gmac_clkin { + clock-frequency = <125000000>; +}; + +&gmac { + /* pmu_regulator = "act_ldo5"; */ + /* power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>; */ + /* reset-gpio = <&gpio3 GPIO_B4 GPIO_ACTIVE_LOW>; */ + /* phyirq-gpio = <&gpio0 GPIO_B1 GPIO_ACTIVE_LOW>; */ + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rmii_pins>; + clock_in_out = "input"; + tx_delay = <0x30>; + rx_delay = <0x10>; +}; diff --git a/arch/arm/boot/dts/rk3228.dtsi b/arch/arm/boot/dts/rk3228.dtsi index ffe2f8a2a9d2..ea548866c031 100755 --- a/arch/arm/boot/dts/rk3228.dtsi +++ b/arch/arm/boot/dts/rk3228.dtsi @@ -739,6 +739,26 @@ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; }; + gmac: eth@30200000 { + compatible = "rockchip,rk3228-gmac"; + reg = <0x30200000 0x10000>; + rockchip,grf = <&grf>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clocks = <&clk_mac>, <&clk_gates5 5>, + <&clk_gates5 6>, <&clk_gates5 3>, + <&clk_gates5 4>, <&clk_gates11 4>, + <&clk_gates11 5>; + clock-names = "clk_mac", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", + "pclk_mac"; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + status = "disabled"; + }; + pinctrl: pinctrl { compatible = "rockchip,rk3228-pinctrl"; rockchip,grf = <&grf>; diff --git a/drivers/net/ethernet/rockchip/gmac/stmmac.h b/drivers/net/ethernet/rockchip/gmac/stmmac.h index 810d2b342741..4c134020cb00 100755 --- a/drivers/net/ethernet/rockchip/gmac/stmmac.h +++ b/drivers/net/ethernet/rockchip/gmac/stmmac.h @@ -113,7 +113,8 @@ struct stmmac_priv { enum { RK3288_GMAC, RK312X_GMAC, - RK3368_GMAC + RK3368_GMAC, + RK3228_GMAC }; struct bsp_priv { diff --git a/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c b/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c index 39e670a6ea85..e8076e5a993a 100755 --- a/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c +++ b/drivers/net/ethernet/rockchip/gmac/stmmac_platform.c @@ -39,13 +39,13 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); -/*for RK3288 & RK3128*/ +/* for RK3288 & RK3128 */ #define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset) #define grf_writel(v, offset) \ do { writel_relaxed(v, RK_GRF_VIRT + offset); dsb(sy); } while (0) -/*RK3288_GRF_SOC_CON1*/ -/*RK3128_GRF_MAC_CON1*/ +/* RK3288_GRF_SOC_CON1 */ +/* RK3128_GRF_MAC_CON1 */ #define GMAC_PHY_INTF_SEL_RGMII ((0x01C0 << 16) | (0x0040)) #define GMAC_PHY_INTF_SEL_RMII ((0x01C0 << 16) | (0x0100)) #define GMAC_FLOW_CTRL ((0x0200 << 16) | (0x0200)) @@ -60,8 +60,8 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); #define GMAC_RMII_MODE ((0x4000 << 16) | (0x4000)) #define GMAC_RMII_MODE_CLR ((0x4000 << 16) | (0x0000)) -/*RK3288_GRF_SOC_CON3*/ -/*RK3128_GRF_MAC_CON0*/ +/* RK3288_GRF_SOC_CON3 */ +/* RK3128_GRF_MAC_CON0 */ #define GMAC_TXCLK_DLY_ENABLE ((0x4000 << 16) | (0x4000)) #define GMAC_TXCLK_DLY_DISABLE ((0x4000 << 16) | (0x0000)) #define GMAC_RXCLK_DLY_ENABLE ((0x8000 << 16) | (0x8000)) @@ -69,7 +69,7 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); #define GMAC_CLK_RX_DL_CFG(val) ((0x3F80 << 16) | (val<<7)) #define GMAC_CLK_TX_DL_CFG(val) ((0x007F << 16) | (val)) -/*for RK3368*/ +/* for RK3368 */ #define HIWORD_UPDATE(val, mask, shift) \ ((val) << (shift) | (mask) << ((shift) + 16)) @@ -79,7 +79,7 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); #define RK3368_GRF_SOC_CON15 0x043c #define RK3368_GRF_SOC_CON16 0x0440 -/*RK3368_GRF_SOC_CON15*/ +/* RK3368_GRF_SOC_CON15 */ #define RK3368_GMAC_PHY_INTF_SEL_RGMII \ (GRF_BIT(9) | GRF_CLR_BIT(10) | GRF_CLR_BIT(11)) #define RK3368_GMAC_PHY_INTF_SEL_RMII \ @@ -96,7 +96,7 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); #define RK3368_GMAC_RMII_MODE GRF_BIT(6) #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) -/*RK3368_GRF_SOC_CON16*/ +/* RK3368_GRF_SOC_CON16 */ #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) @@ -104,6 +104,34 @@ static u64 gmac_dmamask = DMA_BIT_MASK(32); #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) +#define RK3228_GRF_MAC_CON0 0x0900 +#define RK3228_GRF_MAC_CON1 0x0904 + +/* 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) + +/* 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) + static void SET_RGMII(struct bsp_priv *bsp_priv, int type, int tx_delay, int rx_delay) { @@ -141,6 +169,24 @@ static void SET_RGMII(struct bsp_priv *bsp_priv, int type, RK3368_GMAC_TXCLK_DLY_ENABLE | RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + 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)); } } @@ -164,6 +210,18 @@ static void SET_RMII(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_PHY_INTF_SEL_RMII | + RK3228_GMAC_RMII_MODE); } } @@ -184,6 +242,17 @@ static void SET_RGMII_10M(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_CLK_2_5M); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_2_5M); } } @@ -204,6 +273,17 @@ static void SET_RGMII_100M(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_CLK_25M); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_25M); } } @@ -224,6 +304,17 @@ static void SET_RGMII_1000M(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_CLK_125M); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_125M); } } @@ -247,6 +338,19 @@ static void SET_RMII_10M(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_RMII_CLK_2_5M | RK3368_GMAC_SPEED_10M); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_RMII_CLK_2_5M | + RK3228_GMAC_SPEED_10M); + } } @@ -270,10 +374,23 @@ static void SET_RMII_100M(struct bsp_priv *bsp_priv, int type) regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, RK3368_GMAC_RMII_CLK_25M | RK3368_GMAC_SPEED_100M); + } else if (type == RK3228_GMAC) { + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", + __func__); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_RMII_CLK_25M | + RK3228_GMAC_SPEED_100M); + } } -struct bsp_priv g_bsp_priv; +static struct bsp_priv g_bsp_priv; int gmac_clk_init(struct device *device) { @@ -461,13 +578,13 @@ static int power_on_by_pmu(bool enable) { static int power_on_by_gpio(bool enable) { struct bsp_priv * bsp_priv = &g_bsp_priv; if (enable) { - /*power on*/ + /* power on */ if (gpio_is_valid(bsp_priv->power_io)) { gpio_direction_output(bsp_priv->power_io, bsp_priv->power_io_level); } } else { - /*power off*/ + /* power off */ if (gpio_is_valid(bsp_priv->power_io)) { gpio_direction_output(bsp_priv->power_io, !bsp_priv->power_io_level); @@ -491,7 +608,7 @@ static int phy_power_on(bool enable) } if (enable) { - //reset + /* reset */ if (gpio_is_valid(bsp_priv->reset_io)) { gpio_direction_output(bsp_priv->reset_io, bsp_priv->reset_io_level); @@ -502,7 +619,7 @@ static int phy_power_on(bool enable) mdelay(30); } else { - //pull down reset + /* pull down reset */ if (gpio_is_valid(bsp_priv->reset_io)) { gpio_direction_output(bsp_priv->reset_io, bsp_priv->reset_io_level); @@ -520,7 +637,7 @@ int stmmc_pltfr_init(struct platform_device *pdev) { pr_info("%s:\n", __func__); phy_iface = bsp_priv->phy_iface; -//power +/* power */ if (!gpio_is_valid(bsp_priv->power_io)) { pr_err("%s: ERROR: Get power-gpio failed.\n", __func__); } else { @@ -572,7 +689,7 @@ int stmmc_pltfr_init(struct platform_device *pdev) { } } -/*rmii or rgmii*/ +/* rmii or rgmii */ if (phy_iface == PHY_INTERFACE_MODE_RGMII) { pr_info("%s: init for RGMII\n", __func__); SET_RGMII(bsp_priv, bsp_priv->chip, @@ -716,10 +833,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, of_get_named_gpio_flags(np, "phyirq-gpio", 0, &flags); g_bsp_priv.phyirq_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; - g_bsp_priv.reset_io = + g_bsp_priv.reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); g_bsp_priv.reset_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; - g_bsp_priv.power_io = + g_bsp_priv.power_io = of_get_named_gpio_flags(np, "power-gpio", 0, &flags); g_bsp_priv.power_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; @@ -736,7 +853,8 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, */ if (of_device_is_compatible(np, "rockchip,rk3288-gmac") || of_device_is_compatible(np, "rockchip,rk312x-gmac") || - of_device_is_compatible(np, "rockchip,rk3368-gmac")) { + of_device_is_compatible(np, "rockchip,rk3368-gmac") || + of_device_is_compatible(np, "rockchip,rk3228-gmac")) { plat->has_gmac = 1; plat->pmt = 1; } @@ -750,6 +868,9 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, } else if (of_device_is_compatible(np, "rockchip,rk3368-gmac")) { g_bsp_priv.chip = RK3368_GMAC; pr_info("%s: is rockchip,rk3368-gmac\n", __func__); + } else if (of_device_is_compatible(np, "rockchip,rk3228-gmac")) { + g_bsp_priv.chip = RK3228_GMAC; + pr_info("%s: is rockchip,rk3228-gmac\n", __func__); } else { pr_info("%s: unknown platform\n", __func__); } @@ -811,7 +932,7 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) plat_dat = pdev->dev.platform_data; } - /* Custom initialisation (if needed)*/ + /* Custom initialisation (if needed) */ if (plat_dat->init) { ret = plat_dat->init(pdev); if (unlikely(ret)) @@ -938,6 +1059,7 @@ static const struct of_device_id stmmac_dt_ids[] = { { .compatible = "rockchip,rk3288-gmac"}, { .compatible = "rockchip,rk312x-gmac"}, { .compatible = "rockchip,rk3368-gmac"}, + { .compatible = "rockchip,rk3228-gmac"}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, stmmac_dt_ids); -- 2.34.1