2024-04-26 13:00:23

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 00/11] Series to deliver Ethernets for STM32MP13

STM32MP13 is STM32 SOC with 2 GMACs instances
This board have 2 RMII phy:
-Ethernet1: RMII with crystal
-Ethernet2: RMII without crystal
Rework dwmac glue to simplify management for next stm32
Add support for PHY regulator

V2: - Remark from Rob Herring (add Krzysztof's ack in patch 02/11, update in yaml)
Remark from Serge Semin (upate commits msg)

Christophe Roullier (11):
dt-bindings: net: add STM32MP13 compatible in documentation for stm32
dt-bindings: net: add phy-supply property for stm32
net: stmmac: dwmac-stm32: rework glue to simplify management
net: stmmac: dwmac-stm32: add management of stm32mp13
net: stmmac: dwmac-stm32: update config management for phy wo cristal
net: stmmac: dwmac-stm32: clean the way to manage wol irqwake
net: stmmac: dwmac-stm32: support the phy-supply regulator binding
ARM: dts: stm32: add ethernet1 and ethernet2 support on stm32mp13
ARM: dts: stm32: add ethernet1/2 RMII pins for STM32MP13F-DK board
ARM: dts: stm32: add ethernet1 and ethernet2 for STM32MP135F-DK board
ARM: multi_v7_defconfig: Add MCP23S08 pinctrl support

.../devicetree/bindings/net/stm32-dwmac.yaml | 79 +++++-
arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 71 ++++++
arch/arm/boot/dts/st/stm32mp131.dtsi | 31 +++
arch/arm/boot/dts/st/stm32mp133.dtsi | 30 +++
arch/arm/boot/dts/st/stm32mp135f-dk.dts | 48 ++++
arch/arm/configs/multi_v7_defconfig | 1 +
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 235 ++++++++++++------
7 files changed, 416 insertions(+), 79 deletions(-)

--
2.25.1



2024-04-26 13:00:31

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 08/11] ARM: dts: stm32: add ethernet1 and ethernet2 support on stm32mp13

Both instances ethernet based on GMAC SNPS IP on stm32mp13.
GMAC IP version is SNPS 4.20.

Signed-off-by: Christophe Roullier <[email protected]>
---
arch/arm/boot/dts/st/stm32mp131.dtsi | 31 ++++++++++++++++++++++++++++
arch/arm/boot/dts/st/stm32mp133.dtsi | 30 +++++++++++++++++++++++++++
2 files changed, 61 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index ecfa120827ba..00d258d2032e 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -854,6 +854,37 @@ crc1: crc@58009000 {
status = "disabled";
};

+ ethernet1: ethernet@5800a000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 68 1>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH1MAC>,
+ <&rcc ETH1TX>,
+ <&rcc ETH1RX>,
+ <&rcc ETH1STP>,
+ <&rcc ETH1CK_K>;
+ st,syscon = <&syscfg 0x4 0xff0000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_1>;
+ snps,tso;
+ status = "disabled";
+
+ stmmac_axi_config_1: stmmac-axi-config {
+ snps,wr_osr_lmt = <0x7>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,blen = <0 0 0 0 16 8 4>;
+ };
+ };
+
usbh_ohci: usb@5800c000 {
compatible = "generic-ohci";
reg = <0x5800c000 0x1000>;
diff --git a/arch/arm/boot/dts/st/stm32mp133.dtsi b/arch/arm/boot/dts/st/stm32mp133.dtsi
index 3e394c8e58b9..2796d15276df 100644
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -68,4 +68,34 @@ channel@18 {
};
};
};
+
+ ethernet2: ethernet@5800e000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800e000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH2MAC>,
+ <&rcc ETH2TX>,
+ <&rcc ETH2RX>,
+ <&rcc ETH2STP>,
+ <&rcc ETH2CK_K>;
+ st,syscon = <&syscfg 0x4 0xff000000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_2>;
+ snps,tso;
+ status = "disabled";
+
+ stmmac_axi_config_2: stmmac-axi-config {
+ snps,wr_osr_lmt = <0x7>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,blen = <0 0 0 0 16 8 4>;
+ };
+ };
};
--
2.25.1


2024-04-26 13:00:34

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 02/11] dt-bindings: net: add phy-supply property for stm32

Phandle to a regulator that provides power to the PHY. This
regulator will be managed during the PHY power on/off sequence.

Acked-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Christophe Roullier <[email protected]>
---
Documentation/devicetree/bindings/net/stm32-dwmac.yaml | 3 +++
1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
index b901a432dfa9..7c3aa181abcb 100644
--- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
@@ -84,6 +84,9 @@ properties:
- description: offset of the control register
- description: field to set mask in register

+ phy-supply:
+ description: PHY regulator
+
st,eth-clk-sel:
description:
set this property in RGMII PHY when you want to select RCC clock instead of ETH_CLK125.
--
2.25.1


2024-04-26 13:00:58

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 04/11] net: stmmac: dwmac-stm32: add management of stm32mp13

Add Ethernet support for STM32MP13.
STM32MP13 is STM32 SOC with 2 GMACs instances.
GMAC IP version is SNPS 4.20.
GMAC IP configure with 1 RX and 1 TX queue.
DMA HW capability register supported
RX Checksum Offload Engine supported
TX Checksum insertion supported
Wake-Up On Lan supported
TSO supported

Signed-off-by: Christophe Roullier <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index 68a02de25ac7..7529a8d15492 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -517,9 +517,30 @@ static struct stm32_ops stm32mp1_dwmac_data = {
}
};

+static struct stm32_ops stm32mp13_dwmac_data = {
+ .set_mode = stm32mp1_set_mode,
+ .suspend = stm32mp1_suspend,
+ .resume = stm32mp1_resume,
+ .parse_data = stm32mp1_parse_data,
+ .clk_rx_enable_in_suspend = true,
+ .syscfg_clr_off = 0x08,
+ .pmcsetr = {
+ .eth1_clk_sel = BIT(16),
+ .eth1_ref_clk_sel = BIT(17),
+ .eth1_selmii = 0,
+ .eth1_sel_rgmii = BIT(21),
+ .eth1_sel_rmii = BIT(23),
+ .eth2_clk_sel = BIT(24),
+ .eth2_ref_clk_sel = BIT(25),
+ .eth2_sel_rgmii = BIT(29),
+ .eth2_sel_rmii = BIT(31)
+ }
+};
+
static const struct of_device_id stm32_dwmac_match[] = {
{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
+ { .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
--
2.25.1


2024-04-26 13:02:08

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 06/11] net: stmmac: dwmac-stm32: clean the way to manage wol irqwake

On STM32 platforms it is no longer needed to use a dedicated wakeup to
wake up system from CStop. This patch removes the dedicated wake up usage
and clean the way to register the wake up irq.

Signed-off-by: Christophe Roullier <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 66 +++++++++----------
1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index e648c4e790a7..5d8f4eac4bc0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -81,7 +81,6 @@ struct stm32_dwmac {
int enable_eth_ck;
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_mask;
struct regmap *regmap;
@@ -312,9 +311,7 @@ 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;

/* Ethernet PHY have no crystal */
dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
@@ -346,29 +343,24 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
if (IS_ERR(dwmac->syscfg_clk))
dwmac->syscfg_clk = NULL;

- /* 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_optional(pdev,
- "stm32_pwr_wakeup");
- if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-
- 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");
- 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 0;
+}
+
+static int stm32_dwmac_wake_init(struct device *dev,
+ struct stmmac_resources *stmmac_res)
+{
+ int err;
+
+ device_set_wakeup_capable(dev, true);
+
+ err = dev_pm_set_wake_irq(dev, stmmac_res->wol_irq);
+ if (err) {
+ dev_err(dev, "Failed to set wake up irq\n");
+ device_set_wakeup_capable(dev, false);
+ return err;
}
- return err;
+
+ return 0;
}

static int stm32_dwmac_probe(struct platform_device *pdev)
@@ -406,11 +398,17 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
return ret;
}

+ if (stmmac_res.wol_irq && !dwmac->clk_eth_ck) {
+ ret = stm32_dwmac_wake_init(&pdev->dev, &stmmac_res);
+ if (ret)
+ goto err_wake_init_disable;
+ }
+
plat_dat->bsp_priv = dwmac;

ret = stm32_dwmac_init(plat_dat, false);
if (ret)
- return ret;
+ goto err_wake_init_disable;

ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
@@ -420,7 +418,11 @@ static int stm32_dwmac_probe(struct platform_device *pdev)

err_clk_disable:
stm32_dwmac_clk_disable(dwmac, false);
-
+err_wake_init_disable:
+ if (stmmac_res.wol_irq && !dwmac->clk_eth_ck) {
+ dev_pm_clear_wake_irq(&pdev->dev);
+ device_set_wakeup_capable(&pdev->dev, false);
+ }
return ret;
}

@@ -428,16 +430,12 @@ static void stm32_dwmac_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(ndev);
- struct stm32_dwmac *dwmac = priv->plat->bsp_priv;

stmmac_dvr_remove(&pdev->dev);
+ stm32_dwmac_clk_disable(priv->plat->bsp_priv, false);

- stm32_dwmac_clk_disable(dwmac, false);
-
- if (dwmac->irq_pwr_wakeup >= 0) {
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
- }
+ dev_pm_clear_wake_irq(&pdev->dev);
+ device_init_wakeup(&pdev->dev, false);
}

static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
--
2.25.1


2024-04-26 13:02:41

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 07/11] net: stmmac: dwmac-stm32: support the phy-supply regulator binding

Configure the phy regulator if defined by the "phy-supply" DT phandle.

Signed-off-by: Christophe Roullier <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 51 ++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index 5d8f4eac4bc0..964173d08026 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -14,6 +14,7 @@
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -84,6 +85,7 @@ struct stm32_dwmac {
u32 mode_reg; /* MAC glue-logic mode register */
u32 mode_mask;
struct regmap *regmap;
+ struct regulator *regulator;
u32 speed;
const struct stm32_ops *ops;
struct device *dev;
@@ -305,6 +307,16 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
if (err)
pr_debug("Warning sysconfig register mask not set\n");

+ dwmac->regulator = devm_regulator_get_optional(dev, "phy");
+ if (IS_ERR(dwmac->regulator)) {
+ if (PTR_ERR(dwmac->regulator) == -EPROBE_DEFER) {
+ dev_dbg(dev, "phy regulator is not available yet, deferred probing\n");
+ return -EPROBE_DEFER;
+ }
+ dev_dbg(dev, "no regulator found\n");
+ dwmac->regulator = NULL;
+ }
+
return 0;
}

@@ -363,6 +375,27 @@ static int stm32_dwmac_wake_init(struct device *dev,
return 0;
}

+static int phy_power_on(struct stm32_dwmac *bsp_priv, bool enable)
+{
+ int ret;
+ struct device *dev = bsp_priv->dev;
+
+ if (!bsp_priv->regulator)
+ return 0;
+
+ if (enable) {
+ ret = regulator_enable(bsp_priv->regulator);
+ if (ret)
+ dev_err(dev, "fail to enable phy-supply\n");
+ } else {
+ ret = regulator_disable(bsp_priv->regulator);
+ if (ret)
+ dev_err(dev, "fail to disable phy-supply\n");
+ }
+
+ return ret;
+}
+
static int stm32_dwmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
@@ -410,12 +443,18 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
if (ret)
goto err_wake_init_disable;

- ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ ret = phy_power_on(plat_dat->bsp_priv, true);
if (ret)
goto err_clk_disable;

+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (ret)
+ goto err_gmac_powerdown;
+
return 0;

+err_gmac_powerdown:
+ phy_power_on(plat_dat->bsp_priv, false);
err_clk_disable:
stm32_dwmac_clk_disable(dwmac, false);
err_wake_init_disable:
@@ -436,6 +475,8 @@ static void stm32_dwmac_remove(struct platform_device *pdev)

dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
+
+ phy_power_on(priv->plat->bsp_priv, false);
}

static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
@@ -466,6 +507,10 @@ static int stm32_dwmac_suspend(struct device *dev)
if (dwmac->ops->suspend)
ret = dwmac->ops->suspend(dwmac);

+ /* Keep the PHY up if we use Wake-on-Lan. */
+ if (!device_may_wakeup(dwmac->dev))
+ phy_power_on(dwmac, false);
+
return ret;
}

@@ -479,6 +524,10 @@ static int stm32_dwmac_resume(struct device *dev)
if (dwmac->ops->resume)
dwmac->ops->resume(dwmac);

+ /* The PHY was up for Wake-on-Lan. */
+ if (!device_may_wakeup(dwmac->dev))
+ phy_power_on(dwmac, true);
+
ret = stm32_dwmac_init(priv->plat, true);
if (ret)
return ret;
--
2.25.1


2024-04-26 13:02:43

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 03/11] net: stmmac: dwmac-stm32: rework glue to simplify management

Change glue to be more generic and manage easily next stm32 products.
The goal of this commit is to have one stm32mp1_set_mode function which
can manage different STM32 SOC. SOC can have different SYSCFG register
bitfields. so in pmcsetr we defined the bitfields corresponding to the SOC.

Signed-off-by: Christophe Roullier <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 76 +++++++++++++------
1 file changed, 51 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index c92dfc4ecf57..68a02de25ac7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -23,10 +23,6 @@

#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)

/* CLOCK feed to PHY*/
#define ETH_CK_F_25M 25000000
@@ -46,9 +42,6 @@
* 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)
#define SYSCFG_PMCR_ETH_SEL_GMII 0
#define SYSCFG_MCU_ETH_SEL_MII 0
#define SYSCFG_MCU_ETH_SEL_RMII 1
@@ -90,19 +83,33 @@ struct stm32_dwmac {
int eth_ref_clk_sel_reg;
int irq_pwr_wakeup;
u32 mode_reg; /* MAC glue-logic mode register */
+ u32 mode_mask;
struct regmap *regmap;
u32 speed;
const struct stm32_ops *ops;
struct device *dev;
};

+struct stm32_syscfg_pmcsetr {
+ u32 eth1_clk_sel;
+ u32 eth1_ref_clk_sel;
+ u32 eth1_selmii;
+ u32 eth1_sel_rgmii;
+ u32 eth1_sel_rmii;
+ u32 eth2_clk_sel;
+ u32 eth2_ref_clk_sel;
+ u32 eth2_sel_rgmii;
+ u32 eth2_sel_rmii;
+};
+
struct stm32_ops {
int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
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;
+ u32 syscfg_clr_off;
+ struct stm32_syscfg_pmcsetr pmcsetr;
bool clk_rx_enable_in_suspend;
};

@@ -161,7 +168,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, clk_rate;
- int val;
+ int val = 0;

clk_rate = clk_get_rate(dwmac->clk_eth_ck);
dwmac->enable_eth_ck = false;
@@ -169,7 +176,7 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
case PHY_INTERFACE_MODE_MII:
if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
dwmac->enable_eth_ck = true;
- val = SYSCFG_PMCR_ETH_SEL_MII;
+ val = dwmac->ops->pmcsetr.eth1_selmii;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
@@ -177,16 +184,17 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
if (clk_rate == ETH_CK_F_25M &&
(dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
dwmac->enable_eth_ck = true;
- val |= SYSCFG_PMCR_ETH_CLK_SEL;
+ val |= dwmac->ops->pmcsetr.eth1_clk_sel;
}
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
- val = SYSCFG_PMCR_ETH_SEL_RMII;
+ val = dwmac->ops->pmcsetr.eth1_sel_rmii | dwmac->ops->pmcsetr.eth2_sel_rmii;
if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
dwmac->enable_eth_ck = true;
- val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
+ val |= dwmac->ops->pmcsetr.eth1_ref_clk_sel;
+ val |= dwmac->ops->pmcsetr.eth2_ref_clk_sel;
}
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
@@ -194,11 +202,12 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
- val = SYSCFG_PMCR_ETH_SEL_RGMII;
+ val = dwmac->ops->pmcsetr.eth1_sel_rgmii | dwmac->ops->pmcsetr.eth2_sel_rgmii;
if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
(dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
dwmac->enable_eth_ck = true;
- val |= SYSCFG_PMCR_ETH_CLK_SEL;
+ val |= dwmac->ops->pmcsetr.eth1_clk_sel;
+ val |= dwmac->ops->pmcsetr.eth2_clk_sel;
}
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
break;
@@ -210,12 +219,12 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
}

/* Need to update PMCCLRR (clear register) */
- regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
- dwmac->ops->syscfg_eth_mask);
+ regmap_write(dwmac->regmap, reg + dwmac->ops->syscfg_clr_off,
+ dwmac->mode_mask);

/* Update PMCSETR (set register) */
return regmap_update_bits(dwmac->regmap, reg,
- dwmac->ops->syscfg_eth_mask, val);
+ dwmac->mode_mask, val);
}

static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -241,7 +250,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 << 23);
+ SYSCFG_MCU_ETH_MASK, val << 23);
}

static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
@@ -286,10 +295,17 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
return PTR_ERR(dwmac->regmap);

err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
+ if (err) {
+ dev_err(dev, "Can't get sysconfig register offset (%d)\n", err);
+ return err;
+ }
+
+ dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
+ err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
if (err)
- dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
+ pr_debug("Warning sysconfig register mask not set\n");

- return err;
+ return 0;
}

static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
@@ -478,8 +494,7 @@ 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,
- .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
+ .set_mode = stm32mcu_set_mode
};

static struct stm32_ops stm32mp1_dwmac_data = {
@@ -487,8 +502,19 @@ static struct stm32_ops stm32mp1_dwmac_data = {
.suspend = stm32mp1_suspend,
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
- .clk_rx_enable_in_suspend = true
+ .clk_rx_enable_in_suspend = true,
+ .syscfg_clr_off = 0x44,
+ .pmcsetr = {
+ .eth1_clk_sel = BIT(16),
+ .eth1_ref_clk_sel = BIT(17),
+ .eth1_selmii = BIT(20),
+ .eth1_sel_rgmii = BIT(21),
+ .eth1_sel_rmii = BIT(23),
+ .eth2_clk_sel = 0,
+ .eth2_ref_clk_sel = 0,
+ .eth2_sel_rgmii = 0,
+ .eth2_sel_rmii = 0
+ }
};

static const struct of_device_id stm32_dwmac_match[] = {
--
2.25.1


2024-04-26 13:03:12

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 09/11] ARM: dts: stm32: add ethernet1/2 RMII pins for STM32MP13F-DK board

Those pins are used for Ethernet 1 and 2 on STM32MP13F-DK board.
ethernet1: RMII with crystal.
ethernet2: RMII without crystal.
Add analog gpio pin configuration ("sleep") to manage power mode on
stm32mp13.

Signed-off-by: Christophe Roullier <[email protected]>
---
arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 71 +++++++++++++++++++++
1 file changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
index 32c5d8a1e06a..7f72c62da0a6 100644
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -13,6 +13,77 @@ pins {
};
};

+ eth1_rmii_pins_a: eth1-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, AF10)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+
+ };
+
+ eth1_rmii_sleep_pins_a: eth1-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
+ eth2_rmii_pins_a: eth2-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, AF10)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, AF13)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, AF10)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, AF11)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+ };
+
+ eth2_rmii_sleep_pins_a: eth2-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('F', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
--
2.25.1


2024-04-26 13:03:20

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 05/11] net: stmmac: dwmac-stm32: update config management for phy wo cristal

Some cleaning because some Ethernet PHY configs do not need to add
st,ext-phyclk property.
Change print info message "No phy clock provided" only when debug.

Signed-off-by: Christophe Roullier <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 27 ++++++++++---------
1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index 7529a8d15492..e648c4e790a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -55,17 +55,17 @@
*| | | 25MHz | 50MHz | |
* ---------------------------------------------------------------------------
*| MII | - | eth-ck | n/a | n/a |
- *| | | st,ext-phyclk | | |
+ *| | | | | |
* ---------------------------------------------------------------------------
*| GMII | - | eth-ck | n/a | n/a |
- *| | | st,ext-phyclk | | |
+ *| | | | | |
* ---------------------------------------------------------------------------
*| RGMII | - | eth-ck | n/a | eth-ck |
- *| | | st,ext-phyclk | | st,eth-clk-sel or|
+ *| | | | | st,eth-clk-sel or|
*| | | | | st,ext-phyclk |
* ---------------------------------------------------------------------------
*| RMII | - | eth-ck | eth-ck | n/a |
- *| | | st,ext-phyclk | st,eth-ref-clk-sel | |
+ *| | | | st,eth-ref-clk-sel | |
*| | | | or st,ext-phyclk | |
* ---------------------------------------------------------------------------
*
@@ -174,23 +174,22 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
dwmac->enable_eth_ck = false;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
+ if (clk_rate == ETH_CK_F_25M)
dwmac->enable_eth_ck = true;
val = dwmac->ops->pmcsetr.eth1_selmii;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
- if (clk_rate == ETH_CK_F_25M &&
- (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (clk_rate == ETH_CK_F_25M)
dwmac->enable_eth_ck = true;
- val |= dwmac->ops->pmcsetr.eth1_clk_sel;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = dwmac->ops->pmcsetr.eth1_sel_rmii | dwmac->ops->pmcsetr.eth2_sel_rmii;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
+ if (clk_rate == ETH_CK_F_25M)
+ dwmac->enable_eth_ck = true;
+ if (clk_rate == ETH_CK_F_50M &&
(dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
dwmac->enable_eth_ck = true;
val |= dwmac->ops->pmcsetr.eth1_ref_clk_sel;
@@ -203,7 +202,9 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = dwmac->ops->pmcsetr.eth1_sel_rgmii | dwmac->ops->pmcsetr.eth2_sel_rgmii;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
+ if (clk_rate == ETH_CK_F_25M)
+ dwmac->enable_eth_ck = true;
+ if (clk_rate == ETH_CK_F_125M &&
(dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
dwmac->enable_eth_ck = true;
val |= dwmac->ops->pmcsetr.eth1_clk_sel;
@@ -219,7 +220,7 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
}

/* Need to update PMCCLRR (clear register) */
- regmap_write(dwmac->regmap, reg + dwmac->ops->syscfg_clr_off,
+ regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
dwmac->mode_mask);

/* Update PMCSETR (set register) */
@@ -328,7 +329,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
/* Get ETH_CLK clocks */
dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
if (IS_ERR(dwmac->clk_eth_ck)) {
- dev_info(dev, "No phy clock provided...\n");
+ dev_dbg(dev, "No phy clock provided...\n");
dwmac->clk_eth_ck = NULL;
}

--
2.25.1


2024-04-26 13:03:50

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 10/11] ARM: dts: stm32: add ethernet1 and ethernet2 for STM32MP135F-DK board

Add dual Ethernet:
-Ethernet1: RMII with crystal
-Ethernet2: RMII without crystal
PHYs used are SMSC (LAN8742A)

With Ethernet1, we can performed WoL from PHY instead of GMAC point
of view.
(in this case IRQ for WoL is managed as wakeup pin and configured
in OS secure).

Signed-off-by: Christophe Roullier <[email protected]>
---
arch/arm/boot/dts/st/stm32mp135f-dk.dts | 48 +++++++++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index 567e53ad285f..3b8eb0ab9ab9 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -19,6 +19,8 @@ / {
compatible = "st,stm32mp135f-dk", "st,stm32mp135";

aliases {
+ ethernet0 = &ethernet1;
+ ethernet1 = &ethernet2;
serial0 = &uart4;
serial1 = &usart1;
serial2 = &uart8;
@@ -141,6 +143,52 @@ &cryp {
status = "okay";
};

+&ethernet1 {
+ status = "okay";
+ pinctrl-0 = <&eth1_rmii_pins_a>;
+ pinctrl-1 = <&eth1_rmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rmii";
+ max-speed = <100>;
+ phy-handle = <&phy0_eth1>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy0_eth1: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0007.c131";
+ reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>;
+ reg = <0>;
+ wakeup-source;
+ };
+ };
+};
+
+&ethernet2 {
+ status = "okay";
+ pinctrl-0 = <&eth2_rmii_pins_a>;
+ pinctrl-1 = <&eth2_rmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rmii";
+ max-speed = <100>;
+ phy-handle = <&phy0_eth2>;
+ st,ext-phyclk;
+ phy-supply = <&scmi_v3v3_sw>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ phy0_eth2: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0007.c131";
+ reset-gpios = <&mcp23017 10 GPIO_ACTIVE_LOW>;
+ reg = <0>;
+ };
+ };
+};
+
&i2c1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c1_pins_a>;
--
2.25.1


2024-04-26 13:03:58

by Christophe Roullier

[permalink] [raw]
Subject: [PATCH v2 11/11] ARM: multi_v7_defconfig: Add MCP23S08 pinctrl support

Need to enable MCP23S08 I/O expanders to manage Ethernet phy
reset in STM32MP135F-DK board
STMMAC driver defer is not silent, need to put this config in
built-in to avoid huge of Ethernet messages

Signed-off-by: Christophe Roullier <[email protected]>
---
arch/arm/configs/multi_v7_defconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b2955dcb5a53..0abbe00372df 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -469,6 +469,7 @@ CONFIG_SPI_XILINX=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_MCP23S08=y
CONFIG_PINCTRL_MICROCHIP_SGPIO=y
CONFIG_PINCTRL_OCELOT=y
CONFIG_PINCTRL_PALMAS=y
--
2.25.1


2024-04-26 14:22:59

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v2 00/11] Series to deliver Ethernets for STM32MP13


On Fri, 26 Apr 2024 14:56:56 +0200, Christophe Roullier wrote:
> STM32MP13 is STM32 SOC with 2 GMACs instances
> This board have 2 RMII phy:
> -Ethernet1: RMII with crystal
> -Ethernet2: RMII without crystal
> Rework dwmac glue to simplify management for next stm32
> Add support for PHY regulator
>
> V2: - Remark from Rob Herring (add Krzysztof's ack in patch 02/11, update in yaml)
> Remark from Serge Semin (upate commits msg)
>
> Christophe Roullier (11):
> dt-bindings: net: add STM32MP13 compatible in documentation for stm32
> dt-bindings: net: add phy-supply property for stm32
> net: stmmac: dwmac-stm32: rework glue to simplify management
> net: stmmac: dwmac-stm32: add management of stm32mp13
> net: stmmac: dwmac-stm32: update config management for phy wo cristal
> net: stmmac: dwmac-stm32: clean the way to manage wol irqwake
> net: stmmac: dwmac-stm32: support the phy-supply regulator binding
> ARM: dts: stm32: add ethernet1 and ethernet2 support on stm32mp13
> ARM: dts: stm32: add ethernet1/2 RMII pins for STM32MP13F-DK board
> ARM: dts: stm32: add ethernet1 and ethernet2 for STM32MP135F-DK board
> ARM: multi_v7_defconfig: Add MCP23S08 pinctrl support
>
> .../devicetree/bindings/net/stm32-dwmac.yaml | 79 +++++-
> arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 71 ++++++
> arch/arm/boot/dts/st/stm32mp131.dtsi | 31 +++
> arch/arm/boot/dts/st/stm32mp133.dtsi | 30 +++
> arch/arm/boot/dts/st/stm32mp135f-dk.dts | 48 ++++
> arch/arm/configs/multi_v7_defconfig | 1 +
> .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 235 ++++++++++++------
> 7 files changed, 416 insertions(+), 79 deletions(-)
>
> --
> 2.25.1
>
>
>


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y st/stm32mp135f-dk.dtb' for [email protected]:

arch/arm/boot/dts/st/stm32mp135f-dk.dtb: ethernet@5800e000: Unevaluated properties are not allowed ('st,ext-phyclk' was unexpected)
from schema $id: http://devicetree.org/schemas/net/stm32-dwmac.yaml#






2024-04-26 15:34:43

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v2 02/11] dt-bindings: net: add phy-supply property for stm32

On Fri, Apr 26, 2024 at 02:56:58PM +0200, Christophe Roullier wrote:
> Phandle to a regulator that provides power to the PHY. This
> regulator will be managed during the PHY power on/off sequence.
>
> Acked-by: Krzysztof Kozlowski <[email protected]>
> Signed-off-by: Christophe Roullier <[email protected]>
> ---
> Documentation/devicetree/bindings/net/stm32-dwmac.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
> index b901a432dfa9..7c3aa181abcb 100644
> --- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
> @@ -84,6 +84,9 @@ properties:
> - description: offset of the control register
> - description: field to set mask in register
>
> + phy-supply:
> + description: PHY regulator

This is for which PHY? The serdes phy or ethernet phy? This only makes
sense here if the phy is part of the MAC. Otherwise, it belongs in the
phy node.

Rob

2024-04-26 16:01:32

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 06/11] net: stmmac: dwmac-stm32: clean the way to manage wol irqwake

On 4/26/24 2:57 PM, Christophe Roullier wrote:
> On STM32 platforms it is no longer needed to use a dedicated wakeup to
> wake up system from CStop.

This really needs more clarification.

Why was the code needed before ? Maybe because it was used by some of
the older STM32F4/F7/H7 SoCs ? Is it still needed by those SoCs ? Will
this patch break those older SoCs ?

> This patch removes the dedicated wake up usage
> and clean the way to register the wake up irq.

[...]

2024-04-26 16:02:28

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 05/11] net: stmmac: dwmac-stm32: update config management for phy wo cristal

On 4/26/24 2:57 PM, Christophe Roullier wrote:
> Some cleaning because some Ethernet PHY configs do not need to add
> st,ext-phyclk property.
> Change print info message "No phy clock provided" only when debug.
>
> Signed-off-by: Christophe Roullier <[email protected]>
> ---
> .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 27 ++++++++++---------
> 1 file changed, 14 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index 7529a8d15492..e648c4e790a7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -55,17 +55,17 @@
> *| | | 25MHz | 50MHz | |
> * ---------------------------------------------------------------------------
> *| MII | - | eth-ck | n/a | n/a |
> - *| | | st,ext-phyclk | | |
> + *| | | | | |
> * ---------------------------------------------------------------------------
> *| GMII | - | eth-ck | n/a | n/a |
> - *| | | st,ext-phyclk | | |
> + *| | | | | |
> * ---------------------------------------------------------------------------
> *| RGMII | - | eth-ck | n/a | eth-ck |
> - *| | | st,ext-phyclk | | st,eth-clk-sel or|
> + *| | | | | st,eth-clk-sel or|
> *| | | | | st,ext-phyclk |
> * ---------------------------------------------------------------------------
> *| RMII | - | eth-ck | eth-ck | n/a |
> - *| | | st,ext-phyclk | st,eth-ref-clk-sel | |
> + *| | | | st,eth-ref-clk-sel | |
> *| | | | or st,ext-phyclk | |
> * ---------------------------------------------------------------------------
> *
> @@ -174,23 +174,22 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> dwmac->enable_eth_ck = false;
> switch (plat_dat->mac_interface) {
> case PHY_INTERFACE_MODE_MII:
> - if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
> + if (clk_rate == ETH_CK_F_25M)

I see two problems here.

First, according to the table above, in MII mode, clk_rate cannot be
anything else but 25 MHz, so the (clk_rate == ETH_CK_F_25M) condition is
always true. Why not drop that condition ?

The "dwmac->ext_phyclk" means "Ethernet PHY have no crystal", which
means the clock are provided by the STM32 RCC clock IP instead, which
means if the dwmac->ext_phyclk is true, dwmac->enable_eth_ck should be
set to true, because dwmac->enable_eth_ck controls the enablement of
these STM32 clock IP generated clock.

Second, as far as I understand it, there is no way to operate this IP
with external clock in MII mode, so this section should always be only:

dwmac->enable_eth_ck = true;

> dwmac->enable_eth_ck = true;
> val = dwmac->ops->pmcsetr.eth1_selmii;
> pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
> break;
> case PHY_INTERFACE_MODE_GMII:
> val = SYSCFG_PMCR_ETH_SEL_GMII;
> - if (clk_rate == ETH_CK_F_25M &&
> - (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
> + if (clk_rate == ETH_CK_F_25M)
> dwmac->enable_eth_ck = true;
> - val |= dwmac->ops->pmcsetr.eth1_clk_sel;
> - }
> pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
> break;
> case PHY_INTERFACE_MODE_RMII:
> val = dwmac->ops->pmcsetr.eth1_sel_rmii | dwmac->ops->pmcsetr.eth2_sel_rmii;
> - if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
> + if (clk_rate == ETH_CK_F_25M)
> + dwmac->enable_eth_ck = true;
> + if (clk_rate == ETH_CK_F_50M &&
> (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {

This doesn't seem to be equivalent change to the previous code . Here,
if the clock frequency is 25 MHz, the clock are unconditionally enabled.
Before, the code enabled the clock only if clock frequency was 25 MHz
AND one of the "dwmac->eth_ref_clk_sel_reg" or "dwmac->ext_phyclk" was
set (i.e. clock provided by SoC RCC clock IP).

I think it might make this code easier if you drop all of the frequency
test conditionals, which aren't really all that useful, and only enable
the clock if either dwmac->ext_phyclk / dwmac->eth_clk_sel_reg /
dwmac->eth_ref_clk_sel_reg is set , because effectively what this entire
convoluted code is implementing is "if (clock supplied by clock IP i.e.
RCC) enable the clock()" *, right ?

* And it is also toggling the right clock mux bit in PMCSETR.

So, for MII this would be plain:
dwmac->enable_eth_ck = true;

For GMII/RGMII this would be:
if (dwmac->ext_phyclk || dwmac->eth_clk_sel_reg)
dwmac->enable_eth_ck = true;

For RMII this would be:
if (dwmac->ext_phyclk || dwmac->eth_ref_clk_sel_reg)
dwmac->enable_eth_ck = true;

Maybe the clock frequency validation can be retained, but done separately?

> dwmac->enable_eth_ck = true;
> val |= dwmac->ops->pmcsetr.eth1_ref_clk_sel;
> @@ -203,7 +202,9 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> case PHY_INTERFACE_MODE_RGMII_RXID:
> case PHY_INTERFACE_MODE_RGMII_TXID:
> val = dwmac->ops->pmcsetr.eth1_sel_rgmii | dwmac->ops->pmcsetr.eth2_sel_rgmii;
> - if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
> + if (clk_rate == ETH_CK_F_25M)
> + dwmac->enable_eth_ck = true;
> + if (clk_rate == ETH_CK_F_125M &&
> (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
> dwmac->enable_eth_ck = true;
> val |= dwmac->ops->pmcsetr.eth1_clk_sel;
> @@ -219,7 +220,7 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> }
>
> /* Need to update PMCCLRR (clear register) */
> - regmap_write(dwmac->regmap, reg + dwmac->ops->syscfg_clr_off,
> + regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
> dwmac->mode_mask);
>
> /* Update PMCSETR (set register) */
> @@ -328,7 +329,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
> /* Get ETH_CLK clocks */
> dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
> if (IS_ERR(dwmac->clk_eth_ck)) {
> - dev_info(dev, "No phy clock provided...\n");
> + dev_dbg(dev, "No phy clock provided...\n");
> dwmac->clk_eth_ck = NULL;
> }
>

2024-04-26 16:03:12

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 10/11] ARM: dts: stm32: add ethernet1 and ethernet2 for STM32MP135F-DK board

On 4/26/24 2:57 PM, Christophe Roullier wrote:
> Add dual Ethernet:
> -Ethernet1: RMII with crystal
> -Ethernet2: RMII without crystal
> PHYs used are SMSC (LAN8742A)
>
> With Ethernet1, we can performed WoL from PHY instead of GMAC point
> of view.
> (in this case IRQ for WoL is managed as wakeup pin and configured
> in OS secure).

How does the Linux PHY driver process such a PHY IRQ ?

Or is Linux unaware of the PHY IRQ ? Doesn't that cause issues ?

> diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
> index 567e53ad285f..3b8eb0ab9ab9 100644
> --- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
> +++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
> @@ -19,6 +19,8 @@ / {
> compatible = "st,stm32mp135f-dk", "st,stm32mp135";
>
> aliases {
> + ethernet0 = &ethernet1;
> + ethernet1 = &ethernet2;
> serial0 = &uart4;
> serial1 = &usart1;
> serial2 = &uart8;
> @@ -141,6 +143,52 @@ &cryp {
> status = "okay";
> };
>
> +&ethernet1 {
> + status = "okay";
> + pinctrl-0 = <&eth1_rmii_pins_a>;
> + pinctrl-1 = <&eth1_rmii_sleep_pins_a>;
> + pinctrl-names = "default", "sleep";
> + phy-mode = "rmii";
> + max-speed = <100>;
> + phy-handle = <&phy0_eth1>;

Keep the list sorted please (is the max-speed even needed? if not, drop it)

> + mdio {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "snps,dwmac-mdio";
> +
> + phy0_eth1: ethernet-phy@0 {
> + compatible = "ethernet-phy-id0007.c131";
> + reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>;
> + reg = <0>;
> + wakeup-source;
> + };
> + };
> +};
> +
> +&ethernet2 {
> + status = "okay";
> + pinctrl-0 = <&eth2_rmii_pins_a>;
> + pinctrl-1 = <&eth2_rmii_sleep_pins_a>;
> + pinctrl-names = "default", "sleep";
> + phy-mode = "rmii";
> + max-speed = <100>;
> + phy-handle = <&phy0_eth2>;
> + st,ext-phyclk;
> + phy-supply = <&scmi_v3v3_sw>;

Sort please

[...]

2024-04-26 16:03:32

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 07/11] net: stmmac: dwmac-stm32: support the phy-supply regulator binding

On 4/26/24 2:57 PM, Christophe Roullier wrote:
> Configure the phy regulator if defined by the "phy-supply" DT phandle.
>
> Signed-off-by: Christophe Roullier <[email protected]>

Maybe this should be separate from this series ?

2024-04-26 16:25:49

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 02/11] dt-bindings: net: add phy-supply property for stm32

On 4/26/24 2:56 PM, Christophe Roullier wrote:
> Phandle to a regulator that provides power to the PHY. This
> regulator will be managed during the PHY power on/off sequence.
>
> Acked-by: Krzysztof Kozlowski <[email protected]>
> Signed-off-by: Christophe Roullier <[email protected]>

Maybe this entire regulator business should be separate series from the
MP13 DWMAC ethernet series ?

2024-04-26 16:27:20

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH v2 03/11] net: stmmac: dwmac-stm32: rework glue to simplify management

On 4/26/24 2:56 PM, Christophe Roullier wrote:
> Change glue to be more generic and manage easily next stm32 products.
> The goal of this commit is to have one stm32mp1_set_mode function which
> can manage different STM32 SOC. SOC can have different SYSCFG register
> bitfields. so in pmcsetr we defined the bitfields corresponding to the SOC.
>
> Signed-off-by: Christophe Roullier <[email protected]>
> ---
> .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 76 +++++++++++++------
> 1 file changed, 51 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index c92dfc4ecf57..68a02de25ac7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -23,10 +23,6 @@
>
> #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)
>
> /* CLOCK feed to PHY*/
> #define ETH_CK_F_25M 25000000
> @@ -46,9 +42,6 @@
> * 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)
> #define SYSCFG_PMCR_ETH_SEL_GMII 0
> #define SYSCFG_MCU_ETH_SEL_MII 0
> #define SYSCFG_MCU_ETH_SEL_RMII 1
> @@ -90,19 +83,33 @@ struct stm32_dwmac {
> int eth_ref_clk_sel_reg;
> int irq_pwr_wakeup;
> u32 mode_reg; /* MAC glue-logic mode register */
> + u32 mode_mask;
> struct regmap *regmap;
> u32 speed;
> const struct stm32_ops *ops;
> struct device *dev;
> };
>
> +struct stm32_syscfg_pmcsetr {
> + u32 eth1_clk_sel;
> + u32 eth1_ref_clk_sel;
> + u32 eth1_selmii;
> + u32 eth1_sel_rgmii;
> + u32 eth1_sel_rmii;
> + u32 eth2_clk_sel;
> + u32 eth2_ref_clk_sel;
> + u32 eth2_sel_rgmii;
> + u32 eth2_sel_rmii;
> +};

[...]

> @@ -487,8 +502,19 @@ static struct stm32_ops stm32mp1_dwmac_data = {
> .suspend = stm32mp1_suspend,
> .resume = stm32mp1_resume,
> .parse_data = stm32mp1_parse_data,
> - .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
> - .clk_rx_enable_in_suspend = true
> + .clk_rx_enable_in_suspend = true,
> + .syscfg_clr_off = 0x44,
> + .pmcsetr = {
> + .eth1_clk_sel = BIT(16),
> + .eth1_ref_clk_sel = BIT(17),
> + .eth1_selmii = BIT(20),
> + .eth1_sel_rgmii = BIT(21),
> + .eth1_sel_rmii = BIT(23),
> + .eth2_clk_sel = 0,
> + .eth2_ref_clk_sel = 0,
> + .eth2_sel_rgmii = 0,
> + .eth2_sel_rmii = 0
> + }
> };

Is this structure really necessary ?

It seems the MP15 single ethernet config bitfield is at offset 16.
MP13 has two bitfields, one at offset 16, the other at offset 24 .

All you need to do is figure out which of the two MACs you are
configuring, and then shift the bitfield mask by 16 or 24, since the
bits are at the same offset for both bitfields.

See the matching upstream U-Boot commit for how this shift can be done:
a440d19c6c91 ("net: dwc_eth_qos: Add DT parsing for STM32MP13xx platform")