From 634565f815561317f32191df57e11c05aa0b8297 Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:23 +0100 Subject: net: ethernet: stmmac: manage Ethernet WoL for stm32mp157c. Add glue codes to support magic packet on stm32mp157c Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c index 7e2e79dedebf..d1cf145b8986 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -42,6 +42,7 @@ struct stm32_dwmac { struct clk *clk_ethstp; struct clk *syscfg_clk; bool int_phyclk; /* Clock from RCC to drive PHY */ + int irq_pwr_wakeup; u32 mode_reg; /* MAC glue-logic mode register */ struct regmap *regmap; u32 speed; @@ -232,7 +233,9 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct device_node *np = dev->of_node; + int err = 0; dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk"); @@ -260,7 +263,26 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, return PTR_ERR(dwmac->syscfg_clk); } - return 0; + /* Get IRQ information early to have an ability to ask for deferred + * probe if needed before we went too far with resource allocation. + */ + dwmac->irq_pwr_wakeup = platform_get_irq_byname(pdev, + "stm32_pwr_wakeup"); + if (!dwmac->int_phyclk && dwmac->irq_pwr_wakeup >= 0) { + err = device_init_wakeup(&pdev->dev, true); + if (err) { + dev_err(&pdev->dev, "Failed to init wake up irq\n"); + return err; + } + err = dev_pm_set_dedicated_wake_irq(&pdev->dev, + dwmac->irq_pwr_wakeup); + if (err) { + dev_err(&pdev->dev, "Failed to set wake up irq\n"); + device_init_wakeup(&pdev->dev, false); + } + device_set_wakeup_enable(&pdev->dev, false); + } + return err; } static int stm32_dwmac_probe(struct platform_device *pdev) @@ -326,9 +348,15 @@ static int stm32_dwmac_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(ndev); int ret = stmmac_dvr_remove(&pdev->dev); + struct stm32_dwmac *dwmac = priv->plat->bsp_priv; stm32_dwmac_clk_disable(priv->plat->bsp_priv); + if (dwmac->irq_pwr_wakeup >= 0) { + dev_pm_clear_wake_irq(&pdev->dev); + device_init_wakeup(&pdev->dev, false); + } + return ret; } -- cgit v1.2.3-59-g8ed1b From 22947335c4a69bbac72e402bc26edac05a627612 Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:24 +0100 Subject: net: ethernet: stmmac: update to support all PHY config for stm32mp157c. Update glue codes to support all PHY config on stm32mp157c PHY_MODE (MII,GMII, RMII, RGMII) and in normal, PHY wo crystal (25Mhz), PHY wo crystal (50Mhz), No 125Mhz from PHY config. Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 107 +++++++++++++++++----- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c index d1cf145b8986..062a600fa5a7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -25,9 +25,24 @@ #define SYSCFG_MCU_ETH_MASK BIT(23) #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16) +#define SYSCFG_PMCCLRR_OFFSET 0x40 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16) #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17) + +/* Ethernet PHY interface selection in register SYSCFG Configuration + *------------------------------------------ + * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)| + *------------------------------------------ + * MII | 0 | 0 | 0 | 1 | + *------------------------------------------ + * GMII | 0 | 0 | 0 | 0 | + *------------------------------------------ + * RGMII | 0 | 0 | 1 | n/a | + *------------------------------------------ + * RMII | 1 | 0 | 0 | n/a | + *------------------------------------------ + */ #define SYSCFG_PMCR_ETH_SEL_MII BIT(20) #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21) #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23) @@ -35,15 +50,54 @@ #define SYSCFG_MCU_ETH_SEL_MII 0 #define SYSCFG_MCU_ETH_SEL_RMII 1 +/* STM32MP1 register definitions + * + * Below table summarizes the clock requirement and clock sources for + * supported phy interface modes. + * __________________________________________________________________________ + *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY| + *| | | 25MHz | 50MHz | | + * --------------------------------------------------------------------------- + *| MII | - | eth-ck | n/a | n/a | + *| | | | | | + * --------------------------------------------------------------------------- + *| GMII | - | eth-ck | n/a | n/a | + *| | | | | | + * --------------------------------------------------------------------------- + *| RGMII | - | eth-ck | n/a | eth-ck (no pin) | + *| | | | | st,eth-clk-sel | + * --------------------------------------------------------------------------- + *| RMII | - | eth-ck | eth-ck | n/a | + *| | | | st,eth-ref-clk-sel | | + * --------------------------------------------------------------------------- + * + * BIT(17) : set this bit in RMII mode when you have PHY without crystal 50MHz + * BIT(16) : set this bit in GMII/RGMII PHY when you do not want use 125Mhz + * from PHY + *----------------------------------------------------- + * src | BIT(17) | BIT(16) | + *----------------------------------------------------- + * MII | n/a | n/a | + *----------------------------------------------------- + * GMII | n/a | st,eth-clk-sel | + *----------------------------------------------------- + * RGMII | n/a | st,eth-clk-sel | + *----------------------------------------------------- + * RMII | st,eth-ref-clk-sel | n/a | + *----------------------------------------------------- + * + */ + 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 */ + int eth_clk_sel_reg; + int eth_ref_clk_sel_reg; int irq_pwr_wakeup; - u32 mode_reg; /* MAC glue-logic mode register */ + u32 mode_reg; /* MAC glue-logic mode register */ struct regmap *regmap; u32 speed; const struct stm32_ops *ops; @@ -103,7 +157,7 @@ static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare) if (ret) return ret; - if (dwmac->int_phyclk) { + if (dwmac->clk_eth_ck) { ret = clk_prepare_enable(dwmac->clk_eth_ck); if (ret) { clk_disable_unprepare(dwmac->syscfg_clk); @@ -112,7 +166,7 @@ static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare) } } else { clk_disable_unprepare(dwmac->syscfg_clk); - if (dwmac->int_phyclk) + if (dwmac->clk_eth_ck) clk_disable_unprepare(dwmac->clk_eth_ck); } return ret; @@ -122,7 +176,7 @@ 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; + int val, ret; switch (plat_dat->interface) { case PHY_INTERFACE_MODE_MII: @@ -131,19 +185,22 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) break; case PHY_INTERFACE_MODE_GMII: val = SYSCFG_PMCR_ETH_SEL_GMII; - if (dwmac->int_phyclk) + if (dwmac->eth_clk_sel_reg) 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) + if (dwmac->eth_ref_clk_sel_reg) 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) + if (dwmac->eth_clk_sel_reg) val |= SYSCFG_PMCR_ETH_CLK_SEL; pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n"); break; @@ -154,6 +211,11 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) return -EINVAL; } + /* Need to update PMCCLRR (clear register) */ + ret = regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET, + dwmac->ops->syscfg_eth_mask); + + /* Update PMCSETR (set register) */ return regmap_update_bits(dwmac->regmap, reg, dwmac->ops->syscfg_eth_mask, val); } @@ -181,7 +243,7 @@ static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) } return regmap_update_bits(dwmac->regmap, reg, - dwmac->ops->syscfg_eth_mask, val); + dwmac->ops->syscfg_eth_mask, val << 23); } static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) @@ -237,22 +299,25 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, struct device_node *np = dev->of_node; int err = 0; - dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk"); + /* Gigabit Ethernet 125MHz clock selection. */ + dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel"); - /* 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); - } + /* Ethernet 50Mhz RMII clock selection */ + dwmac->eth_ref_clk_sel_reg = + of_property_read_bool(np, "st,eth-ref-clk-sel"); + + /* Get ETH_CLK clocks */ + dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); + if (IS_ERR(dwmac->clk_eth_ck)) { + dev_warn(dev, "No phy clock provided...\n"); + dwmac->clk_eth_ck = NULL; } /* 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"); + dev_err(dev, + "No ETH peripheral clock provided for CStop mode ...\n"); return PTR_ERR(dwmac->clk_ethstp); } @@ -268,7 +333,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, */ dwmac->irq_pwr_wakeup = platform_get_irq_byname(pdev, "stm32_pwr_wakeup"); - if (!dwmac->int_phyclk && dwmac->irq_pwr_wakeup >= 0) { + if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { err = device_init_wakeup(&pdev->dev, true); if (err) { dev_err(&pdev->dev, "Failed to init wake up irq\n"); @@ -370,7 +435,7 @@ static int stm32mp1_suspend(struct stm32_dwmac *dwmac) clk_disable_unprepare(dwmac->clk_tx); clk_disable_unprepare(dwmac->syscfg_clk); - if (dwmac->int_phyclk) + if (dwmac->clk_eth_ck) clk_disable_unprepare(dwmac->clk_eth_ck); return ret; -- cgit v1.2.3-59-g8ed1b From 830133daec63d450e702e6196cec9f0413164164 Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:25 +0100 Subject: dt-bindings: net: stmmac: add phys config properties Add properties to support all Phy config PHY_MODE (MII,GMII, RMII, RGMII) and in normal, PHY wo crystal (25Mhz), PHY wo crystal (50Mhz), No 125Mhz from PHY config. Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/stm32-dwmac.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt index 1341012722aa..3524e80c5e96 100644 --- a/Documentation/devicetree/bindings/net/stm32-dwmac.txt +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -24,9 +24,9 @@ Required properties: encompases the glue register, and the offset of the control register. Optional properties: -- clock-names: For MPU family "mac-clk-ck" for PHY without quartz -- st,int-phyclk (boolean) : valid only where PHY do not have quartz and need to be clock - by RCC +- clock-names: For MPU family "eth-ck" for PHY without quartz +- st,eth-clk-sel (boolean) : set this property in RGMII PHY when you want to select RCC clock instead of ETH_CLK125. +- st,eth-ref-clk-sel (boolean) : set this property in RMII mode when you have PHY without crystal 50MHz and want to select RCC clock instead of ETH_REF_CLK. Example: -- cgit v1.2.3-59-g8ed1b From 81311c03ab4dca83e4f4c678129b4327f2d41b40 Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:26 +0100 Subject: net: ethernet: stmmac: add management of clk_csr property In Documentation stmmac.txt there is possibility to fixed CSR Clock range selection with property clk_csr. This patch add the management of this property For example to use it, add in your ethernet node DT: clk_csr = <3>; Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 2b800ce1d5bf..3031f2bf15d6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -408,6 +408,9 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) /* Default to phy auto-detection */ plat->phy_addr = -1; + /* Get clk_csr from device tree */ + of_property_read_u32(np, "clk_csr", &plat->clk_csr); + /* "snps,phy-addr" is not a standard property. Mark it as deprecated * and warn of its use. Remove this when phy node support is added. */ -- cgit v1.2.3-59-g8ed1b From 835667999019b71114bec4534fcd6c895ebdcbdb Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:27 +0100 Subject: dt-bindings: net: stmmac: remove syscfg clock property Syscfg clock is no more needed. Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/stm32-dwmac.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt index 3524e80c5e96..a90eef11dc46 100644 --- a/Documentation/devicetree/bindings/net/stm32-dwmac.txt +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -14,8 +14,7 @@ Required properties: - clock-names: Should be "stmmaceth" for the host clock. Should be "mac-clk-tx" for the MAC TX clock. Should be "mac-clk-rx" for the MAC RX clock. - For MPU family need to add also "ethstp" for power mode clock and, - "syscfg-clk" for SYSCFG clock. + For MPU family need to add also "ethstp" for power mode clock - interrupt-names: Should contain a list of interrupt names corresponding to the interrupts in the interrupts property, if available. Should be "macirq" for the main MAC IRQ -- cgit v1.2.3-59-g8ed1b From 5473f1be53c90252d3323e69e90a29379e608aaa Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Tue, 5 Mar 2019 09:29:28 +0100 Subject: ARM: dts: stm32: Add Ethernet support on stm32h7 SOC and activate it for eval and disco boards Synopsys GMAC 4.10 is used. And Phy mode for eval and disco is RMII with PHY SMSC LAN8742 Signed-off-by: Christophe Roullier Signed-off-by: David S. Miller --- arch/arm/boot/dts/stm32h743-pinctrl.dtsi | 15 +++++++++++++++ arch/arm/boot/dts/stm32h743.dtsi | 13 +++++++++++++ arch/arm/boot/dts/stm32h743i-disco.dts | 17 +++++++++++++++++ arch/arm/boot/dts/stm32h743i-eval.dts | 17 +++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/arch/arm/boot/dts/stm32h743-pinctrl.dtsi b/arch/arm/boot/dts/stm32h743-pinctrl.dtsi index 24be8e63dec8..980b2769caf9 100644 --- a/arch/arm/boot/dts/stm32h743-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32h743-pinctrl.dtsi @@ -173,6 +173,21 @@ }; }; + ethernet_rmii: rmii@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + usart1_pins: usart1@0 { pins1 { pinmux = ; /* USART1_TX */ diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index cbdd69ca9e7a..e103b29969ca 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -511,6 +511,19 @@ status = "disabled"; }; }; + + mac: ethernet@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-4.10a"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <61>; + interrupt-names = "macirq"; + clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc ETH1MAC_CK>, <&rcc ETH1TX_CK>, <&rcc ETH1RX_CK>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/stm32h743i-disco.dts b/arch/arm/boot/dts/stm32h743i-disco.dts index 45e088c55741..83ef63d515a8 100644 --- a/arch/arm/boot/dts/stm32h743i-disco.dts +++ b/arch/arm/boot/dts/stm32h743i-disco.dts @@ -66,6 +66,23 @@ clock-frequency = <25000000>; }; +&mac { + status = "disabled"; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + &usart2 { pinctrl-0 = <&usart2_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/stm32h743i-eval.dts b/arch/arm/boot/dts/stm32h743i-eval.dts index 3f8e0c4a998d..383c5bb03720 100644 --- a/arch/arm/boot/dts/stm32h743i-eval.dts +++ b/arch/arm/boot/dts/stm32h743i-eval.dts @@ -104,6 +104,23 @@ status = "okay"; }; +&mac { + status = "disabled"; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + &usart1 { pinctrl-0 = <&usart1_pins>; pinctrl-names = "default"; -- cgit v1.2.3-59-g8ed1b