Message ID | 1527090479-5263-1-git-send-email-christophe.roullier@st.com |
---|---|
Headers | show |
Series | net: ethernet: stmmac: add support for stm32mp1 | expand |
From: Christophe Roullier <christophe.roullier@st.com> Date: Wed, 23 May 2018 17:47:51 +0200 > Patches to have Ethernet support on stm32mp1 > Changelog: > Remark from Rob Herring > Move Documentation/devicetree/bindings/arm/stm32.txt in > Documentation/devicetree/bindings/arm/stm32/stm32.txt and create > Documentation/devicetree/bindings/arm/stm32/stm32-syscon.txt > > Replace also in arch/arm/boot/dts/stm32mp157c.dtsi, syscfg: system-config@50020000 > with syscfg: syscon@50020000syscfg: system-config@50020000 Probably the DTS file updates need to go in via the ARM tree, not mine. Can you respin a net-next targetted series that has just the driver code and device tree binding updates? Thank you! -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 05/23/2018 10:08 PM, David Miller wrote: > From: Christophe Roullier <christophe.roullier@st.com> > Date: Wed, 23 May 2018 17:47:51 +0200 > >> Patches to have Ethernet support on stm32mp1 >> Changelog: >> Remark from Rob Herring >> Move Documentation/devicetree/bindings/arm/stm32.txt in >> Documentation/devicetree/bindings/arm/stm32/stm32.txt and create >> Documentation/devicetree/bindings/arm/stm32/stm32-syscon.txt >> >> Replace also in arch/arm/boot/dts/stm32mp157c.dtsi, syscfg: system-config@50020000 >> with syscfg: syscon@50020000syscfg: system-config@50020000 > > Probably the DTS file updates need to go in via the ARM tree, not > mine. Yes I will take them in my tree > > Can you respin a net-next targetted series that has just the driver > code and device tree binding updates? > > Thank you! > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, On 05/23/2018 05:47 PM, Christophe Roullier wrote: > Glue codes to support stm32mp157c device and stay > compatible with stm32 mcu family > > Signed-off-by: Christophe Roullier <christophe.roullier@st.com> > --- Acked-by: Alexandre TORGUE <alexandre.torgue@st.com> > drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 270 ++++++++++++++++++++-- > 1 file changed, 255 insertions(+), 15 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c > index 9e6db16..f51e327 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c > @@ -16,49 +16,183 @@ > #include <linux/of_net.h> > #include <linux/phy.h> > #include <linux/platform_device.h> > +#include <linux/pm_wakeirq.h> > #include <linux/regmap.h> > #include <linux/slab.h> > #include <linux/stmmac.h> > > #include "stmmac_platform.h" > > -#define MII_PHY_SEL_MASK BIT(23) > +#define SYSCFG_MCU_ETH_MASK BIT(23) > +#define SYSCFG_MP1_ETH_MASK GENMASK(23, 16) > + > +#define SYSCFG_PMCR_ETH_CLK_SEL BIT(16) > +#define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17) > +#define SYSCFG_PMCR_ETH_SEL_MII BIT(20) > +#define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21) > +#define SYSCFG_PMCR_ETH_SEL_RMII BIT(23) > +#define SYSCFG_PMCR_ETH_SEL_GMII 0 > +#define SYSCFG_MCU_ETH_SEL_MII 0 > +#define SYSCFG_MCU_ETH_SEL_RMII 1 > > struct stm32_dwmac { > struct clk *clk_tx; > struct clk *clk_rx; > + struct clk *clk_eth_ck; > + struct clk *clk_ethstp; > + struct clk *syscfg_clk; > + bool int_phyclk; /* Clock from RCC to drive PHY */ > u32 mode_reg; /* MAC glue-logic mode register */ > struct regmap *regmap; > u32 speed; > + const struct stm32_ops *ops; > + struct device *dev; > +}; > + > +struct stm32_ops { > + int (*set_mode)(struct plat_stmmacenet_data *plat_dat); > + int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare); > + int (*suspend)(struct stm32_dwmac *dwmac); > + void (*resume)(struct stm32_dwmac *dwmac); > + int (*parse_data)(struct stm32_dwmac *dwmac, > + struct device *dev); > + u32 syscfg_eth_mask; > }; > > static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) > { > struct stm32_dwmac *dwmac = plat_dat->bsp_priv; > - u32 reg = dwmac->mode_reg; > - u32 val; > int ret; > > - val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; > - ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); > - if (ret) > - return ret; > + if (dwmac->ops->set_mode) { > + ret = dwmac->ops->set_mode(plat_dat); > + if (ret) > + return ret; > + } > > ret = clk_prepare_enable(dwmac->clk_tx); > if (ret) > return ret; > > - ret = clk_prepare_enable(dwmac->clk_rx); > - if (ret) > - clk_disable_unprepare(dwmac->clk_tx); > + if (!dwmac->dev->power.is_suspended) { > + ret = clk_prepare_enable(dwmac->clk_rx); > + if (ret) { > + clk_disable_unprepare(dwmac->clk_tx); > + return ret; > + } > + } > + > + if (dwmac->ops->clk_prepare) { > + ret = dwmac->ops->clk_prepare(dwmac, true); > + if (ret) { > + clk_disable_unprepare(dwmac->clk_rx); > + clk_disable_unprepare(dwmac->clk_tx); > + } > + } > > return ret; > } > > +static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare) > +{ > + int ret = 0; > + > + if (prepare) { > + ret = clk_prepare_enable(dwmac->syscfg_clk); > + if (ret) > + return ret; > + > + if (dwmac->int_phyclk) { > + ret = clk_prepare_enable(dwmac->clk_eth_ck); > + if (ret) { > + clk_disable_unprepare(dwmac->syscfg_clk); > + return ret; > + } > + } > + } else { > + clk_disable_unprepare(dwmac->syscfg_clk); > + if (dwmac->int_phyclk) > + clk_disable_unprepare(dwmac->clk_eth_ck); > + } > + return ret; > +} > + > +static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) > +{ > + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; > + u32 reg = dwmac->mode_reg; > + int val; > + > + switch (plat_dat->interface) { > + case PHY_INTERFACE_MODE_MII: > + val = SYSCFG_PMCR_ETH_SEL_MII; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); > + break; > + case PHY_INTERFACE_MODE_GMII: > + val = SYSCFG_PMCR_ETH_SEL_GMII; > + if (dwmac->int_phyclk) > + val |= SYSCFG_PMCR_ETH_CLK_SEL; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n"); > + break; > + case PHY_INTERFACE_MODE_RMII: > + val = SYSCFG_PMCR_ETH_SEL_RMII; > + if (dwmac->int_phyclk) > + val |= SYSCFG_PMCR_ETH_REF_CLK_SEL; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); > + break; > + case PHY_INTERFACE_MODE_RGMII: > + case PHY_INTERFACE_MODE_RGMII_ID: > + case PHY_INTERFACE_MODE_RGMII_RXID: > + case PHY_INTERFACE_MODE_RGMII_TXID: > + val = SYSCFG_PMCR_ETH_SEL_RGMII; > + if (dwmac->int_phyclk) > + val |= SYSCFG_PMCR_ETH_CLK_SEL; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n"); > + break; > + default: > + pr_debug("SYSCFG init : Do not manage %d interface\n", > + plat_dat->interface); > + /* Do not manage others interfaces */ > + return -EINVAL; > + } > + > + return regmap_update_bits(dwmac->regmap, reg, > + dwmac->ops->syscfg_eth_mask, val); > +} > + > +static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) > +{ > + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; > + u32 reg = dwmac->mode_reg; > + int val; > + > + switch (plat_dat->interface) { > + case PHY_INTERFACE_MODE_MII: > + val = SYSCFG_MCU_ETH_SEL_MII; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); > + break; > + case PHY_INTERFACE_MODE_RMII: > + val = SYSCFG_MCU_ETH_SEL_RMII; > + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); > + break; > + default: > + pr_debug("SYSCFG init : Do not manage %d interface\n", > + plat_dat->interface); > + /* Do not manage others interfaces */ > + return -EINVAL; > + } > + > + return regmap_update_bits(dwmac->regmap, reg, > + dwmac->ops->syscfg_eth_mask, val); > +} > + > static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) > { > clk_disable_unprepare(dwmac->clk_tx); > clk_disable_unprepare(dwmac->clk_rx); > + > + if (dwmac->ops->clk_prepare) > + dwmac->ops->clk_prepare(dwmac, false); > } > > static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, > @@ -70,15 +204,22 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, > /* Get TX/RX clocks */ > dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); > if (IS_ERR(dwmac->clk_tx)) { > - dev_err(dev, "No tx clock provided...\n"); > + dev_err(dev, "No ETH Tx clock provided...\n"); > return PTR_ERR(dwmac->clk_tx); > } > + > dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); > if (IS_ERR(dwmac->clk_rx)) { > - dev_err(dev, "No rx clock provided...\n"); > + dev_err(dev, "No ETH Rx clock provided...\n"); > return PTR_ERR(dwmac->clk_rx); > } > > + if (dwmac->ops->parse_data) { > + err = dwmac->ops->parse_data(dwmac, dev); > + if (err) > + return err; > + } > + > /* Get mode register */ > dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); > if (IS_ERR(dwmac->regmap)) > @@ -91,11 +232,46 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, > return err; > } > > +static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, > + struct device *dev) > +{ > + struct device_node *np = dev->of_node; > + > + dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk"); > + > + /* Check if internal clk from RCC selected */ > + if (dwmac->int_phyclk) { > + /* Get ETH_CLK clocks */ > + dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); > + if (IS_ERR(dwmac->clk_eth_ck)) { > + dev_err(dev, "No ETH CK clock provided...\n"); > + return PTR_ERR(dwmac->clk_eth_ck); > + } > + } > + > + /* Clock used for low power mode */ > + dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); > + if (IS_ERR(dwmac->clk_ethstp)) { > + dev_err(dev, "No ETH peripheral clock provided for CStop mode ...\n"); > + return PTR_ERR(dwmac->clk_ethstp); > + } > + > + /* Clock for sysconfig */ > + dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); > + if (IS_ERR(dwmac->syscfg_clk)) { > + dev_err(dev, "No syscfg clock provided...\n"); > + return PTR_ERR(dwmac->syscfg_clk); > + } > + > + return 0; > +} > + > static int stm32_dwmac_probe(struct platform_device *pdev) > { > struct plat_stmmacenet_data *plat_dat; > struct stmmac_resources stmmac_res; > struct stm32_dwmac *dwmac; > + const struct stm32_ops *data; > int ret; > > ret = stmmac_get_platform_resources(pdev, &stmmac_res); > @@ -112,6 +288,16 @@ static int stm32_dwmac_probe(struct platform_device *pdev) > goto err_remove_config_dt; > } > > + data = of_device_get_match_data(&pdev->dev); > + if (!data) { > + dev_err(&pdev->dev, "no of match data provided\n"); > + ret = -EINVAL; > + goto err_remove_config_dt; > + } > + > + dwmac->ops = data; > + dwmac->dev = &pdev->dev; > + > ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); > if (ret) { > dev_err(&pdev->dev, "Unable to parse OF data\n"); > @@ -149,15 +335,48 @@ static int stm32_dwmac_remove(struct platform_device *pdev) > return ret; > } > > +static int stm32mp1_suspend(struct stm32_dwmac *dwmac) > +{ > + int ret = 0; > + > + ret = clk_prepare_enable(dwmac->clk_ethstp); > + if (ret) > + return ret; > + > + clk_disable_unprepare(dwmac->clk_tx); > + clk_disable_unprepare(dwmac->syscfg_clk); > + if (dwmac->int_phyclk) > + clk_disable_unprepare(dwmac->clk_eth_ck); > + > + return ret; > +} > + > +static void stm32mp1_resume(struct stm32_dwmac *dwmac) > +{ > + clk_disable_unprepare(dwmac->clk_ethstp); > +} > + > +static int stm32mcu_suspend(struct stm32_dwmac *dwmac) > +{ > + clk_disable_unprepare(dwmac->clk_tx); > + clk_disable_unprepare(dwmac->clk_rx); > + > + return 0; > +} > + > #ifdef CONFIG_PM_SLEEP > static int stm32_dwmac_suspend(struct device *dev) > { > struct net_device *ndev = dev_get_drvdata(dev); > struct stmmac_priv *priv = netdev_priv(ndev); > + struct stm32_dwmac *dwmac = priv->plat->bsp_priv; > + > int ret; > > ret = stmmac_suspend(dev); > - stm32_dwmac_clk_disable(priv->plat->bsp_priv); > + > + if (dwmac->ops->suspend) > + ret = dwmac->ops->suspend(dwmac); > > return ret; > } > @@ -166,8 +385,12 @@ static int stm32_dwmac_resume(struct device *dev) > { > struct net_device *ndev = dev_get_drvdata(dev); > struct stmmac_priv *priv = netdev_priv(ndev); > + struct stm32_dwmac *dwmac = priv->plat->bsp_priv; > int ret; > > + if (dwmac->ops->resume) > + dwmac->ops->resume(dwmac); > + > ret = stm32_dwmac_init(priv->plat); > if (ret) > return ret; > @@ -181,8 +404,24 @@ static int stm32_dwmac_resume(struct device *dev) > static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, > stm32_dwmac_suspend, stm32_dwmac_resume); > > +static struct stm32_ops stm32mcu_dwmac_data = { > + .set_mode = stm32mcu_set_mode, > + .suspend = stm32mcu_suspend, > + .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK > +}; > + > +static struct stm32_ops stm32mp1_dwmac_data = { > + .set_mode = stm32mp1_set_mode, > + .clk_prepare = stm32mp1_clk_prepare, > + .suspend = stm32mp1_suspend, > + .resume = stm32mp1_resume, > + .parse_data = stm32mp1_parse_data, > + .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK > +}; > + > static const struct of_device_id stm32_dwmac_match[] = { > - { .compatible = "st,stm32-dwmac"}, > + { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data}, > + { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data}, > { } > }; > MODULE_DEVICE_TABLE(of, stm32_dwmac_match); > @@ -199,5 +438,6 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, > module_platform_driver(stm32_dwmac_driver); > > MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>"); > -MODULE_DESCRIPTION("STMicroelectronics MCU DWMAC Specific Glue layer"); > +MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>"); > +MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer"); > MODULE_LICENSE("GPL v2"); > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi christophe On 05/23/2018 05:47 PM, Christophe Roullier wrote: > Add Ethernet support (Synopsys MAC IP 4.20a) on stm32mp1 SOC. > Enable feature supported by the stmmac driver, such as TSO. > > Signed-off-by: Christophe Roullier <christophe.roullier@st.com> > --- > arch/arm/boot/dts/stm32mp157c.dtsi | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi > index 3db03a2..ea7b6cb 100644 > --- a/arch/arm/boot/dts/stm32mp157c.dtsi > +++ b/arch/arm/boot/dts/stm32mp157c.dtsi > @@ -179,5 +179,35 @@ > clocks = <&rcc USART1_K>; > status = "disabled"; > }; > + > + stmmac_axi_config_0: stmmac-axi-config { > + snps,wr_osr_lmt = <0x7>; > + snps,rd_osr_lmt = <0x7>; > + snps,blen = <0 0 0 0 16 8 4>; > + }; > + > + ethernet0: ethernet@5800a000 { > + compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; > + reg = <0x5800a000 0x2000>; > + reg-names = "stmmaceth"; > + interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_NONE>; IRQ_TYPE_NONE souldn't be used. Please provide edge sensitiv or level sensitic type. > + interrupt-names = "macirq"; > + clock-names = "stmmaceth", > + "mac-clk-tx", > + "mac-clk-rx", > + "ethstp", > + "syscfg-clk"; > + clocks = <&rcc ETHMAC>, > + <&rcc ETHTX>, > + <&rcc ETHRX>, > + <&rcc ETHSTP>, > + <&rcc SYSCFG>; > + st,syscon = <&syscfg 0x4>; > + snps,mixed-burst; > + snps,pbl = <2>; > + snps,axi-config = <&stmmac_axi_config_0>; > + snps,tso; > + status = "disabled"; > + }; > }; > }; > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Christophe, On 05/23/2018 05:47 PM, Christophe Roullier wrote: > Patches to have Ethernet support on stm32mp1 > Changelog: > Remark from Rob Herring > Move Documentation/devicetree/bindings/arm/stm32.txt in > Documentation/devicetree/bindings/arm/stm32/stm32.txt and create > Documentation/devicetree/bindings/arm/stm32/stm32-syscon.txt > > Replace also in arch/arm/boot/dts/stm32mp157c.dtsi, syscfg: system-config@50020000 > with syscfg: syscon@50020000syscfg: system-config@50020000 > > Christophe Roullier (8): > net: ethernet: stmmac: add adaptation for stm32mp157c. > dt-bindings: stm32-dwmac: add support of MPU families > ARM: dts: stm32: add ethernet pins to stm32mp157c > ARM: dts: stm32: Add syscfg on stm32mp1 > ARM: dts: stm32: Add ethernet dwmac on stm32mp1 > net: stmmac: add dwmac-4.20a compatible > ARM: dts: stm32: add support of ethernet on stm32mp157c-ev1 > dt-bindings: stm32: add compatible for syscon > > Documentation/devicetree/bindings/arm/stm32.txt | 10 - > .../devicetree/bindings/arm/stm32/stm32-syscon.txt | 14 ++ > .../devicetree/bindings/arm/stm32/stm32.txt | 10 + > .../devicetree/bindings/net/stm32-dwmac.txt | 18 +- > arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 46 ++++ > arch/arm/boot/dts/stm32mp157c-ev1.dts | 20 ++ > arch/arm/boot/dts/stm32mp157c.dtsi | 35 +++ > drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 270 +++++++++++++++++++-- > .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 +- > 9 files changed, 398 insertions(+), 28 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/arm/stm32.txt > create mode 100644 Documentation/devicetree/bindings/arm/stm32/stm32-syscon.txt > create mode 100644 Documentation/devicetree/bindings/arm/stm32/stm32.txt > As discussed I squashed "ARM: dts: stm32: add ethernet pins to stm32mp157c" and "ARM: dts: stm32: add support of ethernet on stm32mp157c-ev1" ans fixed interrupt binding issue. So DT patches applied on stm32-next. regards Alex -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html