* [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-28 8:16 ` Krzysztof Kozlowski
2025-10-27 15:44 ` [PATCH v3 2/8] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
` (6 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Describe the firmware-managed variant of the QCom DesignWare MAC. As the
properties here differ a lot from the HLOS-managed variant, lets put it
in a separate file.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../devicetree/bindings/net/qcom,ethqos-scmi.yaml | 101 +++++++++++++++++++++
.../devicetree/bindings/net/snps,dwmac.yaml | 5 +-
MAINTAINERS | 1 +
3 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b821299d7b30cdb802d9ee5d9fa17542b8334bd2
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Ethernet ETHQOS device (firmware managed)
+
+maintainers:
+ - Bjorn Andersson <andersson@kernel.org>
+ - Konrad Dybcio <konradybcio@kernel.org>
+ - Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+description:
+ dwmmac based Qualcomm ethernet devices which support Gigabit
+ ethernet (version v2.3.0 and onwards) with clocks, interconnects, etc.
+ managed by firmware
+
+allOf:
+ - $ref: snps,dwmac.yaml#
+
+properties:
+ compatible:
+ const: qcom,sa8255p-ethqos
+
+ reg:
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: stmmaceth
+ - const: rgmii
+
+ interrupts:
+ items:
+ - description: Combined signal for various interrupt events
+ - description: The interrupt that occurs when HW safety error triggered
+
+ interrupt-names:
+ items:
+ - const: macirq
+ - const: sfty
+
+ power-domains:
+ minItems: 3
+
+ power-domain-names:
+ items:
+ - const: core
+ - const: mdio
+ - const: serdes
+
+ iommus:
+ maxItems: 1
+
+ dma-coherent: true
+
+ phys: true
+
+ phy-names:
+ const: serdes
+
+required:
+ - compatible
+ - reg-names
+ - power-domains
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ ethernet: ethernet@7a80000 {
+ compatible = "qcom,sa8255p-ethqos";
+ reg = <0x23040000 0x10000>,
+ <0x23056000 0x100>;
+ reg-names = "stmmaceth", "rgmii";
+
+ iommus = <&apps_smmu 0x120 0x7>;
+
+ interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "sfty";
+
+ dma-coherent;
+
+ snps,tso;
+ snps,pbl = <32>;
+ rx-fifo-depth = <16384>;
+ tx-fifo-depth = <16384>;
+
+ phy-handle = <ðernet_phy>;
+ phy-mode = "2500base-x";
+
+ snps,mtl-rx-config = <&mtl_rx_setup1>;
+ snps,mtl-tx-config = <&mtl_tx_setup1>;
+
+ power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>, <&scmi8_dvfs 0>;
+ power-domain-names = "core", "mdio","serdes";
+ };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index dd3c72e8363e70d101ed2702e2ea3235ee38e2a0..312d1bbc2ad1051520355039f5587381cbd1e01c 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -71,6 +71,7 @@ properties:
- loongson,ls7a-dwmac
- nxp,s32g2-dwmac
- qcom,qcs404-ethqos
+ - qcom,sa8255p-ethqos
- qcom,sa8775p-ethqos
- qcom,sc8280xp-ethqos
- qcom,sm8150-ethqos
@@ -180,7 +181,8 @@ properties:
- const: ahb
power-domains:
- maxItems: 1
+ minItems: 1
+ maxItems: 3
mac-mode:
$ref: ethernet-controller.yaml#/properties/phy-connection-type
@@ -643,6 +645,7 @@ allOf:
- ingenic,x1830-mac
- ingenic,x2000-mac
- qcom,qcs404-ethqos
+ - qcom,sa8255p-ethqos
- qcom,sa8775p-ethqos
- qcom,sc8280xp-ethqos
- qcom,sm8150-ethqos
diff --git a/MAINTAINERS b/MAINTAINERS
index 252b06d4240cc2b67405b8a967055bd53dec7c8e..14c80fbad8b97cc5562555d2422c81724d42111d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21218,6 +21218,7 @@ M: Vinod Koul <vkoul@kernel.org>
L: netdev@vger.kernel.org
L: linux-arm-msm@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
F: Documentation/devicetree/bindings/net/qcom,ethqos.yaml
F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
2025-10-27 15:44 ` [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems Bartosz Golaszewski
@ 2025-10-28 8:16 ` Krzysztof Kozlowski
2025-11-03 17:18 ` Bartosz Golaszewski
0 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-10-28 8:16 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu,
linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
On Mon, Oct 27, 2025 at 04:44:49PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Describe the firmware-managed variant of the QCom DesignWare MAC. As the
> properties here differ a lot from the HLOS-managed variant, lets put it
> in a separate file.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> .../devicetree/bindings/net/qcom,ethqos-scmi.yaml | 101 +++++++++++++++++++++
> .../devicetree/bindings/net/snps,dwmac.yaml | 5 +-
> MAINTAINERS | 1 +
> 3 files changed, 106 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..b821299d7b30cdb802d9ee5d9fa17542b8334bd2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
> @@ -0,0 +1,101 @@
> +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Ethernet ETHQOS device (firmware managed)
> +
> +maintainers:
> + - Bjorn Andersson <andersson@kernel.org>
> + - Konrad Dybcio <konradybcio@kernel.org>
> + - Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> +
> +description:
> + dwmmac based Qualcomm ethernet devices which support Gigabit
> + ethernet (version v2.3.0 and onwards) with clocks, interconnects, etc.
> + managed by firmware
> +
> +allOf:
> + - $ref: snps,dwmac.yaml#
> +
> +properties:
> + compatible:
> + const: qcom,sa8255p-ethqos
> +
> + reg:
> + maxItems: 2
> +
> + reg-names:
> + items:
> + - const: stmmaceth
> + - const: rgmii
> +
> + interrupts:
> + items:
> + - description: Combined signal for various interrupt events
> + - description: The interrupt that occurs when HW safety error triggered
> +
> + interrupt-names:
> + items:
> + - const: macirq
> + - const: sfty
> +
> + power-domains:
> + minItems: 3
maxItems instead
But the other problem is that it is conflicting with snps,dwmac.yaml
which says max 1 is allowed. You need to fix that, along with
restricting other users of that shared schema to maxItems: 1.
> +
> + power-domain-names:
> + items:
> + - const: core
> + - const: mdio
> + - const: serdes
> +
> + iommus:
> + maxItems: 1
> +
> + dma-coherent: true
> +
> + phys: true
Missing maxItems.
> +
> + phy-names:
> + const: serdes
> +
> +required:
> + - compatible
> + - reg-names
> + - power-domains
power-domain-names
Shouldn't phys be required? How device can work sometimes without its
phy?
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> + ethernet: ethernet@7a80000 {
> + compatible = "qcom,sa8255p-ethqos";
> + reg = <0x23040000 0x10000>,
> + <0x23056000 0x100>;
> + reg-names = "stmmaceth", "rgmii";
> +
> + iommus = <&apps_smmu 0x120 0x7>;
> +
> + interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "macirq", "sfty";
> +
> + dma-coherent;
> +
> + snps,tso;
> + snps,pbl = <32>;
> + rx-fifo-depth = <16384>;
> + tx-fifo-depth = <16384>;
> +
> + phy-handle = <ðernet_phy>;
> + phy-mode = "2500base-x";
Incomplete example - missing phys.
> +
> + snps,mtl-rx-config = <&mtl_rx_setup1>;
> + snps,mtl-tx-config = <&mtl_tx_setup1>;
> +
> + power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>, <&scmi8_dvfs 0>;
> + power-domain-names = "core", "mdio","serdes";
> + };
> diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> index dd3c72e8363e70d101ed2702e2ea3235ee38e2a0..312d1bbc2ad1051520355039f5587381cbd1e01c 100644
> --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> @@ -71,6 +71,7 @@ properties:
> - loongson,ls7a-dwmac
> - nxp,s32g2-dwmac
> - qcom,qcs404-ethqos
> + - qcom,sa8255p-ethqos
> - qcom,sa8775p-ethqos
> - qcom,sc8280xp-ethqos
> - qcom,sm8150-ethqos
> @@ -180,7 +181,8 @@ properties:
> - const: ahb
>
> power-domains:
> - maxItems: 1
> + minItems: 1
> + maxItems: 3
Ah, you did it. But you need to update all other bindings as well.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
2025-10-28 8:16 ` Krzysztof Kozlowski
@ 2025-11-03 17:18 ` Bartosz Golaszewski
2025-11-04 7:20 ` Krzysztof Kozlowski
0 siblings, 1 reply; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-11-03 17:18 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu,
linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
On Tue, Oct 28, 2025 at 9:16 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> > +
> > + power-domains:
> > + minItems: 3
>
> maxItems instead
>
> But the other problem is that it is conflicting with snps,dwmac.yaml
> which says max 1 is allowed. You need to fix that, along with
> restricting other users of that shared schema to maxItems: 1.
>
Just to be clear: snps,dwmac.yaml should stay as:
power-domains:
minItems: 1
maxItems: 3
But all bindings referencing it, except the new one, should now gain:
power-domains:
maxItems: 1
>
> Shouldn't phys be required? How device can work sometimes without its
> phy?
>
Actually I will drop phys, the serdes PHY is managed by SCMI.
Bart
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
2025-11-03 17:18 ` Bartosz Golaszewski
@ 2025-11-04 7:20 ` Krzysztof Kozlowski
0 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-04 7:20 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu,
linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
On 03/11/2025 18:18, Bartosz Golaszewski wrote:
> On Tue, Oct 28, 2025 at 9:16 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>>> +
>>> + power-domains:
>>> + minItems: 3
>>
>> maxItems instead
>>
>> But the other problem is that it is conflicting with snps,dwmac.yaml
>> which says max 1 is allowed. You need to fix that, along with
>> restricting other users of that shared schema to maxItems: 1.
>>
>
> Just to be clear: snps,dwmac.yaml should stay as:
>
> power-domains:
> minItems: 1
> maxItems: 3
>
> But all bindings referencing it, except the new one, should now gain:
>
> power-domains:
> maxItems: 1
Yes.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/8] net: stmmac: qcom-ethqos: use generic device properties
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 3/8] net: stmmac: qcom-ethqos: improve typing in devres callback Bartosz Golaszewski
` (5 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
In order to drop the dependency on CONFIG_OF, convert all device property
getters from OF-specific to generic device properties and stop pulling
in any linux/of.h symbols.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 716daa51df7e50e401e2c2ca305055dc52897793..d27733b8a05a393ce356543c799da18a6d9b9083 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -134,7 +134,7 @@ config DWMAC_MESON
config DWMAC_QCOM_ETHQOS
tristate "Qualcomm ETHQOS support"
default ARCH_QCOM
- depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ depends on ARCH_QCOM || COMPILE_TEST
help
Support for the Qualcomm ETHQOS core.
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index d1e48b524d7a964f229e2bf28e7a316325726193..b24134923fdff0de8b608c140dfb8ffaccd19303 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018-19, Linaro Limited
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
@@ -762,7 +762,6 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
static int qcom_ethqos_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
const struct ethqos_emac_driver_data *data;
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
@@ -813,7 +812,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->mac_base = stmmac_res.addr;
- data = of_device_get_match_data(dev);
+ data = device_get_match_data(dev);
ethqos->por = data->por;
ethqos->num_por = data->num_por;
ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
@@ -850,9 +849,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (ethqos->has_emac_ge_3)
plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
plat_dat->pmt = 1;
- if (of_property_read_bool(np, "snps,tso"))
+ if (device_property_present(dev, "snps,tso"))
plat_dat->flags |= STMMAC_FLAG_TSO_EN;
- if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
+ if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
if (data->dma_addr_width)
plat_dat->host_dma_width = data->dma_addr_width;
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 3/8] net: stmmac: qcom-ethqos: improve typing in devres callback
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 1/8] dt-bindings: net: qcom: document the ethqos device for SCMI-based systems Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 2/8] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure Bartosz Golaszewski
` (4 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
It's bad practice to just directly pass void pointers to functions which
expect concrete types. Make it more clear what type ethqos_clks_config()
expects.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index b24134923fdff0de8b608c140dfb8ffaccd19303..ed799da4e4079b4da4b555dd119cce8c6591aa39 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -740,7 +740,9 @@ static int ethqos_clks_config(void *priv, bool enabled)
static void ethqos_clks_disable(void *data)
{
- ethqos_clks_config(data, false);
+ struct qcom_ethqos *ethqos = data;
+
+ ethqos_clks_config(ethqos, false);
}
static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
` (2 preceding siblings ...)
2025-10-27 15:44 ` [PATCH v3 3/8] net: stmmac: qcom-ethqos: improve typing in devres callback Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 5/8] net: stmmac: qcom-ethqos: split power management fields into a separate structure Bartosz Golaszewski
` (3 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
As the first step in enabling power domain support in the driver, we'll
split the device match data and runtime data structures into their
general and power-management-specific parts. To allow that: first wrap
the emac driver data in another layer which will later be expanded.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 51 ++++++++++++++++------
1 file changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index ed799da4e4079b4da4b555dd119cce8c6591aa39..2739bc00e7525a5913bd3a5d28d9c9a8871fb7cf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -101,6 +101,10 @@ struct ethqos_emac_driver_data {
bool needs_sgmii_loopback;
};
+struct ethqos_emac_match_data {
+ const struct ethqos_emac_driver_data *drv_data;
+};
+
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
@@ -218,6 +222,10 @@ static const struct ethqos_emac_driver_data emac_v2_3_0_data = {
.has_emac_ge_3 = false,
};
+static const struct ethqos_emac_match_data emac_qcs404_data = {
+ .drv_data = &emac_v2_3_0_data,
+};
+
static const struct ethqos_emac_por emac_v2_1_0_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x40C01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642C },
@@ -234,6 +242,10 @@ static const struct ethqos_emac_driver_data emac_v2_1_0_data = {
.has_emac_ge_3 = false,
};
+static const struct ethqos_emac_match_data emac_sm8150_data = {
+ .drv_data = &emac_v2_1_0_data,
+};
+
static const struct ethqos_emac_por emac_v3_0_0_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x40c01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642c },
@@ -266,6 +278,10 @@ static const struct ethqos_emac_driver_data emac_v3_0_0_data = {
},
};
+static const struct ethqos_emac_match_data emac_sc8280xp_data = {
+ .drv_data = &emac_v3_0_0_data,
+};
+
static const struct ethqos_emac_por emac_v4_0_0_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x40c01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642c },
@@ -301,6 +317,10 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
},
};
+static const struct ethqos_emac_match_data emac_sa8775p_data = {
+ .drv_data = &emac_v4_0_0_data,
+};
+
static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
{
struct device *dev = ðqos->pdev->dev;
@@ -764,7 +784,8 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
static int qcom_ethqos_probe(struct platform_device *pdev)
{
- const struct ethqos_emac_driver_data *data;
+ const struct ethqos_emac_driver_data *drv_data;
+ const struct ethqos_emac_match_data *data;
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
struct device *dev = &pdev->dev;
@@ -815,13 +836,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->mac_base = stmmac_res.addr;
data = device_get_match_data(dev);
- ethqos->por = data->por;
- ethqos->num_por = data->num_por;
- ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
- ethqos->has_emac_ge_3 = data->has_emac_ge_3;
- ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;
+ drv_data = data->drv_data;
- ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
+ ethqos->por = drv_data->por;
+ ethqos->num_por = drv_data->num_por;
+ ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
+ ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
+ ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
+
+ ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
if (IS_ERR(ethqos->link_clk))
return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
"Failed to get link_clk\n");
@@ -849,14 +872,14 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
plat_dat->core_type = DWMAC_CORE_GMAC4;
if (ethqos->has_emac_ge_3)
- plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
+ plat_dat->dwmac4_addrs = &drv_data->dwmac4_addrs;
plat_dat->pmt = 1;
if (device_property_present(dev, "snps,tso"))
plat_dat->flags |= STMMAC_FLAG_TSO_EN;
if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
- if (data->dma_addr_width)
- plat_dat->host_dma_width = data->dma_addr_width;
+ if (drv_data->dma_addr_width)
+ plat_dat->host_dma_width = drv_data->dma_addr_width;
if (ethqos->serdes_phy) {
plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
@@ -871,10 +894,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_ethqos_match[] = {
- { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
- { .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data},
- { .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data},
- { .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data},
+ { .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+ { .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
+ { .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
+ { .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},
{ }
};
MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 5/8] net: stmmac: qcom-ethqos: split power management fields into a separate structure
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
` (3 preceding siblings ...)
2025-10-27 15:44 ` [PATCH v3 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 6/8] net: stmmac: qcom-ethqos: split power management context into a separate struct Bartosz Golaszewski
` (2 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Now that we have a separate wrapper for device match data, let's extend
this structure with a pointer to the structure containing fields related
to power-management only. This is done because a device may have the
same device settings but different power management mode (e.g.: firmware
vs manual).
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 2739bc00e7525a5913bd3a5d28d9c9a8871fb7cf..7ed07142f67c931cb2c2c0e8806f5a7fbd68945d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -95,14 +95,18 @@ struct ethqos_emac_driver_data {
unsigned int num_por;
bool rgmii_config_loopback_en;
bool has_emac_ge_3;
- const char *link_clk_name;
u32 dma_addr_width;
struct dwmac4_addrs dwmac4_addrs;
bool needs_sgmii_loopback;
};
+struct ethqos_emac_pm_data {
+ const char *link_clk_name;
+};
+
struct ethqos_emac_match_data {
const struct ethqos_emac_driver_data *drv_data;
+ const struct ethqos_emac_pm_data *pm_data;
};
struct qcom_ethqos {
@@ -296,7 +300,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
.num_por = ARRAY_SIZE(emac_v4_0_0_por),
.rgmii_config_loopback_en = false,
.has_emac_ge_3 = true,
- .link_clk_name = "phyaux",
.needs_sgmii_loopback = true,
.dma_addr_width = 36,
.dwmac4_addrs = {
@@ -317,8 +320,13 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
},
};
+static const struct ethqos_emac_pm_data emac_sa8775p_pm_data = {
+ .link_clk_name = "phyaux",
+};
+
static const struct ethqos_emac_match_data emac_sa8775p_data = {
.drv_data = &emac_v4_0_0_data,
+ .pm_data = &emac_sa8775p_pm_data,
};
static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
@@ -785,11 +793,13 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
static int qcom_ethqos_probe(struct platform_device *pdev)
{
const struct ethqos_emac_driver_data *drv_data;
+ const struct ethqos_emac_pm_data *pm_data;
const struct ethqos_emac_match_data *data;
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
struct device *dev = &pdev->dev;
struct qcom_ethqos *ethqos;
+ const char *clk_name;
int ret, i;
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
@@ -837,6 +847,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
data = device_get_match_data(dev);
drv_data = data->drv_data;
+ pm_data = data->pm_data;
+ clk_name = pm_data && pm_data->link_clk_name ?
+ pm_data->link_clk_name : "rgmii";
ethqos->por = drv_data->por;
ethqos->num_por = drv_data->num_por;
@@ -844,7 +857,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
- ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
+ ethqos->link_clk = devm_clk_get(dev, clk_name);
if (IS_ERR(ethqos->link_clk))
return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
"Failed to get link_clk\n");
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 6/8] net: stmmac: qcom-ethqos: split power management context into a separate struct
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
` (4 preceding siblings ...)
2025-10-27 15:44 ` [PATCH v3 5/8] net: stmmac: qcom-ethqos: split power management fields into a separate structure Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 7/8] net: stmmac: qcom-ethqos: define a callback for setting the serdes speed Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 8/8] net: stmmac: qcom-ethqos: add support for sa8255p Bartosz Golaszewski
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
With match data split into general and power-management sections, let's
now do the same with runtime device data.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 46 ++++++++++++----------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 7ed07142f67c931cb2c2c0e8806f5a7fbd68945d..c25b4b4581f9cea6107a39f0bc6165be6955cc1b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -109,17 +109,21 @@ struct ethqos_emac_match_data {
const struct ethqos_emac_pm_data *pm_data;
};
+struct ethqos_emac_pm_ctx {
+ struct clk *link_clk;
+ unsigned int link_clk_rate;
+ struct phy *serdes_phy;
+};
+
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
void __iomem *mac_base;
int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
- unsigned int link_clk_rate;
- struct clk *link_clk;
- struct phy *serdes_phy;
- int serdes_speed;
+ struct ethqos_emac_pm_ctx pm;
phy_interface_t phy_mode;
+ int serdes_speed;
const struct ethqos_emac_por *por;
unsigned int num_por;
@@ -185,9 +189,9 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, int speed)
rate = rgmii_clock(speed);
if (rate > 0)
- ethqos->link_clk_rate = rate * 2;
+ ethqos->pm.link_clk_rate = rate * 2;
- clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
+ clk_set_rate(ethqos->pm.link_clk, ethqos->pm.link_clk_rate);
}
static void
@@ -643,7 +647,7 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
{
if (ethqos->serdes_speed != speed) {
- phy_set_speed(ethqos->serdes_phy, speed);
+ phy_set_speed(ethqos->pm.serdes_phy, speed);
ethqos->serdes_speed = speed;
}
}
@@ -722,23 +726,23 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
struct qcom_ethqos *ethqos = priv;
int ret;
- ret = phy_init(ethqos->serdes_phy);
+ ret = phy_init(ethqos->pm.serdes_phy);
if (ret)
return ret;
- ret = phy_power_on(ethqos->serdes_phy);
+ ret = phy_power_on(ethqos->pm.serdes_phy);
if (ret)
return ret;
- return phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed);
+ return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
}
static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
{
struct qcom_ethqos *ethqos = priv;
- phy_power_off(ethqos->serdes_phy);
- phy_exit(ethqos->serdes_phy);
+ phy_power_off(ethqos->pm.serdes_phy);
+ phy_exit(ethqos->pm.serdes_phy);
}
static int ethqos_clks_config(void *priv, bool enabled)
@@ -747,7 +751,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
int ret = 0;
if (enabled) {
- ret = clk_prepare_enable(ethqos->link_clk);
+ ret = clk_prepare_enable(ethqos->pm.link_clk);
if (ret) {
dev_err(ðqos->pdev->dev, "link_clk enable failed\n");
return ret;
@@ -760,7 +764,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
*/
ethqos_set_func_clk_en(ethqos);
} else {
- clk_disable_unprepare(ethqos->link_clk);
+ clk_disable_unprepare(ethqos->pm.link_clk);
}
return ret;
@@ -857,9 +861,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
- ethqos->link_clk = devm_clk_get(dev, clk_name);
- if (IS_ERR(ethqos->link_clk))
- return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
+ ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+ if (IS_ERR(ethqos->pm.link_clk))
+ return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
"Failed to get link_clk\n");
ret = ethqos_clks_config(ethqos, true);
@@ -870,9 +874,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (ret)
return ret;
- ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");
- if (IS_ERR(ethqos->serdes_phy))
- return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),
+ ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+ if (IS_ERR(ethqos->pm.serdes_phy))
+ return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
"Failed to get serdes phy\n");
ethqos->serdes_speed = SPEED_1000;
@@ -894,7 +898,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (drv_data->dma_addr_width)
plat_dat->host_dma_width = drv_data->dma_addr_width;
- if (ethqos->serdes_phy) {
+ if (ethqos->pm.serdes_phy) {
plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 7/8] net: stmmac: qcom-ethqos: define a callback for setting the serdes speed
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
` (5 preceding siblings ...)
2025-10-27 15:44 ` [PATCH v3 6/8] net: stmmac: qcom-ethqos: split power management context into a separate struct Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
2025-10-27 15:44 ` [PATCH v3 8/8] net: stmmac: qcom-ethqos: add support for sa8255p Bartosz Golaszewski
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Ahead of adding support for firmware driven power management, let's
allow different ways of setting the PHY speed. To that end create a
callback with a single implementation for now, that will be extended
later.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index c25b4b4581f9cea6107a39f0bc6165be6955cc1b..840d44f052786a79b85d25d2181467aa96102ec8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -124,6 +124,7 @@ struct qcom_ethqos {
struct ethqos_emac_pm_ctx pm;
phy_interface_t phy_mode;
int serdes_speed;
+ int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
const struct ethqos_emac_por *por;
unsigned int num_por;
@@ -644,11 +645,16 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
return 0;
}
+static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
+{
+ return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
+}
+
static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
{
if (ethqos->serdes_speed != speed) {
- phy_set_speed(ethqos->pm.serdes_phy, speed);
ethqos->serdes_speed = speed;
+ ethqos->set_serdes_speed(ethqos);
}
}
@@ -879,6 +885,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
"Failed to get serdes phy\n");
+ ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
ethqos->serdes_speed = SPEED_1000;
ethqos_update_link_clk(ethqos, SPEED_1000);
ethqos_set_func_clk_en(ethqos);
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v3 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
2025-10-27 15:44 [PATCH v3 0/8] net: stmmac: qcom-ethqos: add support for SCMI power domains Bartosz Golaszewski
` (6 preceding siblings ...)
2025-10-27 15:44 ` [PATCH v3 7/8] net: stmmac: qcom-ethqos: define a callback for setting the serdes speed Bartosz Golaszewski
@ 2025-10-27 15:44 ` Bartosz Golaszewski
7 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2025-10-27 15:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Richard Cochran, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Jose Abreu
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Extend the driver to support a new model - sa8255p. Unlike the
previously supported variants, this one's power management is done in
the firmware using SCMI. This is modeled in linux using power domains so
add support for them.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 230 ++++++++++++++++++---
1 file changed, 201 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 840d44f052786a79b85d25d2181467aa96102ec8..0917168b1dfa05fdc28d6113261f368fcf06d893 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -7,6 +7,8 @@
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_domain.h>
#include "stmmac.h"
#include "stmmac_platform.h"
@@ -85,6 +87,13 @@
#define SGMII_10M_RX_CLK_DVDR 0x31
+enum ethqos_pd_selector {
+ ETHQOS_PD_CORE = 0,
+ ETHQOS_PD_MDIO,
+ ETHQOS_PD_SERDES,
+ ETHQOS_NUM_PDS,
+};
+
struct ethqos_emac_por {
unsigned int offset;
unsigned int value;
@@ -102,6 +111,9 @@ struct ethqos_emac_driver_data {
struct ethqos_emac_pm_data {
const char *link_clk_name;
+ bool use_domains;
+ struct dev_pm_domain_attach_data pd;
+ unsigned int clk_ptp_rate;
};
struct ethqos_emac_match_data {
@@ -115,13 +127,20 @@ struct ethqos_emac_pm_ctx {
struct phy *serdes_phy;
};
+struct ethqos_emac_pd_ctx {
+ struct dev_pm_domain_list *pd_list;
+};
+
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
void __iomem *mac_base;
int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
- struct ethqos_emac_pm_ctx pm;
+ union {
+ struct ethqos_emac_pm_ctx pm;
+ struct ethqos_emac_pd_ctx pd;
+ };
phy_interface_t phy_mode;
int serdes_speed;
int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
@@ -334,6 +353,25 @@ static const struct ethqos_emac_match_data emac_sa8775p_data = {
.pm_data = &emac_sa8775p_pm_data,
};
+static const char * const emac_sa8255p_pd_names[] = {
+ "power_core", "power_mdio", "perf_serdes"
+};
+
+static const struct ethqos_emac_pm_data emac_sa8255p_pm_data = {
+ .pd = {
+ .pd_flags = PD_FLAG_NO_DEV_LINK,
+ .pd_names = emac_sa8255p_pd_names,
+ .num_pd_names = ETHQOS_NUM_PDS,
+ },
+ .use_domains = true,
+ .clk_ptp_rate = 230400000,
+};
+
+static const struct ethqos_emac_match_data emac_sa8255p_data = {
+ .drv_data = &emac_v4_0_0_data,
+ .pm_data = &emac_sa8255p_pm_data,
+};
+
static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
{
struct device *dev = ðqos->pdev->dev;
@@ -415,6 +453,28 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
return 0;
}
+static int qcom_ethqos_domain_on(struct qcom_ethqos *ethqos,
+ enum ethqos_pd_selector sel)
+{
+ struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+ int ret;
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ dev_err(ðqos->pdev->dev,
+ "Failed to enable the power domain for %s\n",
+ dev_name(dev));
+ return ret;
+}
+
+static void qcom_ethqos_domain_off(struct qcom_ethqos *ethqos,
+ enum ethqos_pd_selector sel)
+{
+ struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+
+ pm_runtime_put_sync(dev);
+}
+
static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
{
struct device *dev = ðqos->pdev->dev;
@@ -650,6 +710,13 @@ static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
}
+static int ethqos_set_serdes_speed_pd(struct qcom_ethqos *ethqos)
+{
+ struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+
+ return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
{
if (ethqos->serdes_speed != speed) {
@@ -751,6 +818,27 @@ static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
phy_exit(ethqos->pm.serdes_phy);
}
+static int qcom_ethqos_pd_serdes_powerup(struct net_device *ndev, void *priv)
+{
+ struct qcom_ethqos *ethqos = priv;
+ struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+ int ret;
+
+ ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+ if (ret < 0)
+ return ret;
+
+ return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
+static void qcom_ethqos_pd_serdes_powerdown(struct net_device *ndev, void *priv)
+{
+ struct qcom_ethqos *ethqos = priv;
+
+ /* TODO set level */
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);
+}
+
static int ethqos_clks_config(void *priv, bool enabled)
{
struct qcom_ethqos *ethqos = priv;
@@ -783,6 +871,61 @@ static void ethqos_clks_disable(void *data)
ethqos_clks_config(ethqos, false);
}
+static int ethqos_pd_clks_config(void *priv, bool enabled)
+{
+ struct qcom_ethqos *ethqos = priv;
+ int ret = 0;
+
+ if (enabled) {
+ ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+ if (ret < 0) {
+ dev_err(ðqos->pdev->dev,
+ "Failed to enable the MDIO power domain\n");
+ return ret;
+ }
+
+ ethqos_set_func_clk_en(ethqos);
+ } else {
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+ }
+
+ return ret;
+}
+
+static int qcom_ethqos_pd_init(struct platform_device *pdev, void *priv)
+{
+ struct qcom_ethqos *ethqos = priv;
+ int ret;
+
+ /*
+ * Enable functional clock to prevent DMA reset after timeout due
+ * to no PHY clock being enabled after the hardware block has been
+ * power cycled. The actual configuration will be adjusted once
+ * ethqos_fix_mac_speed() is called.
+ */
+ ethqos_set_func_clk_en(ethqos);
+
+ ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_CORE);
+ if (ret)
+ return ret;
+
+ ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+ if (ret) {
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void qcom_ethqos_pd_exit(struct platform_device *pdev, void *data)
+{
+ struct qcom_ethqos *ethqos = data;
+
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+}
+
static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
{
struct plat_stmmacenet_data *plat_dat = priv->plat;
@@ -823,8 +966,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
"dt configuration failed\n");
}
- plat_dat->clks_config = ethqos_clks_config;
-
ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);
if (!ethqos)
return -ENOMEM;
@@ -866,28 +1007,63 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
-
- ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
- if (IS_ERR(ethqos->pm.link_clk))
- return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
- "Failed to get link_clk\n");
-
- ret = ethqos_clks_config(ethqos, true);
- if (ret)
- return ret;
-
- ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
- if (ret)
- return ret;
-
- ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
- if (IS_ERR(ethqos->pm.serdes_phy))
- return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
- "Failed to get serdes phy\n");
-
- ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
ethqos->serdes_speed = SPEED_1000;
- ethqos_update_link_clk(ethqos, SPEED_1000);
+
+ if (pm_data && pm_data->use_domains) {
+ ethqos->set_serdes_speed = ethqos_set_serdes_speed_pd;
+
+ ret = devm_pm_domain_attach_list(dev, &pm_data->pd,
+ ðqos->pd.pd_list);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to attach power domains\n");
+
+ plat_dat->clks_config = ethqos_pd_clks_config;
+ plat_dat->serdes_powerup = qcom_ethqos_pd_serdes_powerup;
+ plat_dat->serdes_powerdown = qcom_ethqos_pd_serdes_powerdown;
+ plat_dat->exit = qcom_ethqos_pd_exit;
+ plat_dat->init = qcom_ethqos_pd_init;
+ plat_dat->clk_ptp_rate = pm_data->clk_ptp_rate;
+
+ ret = qcom_ethqos_pd_init(pdev, ethqos);
+ if (ret)
+ return ret;
+
+ ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to enable the serdes power domain\n");
+ } else {
+ ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
+
+ ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+ if (IS_ERR(ethqos->pm.link_clk))
+ return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
+ "Failed to get link_clk\n");
+
+ ret = ethqos_clks_config(ethqos, true);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
+ if (ret)
+ return ret;
+
+ ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+ if (IS_ERR(ethqos->pm.serdes_phy))
+ return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
+ "Failed to get serdes phy\n");
+
+ ethqos_update_link_clk(ethqos, SPEED_1000);
+
+ plat_dat->clks_config = ethqos_clks_config;
+ plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
+
+ if (ethqos->pm.serdes_phy) {
+ plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
+ plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
+ }
+ }
+
ethqos_set_func_clk_en(ethqos);
plat_dat->bsp_priv = ethqos;
@@ -905,11 +1081,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (drv_data->dma_addr_width)
plat_dat->host_dma_width = drv_data->dma_addr_width;
- if (ethqos->pm.serdes_phy) {
- plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
- plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
- }
-
/* Enable TSO on queue0 and enable TBS on rest of the queues */
for (i = 1; i < plat_dat->tx_queues_to_use; i++)
plat_dat->tx_queues_cfg[i].tbs_en = 1;
@@ -919,6 +1090,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
static const struct of_device_id qcom_ethqos_match[] = {
{ .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+ { .compatible = "qcom,sa8255p-ethqos", .data = &emac_sa8255p_data},
{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
{ .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},
--
2.48.1
^ permalink raw reply related [flat|nested] 12+ messages in thread