* [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
@ 2026-03-11 17:03 ` Bartosz Golaszewski
2026-03-11 17:13 ` Russell King (Oracle)
2026-03-11 17:03 ` [PATCH net-next v8 3/6] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure Bartosz Golaszewski
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, brgl, Bartosz Golaszewski, 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>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
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 07088d03dbab5bd1abf66e9460613b839c1d565e..e2af4fdd654340d618477ed87d3889dbb9aab456 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -135,7 +135,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 cb1c074c205307bca556192584fb0a4a10eecd47..fb4ffd0d5360d091bf0192740b8a4a8d2c66e09e 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>
@@ -728,7 +728,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;
@@ -778,7 +777,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ethqos->rgmii_base),
"Failed to map rgmii resource\n");
- data = of_device_get_match_data(dev);
+ data = device_get_match_data(dev);
ethqos->rgmii_por = data->rgmii_por;
ethqos->num_rgmii_por = data->num_rgmii_por;
ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
@@ -818,9 +817,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.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v8 3/6] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
2026-03-11 17:03 ` [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
@ 2026-03-11 17:03 ` Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 4/6] net: stmmac: qcom-ethqos: split power management fields into a separate structure Bartosz Golaszewski
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, brgl, Bartosz Golaszewski, Bartosz Golaszewski,
Konrad Dybcio
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>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 52 +++++++++++++++-------
1 file changed, 37 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index fb4ffd0d5360d091bf0192740b8a4a8d2c66e09e..92fc1fd0b4a1f85fdca7ee6f2c78b88415ce440d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -97,6 +97,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;
@@ -223,6 +227,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 },
@@ -239,6 +247,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 },
@@ -271,6 +283,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 },
@@ -306,6 +322,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;
@@ -728,7 +748,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;
@@ -778,13 +799,14 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
"Failed to map rgmii resource\n");
data = device_get_match_data(dev);
- ethqos->rgmii_por = data->rgmii_por;
- ethqos->num_rgmii_por = data->num_rgmii_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;
-
- ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
+ drv_data = data->drv_data;
+ ethqos->rgmii_por = drv_data->rgmii_por;
+ ethqos->num_rgmii_por = drv_data->num_rgmii_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");
@@ -815,14 +837,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;
@@ -837,10 +859,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.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v8 4/6] net: stmmac: qcom-ethqos: split power management fields into a separate structure
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
2026-03-11 17:03 ` [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 3/6] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure Bartosz Golaszewski
@ 2026-03-11 17:03 ` Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 5/6] net: stmmac: qcom-ethqos: split power management context into a separate struct Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 6/6] net: stmmac: qcom-ethqos: add support for sa8255p Bartosz Golaszewski
4 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, brgl, Bartosz Golaszewski, 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>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
.../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 92fc1fd0b4a1f85fdca7ee6f2c78b88415ce440d..2166084aac999a38367af4294129f925391179de 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -91,14 +91,18 @@ struct ethqos_emac_driver_data {
unsigned int num_rgmii_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 {
@@ -301,7 +305,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
.num_rgmii_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 = {
@@ -322,8 +325,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)
@@ -749,11 +757,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);
@@ -800,13 +810,16 @@ 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->rgmii_por = drv_data->rgmii_por;
ethqos->num_rgmii_por = drv_data->num_rgmii_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");
+ 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.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v8 5/6] net: stmmac: qcom-ethqos: split power management context into a separate struct
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
` (2 preceding siblings ...)
2026-03-11 17:03 ` [PATCH net-next v8 4/6] net: stmmac: qcom-ethqos: split power management fields into a separate structure Bartosz Golaszewski
@ 2026-03-11 17:03 ` Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 6/6] net: stmmac: qcom-ethqos: add support for sa8255p Bartosz Golaszewski
4 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, brgl, Bartosz Golaszewski, 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>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 40 ++++++++++++----------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 2166084aac999a38367af4294129f925391179de..7e3dc1df093a20eb766ebcb29738d9f4261145eb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -105,14 +105,18 @@ struct ethqos_emac_match_data {
const struct ethqos_emac_pm_data *pm_data;
};
+struct ethqos_emac_pm_ctx {
+ struct clk *link_clk;
+ struct phy *serdes_phy;
+};
+
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
void (*configure_func)(struct qcom_ethqos *ethqos,
phy_interface_t interface, int speed);
- struct clk *link_clk;
- struct phy *serdes_phy;
+ struct ethqos_emac_pm_ctx pm;
phy_interface_t phy_mode;
const struct ethqos_emac_por *rgmii_por;
@@ -194,7 +198,7 @@ static int ethqos_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
if (rate < 0)
return rate;
- return clk_set_rate(ethqos->link_clk, rate * 2);
+ return clk_set_rate(ethqos->pm.link_clk, rate * 2);
}
static void
@@ -670,13 +674,13 @@ 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)
- phy_exit(ethqos->serdes_phy);
+ phy_exit(ethqos->pm.serdes_phy);
return ret;
}
@@ -685,8 +689,8 @@ 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_mac_finish_serdes(struct net_device *ndev, void *priv,
@@ -700,7 +704,7 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
if (interface == PHY_INTERFACE_MODE_SGMII ||
interface == PHY_INTERFACE_MODE_2500BASEX)
- ret = phy_set_mode_ext(ethqos->serdes_phy, PHY_MODE_ETHERNET,
+ ret = phy_set_mode_ext(ethqos->pm.serdes_phy, PHY_MODE_ETHERNET,
interface);
return ret;
@@ -712,7 +716,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;
@@ -726,7 +730,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
qcom_ethqos_set_sgmii_loopback(ethqos, true);
ethqos_set_func_clk_en(ethqos);
} else {
- clk_disable_unprepare(ethqos->link_clk);
+ clk_disable_unprepare(ethqos->pm.link_clk);
}
return ret;
@@ -819,9 +823,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);
@@ -832,9 +836,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_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
@@ -859,7 +863,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.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v8 6/6] net: stmmac: qcom-ethqos: add support for sa8255p
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
` (3 preceding siblings ...)
2026-03-11 17:03 ` [PATCH net-next v8 5/6] net: stmmac: qcom-ethqos: split power management context into a separate struct Bartosz Golaszewski
@ 2026-03-11 17:03 ` Bartosz Golaszewski
4 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec
Cc: linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, brgl, Bartosz Golaszewski, Bartosz Golaszewski
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>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 301 ++++++++++++++++++---
1 file changed, 262 insertions(+), 39 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 7e3dc1df093a20eb766ebcb29738d9f4261145eb..c20f127f341c1b6793c408283353d60dde4dcb5e 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"
@@ -81,6 +83,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;
@@ -98,6 +107,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 {
@@ -110,13 +122,21 @@ struct ethqos_emac_pm_ctx {
struct phy *serdes_phy;
};
+struct ethqos_emac_pd_ctx {
+ struct dev_pm_domain_list *pd_list;
+ int serdes_level;
+};
+
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
void (*configure_func)(struct qcom_ethqos *ethqos,
phy_interface_t interface, 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;
const struct ethqos_emac_por *rgmii_por;
@@ -338,6 +358,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[] = {
+ "core", "mdio", "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;
@@ -406,6 +445,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;
@@ -655,6 +716,20 @@ static void ethqos_configure_sgmii(struct qcom_ethqos *ethqos,
ethqos_pcs_set_inband(priv, interface == PHY_INTERFACE_MODE_SGMII);
}
+static void ethqos_configure_sgmii_pd(struct qcom_ethqos *ethqos,
+ phy_interface_t interface, int speed)
+{
+ switch (speed) {
+ case SPEED_2500:
+ case SPEED_1000:
+ case SPEED_100:
+ case SPEED_10:
+ ethqos->pd.serdes_level = speed;
+ }
+
+ ethqos_configure_sgmii(ethqos, interface, speed);
+}
+
static void ethqos_configure(struct qcom_ethqos *ethqos,
phy_interface_t interface, int speed)
{
@@ -710,6 +785,45 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
return ret;
}
+static int ethqos_mac_finish_serdes_pd(struct net_device *ndev, void *priv,
+ unsigned int mode,
+ phy_interface_t interface)
+{
+ struct qcom_ethqos *ethqos = priv;
+ struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+ int ret = 0;
+
+ qcom_ethqos_set_sgmii_loopback(ethqos, false);
+
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
+ interface == PHY_INTERFACE_MODE_2500BASEX)
+ ret = dev_pm_opp_set_level(dev, ethqos->pd.serdes_level);
+
+ return ret;
+}
+
+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->pd.serdes_level);
+}
+
+static void qcom_ethqos_pd_serdes_powerdown(struct net_device *ndev, void *priv)
+{
+ struct qcom_ethqos *ethqos = priv;
+ struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+
+ dev_pm_opp_set_level(dev, 0);
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);
+}
+
static int ethqos_clks_config(void *priv, bool enabled)
{
struct qcom_ethqos *ethqos = priv;
@@ -741,6 +855,68 @@ static void ethqos_clks_disable(void *data)
ethqos_clks_config(data, false);
}
+static void ethqos_disable_serdes(void *data)
+{
+ struct qcom_ethqos *ethqos = data;
+
+ qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);
+}
+
+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 device *dev, 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 device *dev, 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;
@@ -781,31 +957,11 @@ 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;
ethqos->phy_mode = plat_dat->phy_interface;
- switch (ethqos->phy_mode) {
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- ethqos->configure_func = ethqos_configure_rgmii;
- break;
- case PHY_INTERFACE_MODE_2500BASEX:
- case PHY_INTERFACE_MODE_SGMII:
- ethqos->configure_func = ethqos_configure_sgmii;
- plat_dat->mac_finish = ethqos_mac_finish_serdes;
- break;
- default:
- dev_err(dev, "Unsupported phy mode %s\n",
- phy_modes(ethqos->phy_mode));
- return -EINVAL;
- }
-
ethqos->pdev = pdev;
ethqos->rgmii_base = devm_platform_ioremap_resource_byname(pdev, "rgmii");
if (IS_ERR(ethqos->rgmii_base))
@@ -823,35 +979,101 @@ 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->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");
+ if (pm_data && pm_data->use_domains) {
+ switch (ethqos->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ ethqos->configure_func = ethqos_configure_rgmii;
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_SGMII:
+ ethqos->configure_func = ethqos_configure_sgmii_pd;
+ plat_dat->mac_finish = ethqos_mac_finish_serdes_pd;
+ break;
+ default:
+ dev_err(dev, "Unsupported phy mode %s\n",
+ phy_modes(ethqos->phy_mode));
+ return -EINVAL;
+ }
- ret = ethqos_clks_config(ethqos, true);
- if (ret)
- return ret;
+ 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_domain_on(ethqos, ETHQOS_PD_SERDES);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to enable the serdes power domain\n");
+
+ ret = devm_add_action_or_reset(dev, ethqos_disable_serdes, ethqos);
+ if (ret)
+ return ret;
+ } else {
+ switch (ethqos->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ ethqos->configure_func = ethqos_configure_rgmii;
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_SGMII:
+ ethqos->configure_func = ethqos_configure_sgmii;
+ plat_dat->mac_finish = ethqos_mac_finish_serdes;
+ break;
+ default:
+ dev_err(dev, "Unsupported phy mode %s\n",
+ phy_modes(ethqos->phy_mode));
+ return -EINVAL;
+ }
- ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
- if (ret)
- return ret;
+ 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->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_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
+ SPEED_1000);
- ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
- SPEED_1000);
+ plat_dat->clks_config = ethqos_clks_config;
+ plat_dat->set_clk_tx_rate = ethqos_set_clk_tx_rate;
+ 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;
+ }
+ }
qcom_ethqos_set_sgmii_loopback(ethqos, true);
ethqos_set_func_clk_en(ethqos);
plat_dat->bsp_priv = ethqos;
- plat_dat->set_clk_tx_rate = ethqos_set_clk_tx_rate;
plat_dat->fix_mac_speed = ethqos_fix_mac_speed;
plat_dat->dump_debug_regs = rgmii_dump;
- 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 = &drv_data->dwmac4_addrs;
@@ -877,6 +1099,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.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties
2026-03-11 17:03 ` [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
@ 2026-03-11 17:13 ` Russell King (Oracle)
2026-03-11 17:18 ` Bartosz Golaszewski
0 siblings, 1 reply; 8+ messages in thread
From: Russell King (Oracle) @ 2026-03-11 17:13 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Bartosz Golaszewski, Radu Rendec,
linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, Bartosz Golaszewski
On Wed, Mar 11, 2026 at 06:03:37PM +0100, Bartosz Golaszewski wrote:
> 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>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Please postpone this for the time being - I'm trying to get stmmac's
pain-in-the-arse PCS support sorted, and I've patch series out there
and pending that make a large number of changes to this driver. This
is likely to conflict with my work.
I'm limited by the rate at which patches can be applied to net-next
and the rate at which Mohd can provide me feedback. On that, I notice
you haven't Cc'd Mohd who is now in MAINTAINERS for qcom-ethqos.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties
2026-03-11 17:13 ` Russell King (Oracle)
@ 2026-03-11 17:18 ` Bartosz Golaszewski
2026-03-11 17:46 ` Russell King (Oracle)
0 siblings, 1 reply; 8+ messages in thread
From: Bartosz Golaszewski @ 2026-03-11 17:18 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai,
Jernej Skrabec, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Shawn Guo, Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Radu Rendec, linux-arm-msm, devicetree,
linux-kernel, netdev, linux-stm32, linux-arm-kernel, Drew Fustini,
linux-sunxi, linux-amlogic, linux-mips, imx, linux-renesas-soc,
linux-rockchip, sophgo, linux-riscv, Bartosz Golaszewski
On Wed, Mar 11, 2026 at 6:14 PM Russell King (Oracle)
<linux@armlinux.org.uk> wrote:
>
> On Wed, Mar 11, 2026 at 06:03:37PM +0100, Bartosz Golaszewski wrote:
> > 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>
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
>
> Please postpone this for the time being - I'm trying to get stmmac's
> pain-in-the-arse PCS support sorted, and I've patch series out there
> and pending that make a large number of changes to this driver. This
> is likely to conflict with my work.
>
> I'm limited by the rate at which patches can be applied to net-next
> and the rate at which Mohd can provide me feedback. On that, I notice
> you haven't Cc'd Mohd who is now in MAINTAINERS for qcom-ethqos.
>
Do these two changesets interact with each other a lot? Do you have a
WIP branch I could take a look at? This has been post-poned several
times already, there always seem to be some new changes coming in. :/
Bart
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties
2026-03-11 17:18 ` Bartosz Golaszewski
@ 2026-03-11 17:46 ` Russell King (Oracle)
0 siblings, 0 replies; 8+ messages in thread
From: Russell King (Oracle) @ 2026-03-11 17:46 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai,
Jernej Skrabec, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Shawn Guo, Fabio Estevam, Jan Petrous, s32, Romain Gantois,
Geert Uytterhoeven, Magnus Damm, Maxime Ripard,
Christophe Roullier, Radu Rendec, linux-arm-msm, devicetree,
linux-kernel, netdev, linux-stm32, linux-arm-kernel, Drew Fustini,
linux-sunxi, linux-amlogic, linux-mips, imx, linux-renesas-soc,
linux-rockchip, sophgo, linux-riscv, Bartosz Golaszewski
On Wed, Mar 11, 2026 at 06:18:00PM +0100, Bartosz Golaszewski wrote:
> On Wed, Mar 11, 2026 at 6:14 PM Russell King (Oracle)
> <linux@armlinux.org.uk> wrote:
> >
> > On Wed, Mar 11, 2026 at 06:03:37PM +0100, Bartosz Golaszewski wrote:
> > > 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>
> > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> >
> > Please postpone this for the time being - I'm trying to get stmmac's
> > pain-in-the-arse PCS support sorted, and I've patch series out there
> > and pending that make a large number of changes to this driver. This
> > is likely to conflict with my work.
> >
> > I'm limited by the rate at which patches can be applied to net-next
> > and the rate at which Mohd can provide me feedback. On that, I notice
> > you haven't Cc'd Mohd who is now in MAINTAINERS for qcom-ethqos.
> >
>
> Do these two changesets interact with each other a lot? Do you have a
> WIP branch I could take a look at? This has been post-poned several
> times already, there always seem to be some new changes coming in. :/
I don't have a public branch because this work is subject to rework
depending on the feedback I receive. Mohd has another version of the
series that I'm waiting for feedback for. As soon as I hear that it's
fine, I will be sending it.
The problem I refer to has been a pain point for phylink since stmmac
was converted in 2019, which pre-dates qcom-ethqos, the merging of
which has made solving sthis much more painful as qcom-ethqos
completely bypasses phylink by forcing the PCS inband state behind
phylink's back.
Honestly, over recent months, I've been washing that I'd NACK'd the
merging of dwmac-qcom-ethqos at the time over this, but I didn't
have any solution for stmmac at that point (it wasn't my
responsibility, the broken phylink conversion of stmmac was merged
without my knowledge, without even a Cc to me.)
One of the biggest changes that will definitely conflict with your
changes is the move of qcom-ethqos' SerDes support into stmmac core
code - because the stmmac PCS code needs to know whether the SerDes
can support 2.5Gbps speed. I got the changes for the generic PHY part
of that merged last week.
Another change that will conflict is your patch 3, where masses of
changes in qcom_ethqos_probe() which will conflict with my
"net: stmmac: qcom-ethqos: enable 2500BASE-X" patch.
I've posted patches for that a couple of weeks ago, but Mohd reported
problems, so I've had to rework the series - and now those patches
are part of a follow-on series after sorting the bulk of the stmmac
PCS mess.
I'm currently waiting for Mohd's feedback on the reworked series.
https://lore.kernel.org/r/aZ7ggfQanc8jeCb9@shell.armlinux.org.uk
https://lore.kernel.org/r/aafxqCvJ_XY4YbWw@shell.armlinux.org.uk
Latest version waiting for Mohd's feedback:
https://lore.kernel.org/r/aa6sofjFxyi2nkpr@shell.armlinux.org.uk
Below are the two patches which add and convert qcom-ethqos serdes
support. Note that these two depend on other patches.
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Subject: [PATCH net-next] net: stmmac: add stmmac core serdes support
Rather than having platform glue implement SerDes PHY support, add it
to the core driver, specifically to the stmmac integrated PCS driver
as the SerDes is connected to the integrated PCS.
Platforms using external PCS can also populate plat->serdes, and the
core driver will call phy_init() and phy_exit() when the administrative
state of the interface changes, but the other phy methods will not be
called.
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
--
rfc->v1: avoid calling phy_get_mode() with NULL serdes PHY
v2: add cleanup when dwmac_serdes_set_mode() fails, so that failure at
any point in the internal PCS enable method leaves the overall state
unchanged.
v3: in a pending change to generic PHY documentation indicated by Vinod
recently, calling phy_set_mode(_ext)() before phy_power_on() will be
preferred, so re-organise to use that ordering.
v4: move phy_set_mode() into .mac_finish(), add dwmac_has_serdes() to
make serdes calls conditional on dwmac's active phy interface, with
the exception of phy_init()/phy_exit() calls.
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 37 +++++++-
.../net/ethernet/stmicro/stmmac/stmmac_pcs.c | 44 +++++++--
.../ethernet/stmicro/stmmac/stmmac_serdes.c | 92 +++++++++++++++++++
.../ethernet/stmicro/stmmac/stmmac_serdes.h | 15 +++
include/linux/stmmac.h | 2 +
6 files changed, 181 insertions(+), 11 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.h
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index c9263987ef8d..a3c2cd5d0c91 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -7,7 +7,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
stmmac_xdp.o stmmac_est.o stmmac_fpe.o stmmac_vlan.o \
- stmmac_pcs.o $(stmmac-y)
+ stmmac_pcs.o stmmac_serdes.o $(stmmac-y)
stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 37f6ee7566be..428b2e5bb4c4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -49,6 +49,7 @@
#include "stmmac_fpe.h"
#include "stmmac.h"
#include "stmmac_pcs.h"
+#include "stmmac_serdes.h"
#include "stmmac_xdp.h"
#include <linux/reset.h>
#include <linux/of_mdio.h>
@@ -969,7 +970,7 @@ static int stmmac_mac_finish(struct phylink_config *config, unsigned int mode,
priv->plat->mac_finish(ndev, priv->plat->bsp_priv, mode,
interface);
- return 0;
+ return dwmac_serdes_set_mode(priv, interface);
}
static void stmmac_mac_link_down(struct phylink_config *config,
@@ -3592,12 +3593,14 @@ static void stmmac_safety_feat_configuration(struct stmmac_priv *priv)
static void stmmac_clk_rx_i_require(struct stmmac_priv *priv)
{
+ dwmac_serdes_power_on(priv);
phylink_rx_clk_stop_block(priv->phylink);
}
static void stmmac_clk_rx_i_release(struct stmmac_priv *priv)
{
phylink_rx_clk_stop_unblock(priv->phylink);
+ dwmac_serdes_power_off(priv);
}
/**
@@ -4153,6 +4156,10 @@ static int stmmac_open(struct net_device *dev)
if (ret)
goto err_runtime_pm;
+ ret = dwmac_serdes_init(priv);
+ if (ret < 0)
+ goto err_disconnect_phy;
+
if (!(priv->plat->flags & STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP)) {
ret = stmmac_legacy_serdes_power_up(priv);
if (ret < 0)
@@ -4172,6 +4179,7 @@ static int stmmac_open(struct net_device *dev)
err_serdes:
stmmac_legacy_serdes_power_down(priv);
+ dwmac_serdes_exit(priv);
err_disconnect_phy:
phylink_disconnect_phy(priv->phylink);
err_runtime_pm:
@@ -4232,6 +4240,7 @@ static int stmmac_release(struct net_device *dev)
__stmmac_release(dev);
stmmac_legacy_serdes_power_down(priv);
+ dwmac_serdes_exit(priv);
phylink_disconnect_phy(priv->phylink);
pm_runtime_put(priv->device);
@@ -7781,6 +7790,13 @@ static int __stmmac_dvr_probe(struct device *device,
return -EINVAL;
}
+ if (plat_dat->serdes &&
+ (plat_dat->serdes_powerup || plat_dat->serdes_powerdown)) {
+ dev_err(device,
+ "generic PHY and SerDes platform callbacks are incompatible\n");
+ return -EINVAL;
+ }
+
ndev = devm_alloc_etherdev_mqs(device, sizeof(struct stmmac_priv),
MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES);
if (!ndev)
@@ -8194,6 +8210,15 @@ int stmmac_suspend(struct device *dev)
rtnl_lock();
phylink_suspend(priv->phylink, !!priv->wolopts);
+
+ /* If the MAC has WoL enabled, the SerDes needs to remain active.
+ * Otherwise, phylink will have stopped the MAC and the PCS will
+ * have been disabled, meaning the SerDes is already powered off.
+ * Call its exit function so we can call init during resume.
+ */
+ if (!priv->wolopts)
+ dwmac_serdes_exit(priv);
+
rtnl_unlock();
if (stmmac_fpe_supported(priv))
@@ -8290,6 +8315,15 @@ int stmmac_resume(struct device *dev)
rtnl_lock();
+ /* If the MAC has WoL enabled, the SerDes was left active */
+ if (!priv->wolopts) {
+ ret = dwmac_serdes_init(priv);
+ if (ret) {
+ rtnl_unlock();
+ return ret;
+ }
+ }
+
/* Prepare the PHY to resume, ensuring that its clocks which are
* necessary for the MAC DMA reset to complete are running
*/
@@ -8307,6 +8341,7 @@ int stmmac_resume(struct device *dev)
netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
stmmac_legacy_serdes_power_down(priv);
mutex_unlock(&priv->lock);
+ dwmac_serdes_exit(priv);
rtnl_unlock();
return ret;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
index 0c0eb9e30b95..298d3c00b2fa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "stmmac.h"
#include "stmmac_pcs.h"
+#include "stmmac_serdes.h"
/*
* GMAC_AN_STATUS is equivalent to MII_BMSR
@@ -60,8 +61,14 @@ static unsigned int dwmac_integrated_pcs_inband_caps(struct phylink_pcs *pcs,
static int dwmac_integrated_pcs_enable(struct phylink_pcs *pcs)
{
struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs);
+ struct stmmac_priv *priv = spcs->priv;
+ int ret;
- stmmac_mac_irq_modify(spcs->priv, 0, spcs->int_mask);
+ ret = dwmac_serdes_power_on(priv);
+ if (ret)
+ return ret;
+
+ stmmac_mac_irq_modify(priv, 0, spcs->int_mask);
return 0;
}
@@ -69,8 +76,11 @@ static int dwmac_integrated_pcs_enable(struct phylink_pcs *pcs)
static void dwmac_integrated_pcs_disable(struct phylink_pcs *pcs)
{
struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs);
+ struct stmmac_priv *priv = spcs->priv;
+
+ stmmac_mac_irq_modify(priv, spcs->int_mask, 0);
- stmmac_mac_irq_modify(spcs->priv, spcs->int_mask, 0);
+ dwmac_serdes_power_off(priv);
}
static void dwmac_integrated_pcs_get_state(struct phylink_pcs *pcs,
@@ -220,6 +230,22 @@ int stmmac_integrated_pcs_get_phy_intf_sel(struct phylink_pcs *pcs,
return -EINVAL;
}
+static void stmmac_integrated_pcs_check_support(struct stmmac_priv *priv,
+ struct stmmac_pcs *spcs,
+ phy_interface_t interface,
+ unsigned int flag)
+{
+ bool supported;
+
+ if (priv->plat->serdes)
+ supported = dwmac_serdes_validate(priv, interface) == 0;
+ else
+ supported = !flag || priv->plat->flags & flag;
+
+ if (supported)
+ __set_bit(interface, spcs->pcs.supported_interfaces);
+}
+
int stmmac_integrated_pcs_init(struct stmmac_priv *priv,
const struct stmmac_pcs_info *pcs_info)
{
@@ -243,13 +269,13 @@ int stmmac_integrated_pcs_init(struct stmmac_priv *priv,
if (readl(spcs->base + GMAC_AN_STATUS) & BMSR_ESTATEN)
spcs->support_tbi_rtbi = true;
- __set_bit(PHY_INTERFACE_MODE_SGMII, spcs->pcs.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_1000BASEX, spcs->pcs.supported_interfaces);
-
- /* Only allow 2500BASE-X if the SerDes has support. */
- if (priv->plat->flags & STMMAC_FLAG_SERDES_SUPPORTS_2500M)
- __set_bit(PHY_INTERFACE_MODE_2500BASEX,
- spcs->pcs.supported_interfaces);
+ stmmac_integrated_pcs_check_support(priv, spcs,
+ PHY_INTERFACE_MODE_SGMII, 0);
+ stmmac_integrated_pcs_check_support(priv, spcs,
+ PHY_INTERFACE_MODE_1000BASEX, 0);
+ stmmac_integrated_pcs_check_support(priv, spcs,
+ PHY_INTERFACE_MODE_2500BASEX,
+ STMMAC_FLAG_SERDES_SUPPORTS_2500M);
priv->integrated_pcs = spcs;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.c
new file mode 100644
index 000000000000..a767c0553604
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.c
@@ -0,0 +1,92 @@
+#include <linux/phy/phy.h>
+
+#include "stmmac.h"
+#include "stmmac_serdes.h"
+
+static bool dwmac_has_serdes(struct stmmac_priv *priv)
+{
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ return false;
+
+ return priv->dma_cap.actphyif == PHY_INTF_SEL_SGMII ||
+ priv->dma_cap.actphyif == PHY_INTF_SEL_TBI ||
+ priv->dma_cap.actphyif == PHY_INTF_SEL_RTBI;
+}
+
+int dwmac_serdes_validate(struct stmmac_priv *priv, phy_interface_t interface)
+{
+ struct phy *serdes = priv->plat->serdes;
+
+ return phy_validate(serdes, PHY_MODE_ETHERNET, interface, NULL);
+}
+
+int dwmac_serdes_init(struct stmmac_priv *priv)
+{
+ struct phy *serdes = priv->plat->serdes;
+ int ret;
+
+ ret = phy_init(serdes);
+ if (ret)
+ dev_err(priv->device, "failed to initialize SerDes: %pe\n",
+ ERR_PTR(ret));
+
+ return ret;
+}
+
+int dwmac_serdes_power_on(struct stmmac_priv *priv)
+{
+ struct phy *serdes = priv->plat->serdes;
+ int ret;
+
+ if (!dwmac_has_serdes(priv))
+ return 0;
+
+ ret = phy_power_on(serdes);
+ if (ret)
+ dev_err(priv->device, "failed to power on SerDes: %pe\n",
+ ERR_PTR(ret));
+
+ return ret;
+}
+
+int dwmac_serdes_set_mode(struct stmmac_priv *priv, phy_interface_t interface)
+{
+ struct phy *serdes = priv->plat->serdes;
+ int ret;
+
+ if (!dwmac_has_serdes(priv))
+ return 0;
+
+ ret = phy_set_mode_ext(serdes, PHY_MODE_ETHERNET, interface);
+ if (ret)
+ dev_err(priv->device,
+ "failed to set SerDes mode %s: %pe\n",
+ phy_modes(interface), ERR_PTR(ret));
+
+ return ret;
+}
+
+void dwmac_serdes_power_off(struct stmmac_priv *priv)
+{
+ struct phy *serdes = priv->plat->serdes;
+ int ret;
+
+ if (!dwmac_has_serdes(priv))
+ return;
+
+ ret = phy_power_off(serdes);
+ if (ret)
+ dev_err(priv->device, "failed to power off SerDes: %pe\n",
+ ERR_PTR(ret));
+}
+
+void dwmac_serdes_exit(struct stmmac_priv *priv)
+{
+ struct phy *serdes = priv->plat->serdes;
+ int ret;
+
+ ret = phy_exit(serdes);
+ if (ret)
+ dev_err(priv->device, "failed to shutdown SerDes: %pe\n",
+ ERR_PTR(ret));
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.h
new file mode 100644
index 000000000000..2ca37a7d0fde
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_serdes.h
@@ -0,0 +1,15 @@
+#ifndef STMMAC_SERDES_H
+#define STMMAC_SERDES_H
+
+#include <linux/phy.h>
+
+struct stmmac_priv;
+
+int dwmac_serdes_validate(struct stmmac_priv *priv, phy_interface_t interface);
+int dwmac_serdes_init(struct stmmac_priv *priv);
+int dwmac_serdes_power_on(struct stmmac_priv *priv);
+int dwmac_serdes_set_mode(struct stmmac_priv *priv, phy_interface_t interface);
+void dwmac_serdes_power_off(struct stmmac_priv *priv);
+void dwmac_serdes_exit(struct stmmac_priv *priv);
+
+#endif
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a8e9b5d3289f..bedba4e23088 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -216,6 +216,7 @@ enum dwmac_core_type {
#define STMMAC_FLAG_SERDES_SUPPORTS_2500M BIT(15)
struct mac_device_info;
+struct phy;
struct plat_stmmacenet_data {
enum dwmac_core_type core_type;
@@ -245,6 +246,7 @@ struct plat_stmmacenet_data {
* that phylink uses.
*/
phy_interface_t phy_interface;
+ struct phy *serdes;
struct stmmac_mdio_bus_data *mdio_bus_data;
struct device_node *phy_node;
struct device_node *mdio_node;
--
2.47.3
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Subject: [PATCH net-next] net: stmmac: qcom-ethqos: convert to dwmac core
SerDes support
Convert qcom-ethqos to use the dwmac core's generic SerDes support,
which will handle SerDes initialisation, powering, and mode setting.
Note that generic support requires the SerDes to support phy_validate()
in order to probe which PHY interface modes are supported, and
phy_set_mode_ext() to configure the appropriate PHY interface mode
(and thus the speed.)
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 45 ++-----------------
1 file changed, 4 insertions(+), 41 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 9a2194fccb9b..a40a4bca197d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -104,7 +104,6 @@ struct qcom_ethqos {
phy_interface_t interface, int speed);
struct clk *link_clk;
- struct phy *serdes_phy;
phy_interface_t phy_mode;
const struct ethqos_emac_por *rgmii_por;
@@ -627,45 +626,15 @@ static void ethqos_fix_mac_speed(void *priv, phy_interface_t interface,
ethqos_configure(ethqos, interface, speed);
}
-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);
- if (ret)
- return ret;
-
- ret = phy_power_on(ethqos->serdes_phy);
- if (ret)
- phy_exit(ethqos->serdes_phy);
-
- return ret;
-}
-
-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);
-}
-
static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
unsigned int mode,
phy_interface_t interface)
{
struct qcom_ethqos *ethqos = priv;
- int ret = 0;
qcom_ethqos_set_sgmii_loopback(ethqos, false);
- if (interface == PHY_INTERFACE_MODE_SGMII ||
- interface == PHY_INTERFACE_MODE_2500BASEX)
- ret = phy_set_mode_ext(ethqos->serdes_phy, PHY_MODE_ETHERNET,
- interface);
-
- return ret;
+ return 0;
}
static int ethqos_clks_config(void *priv, bool enabled)
@@ -789,9 +758,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),
+ plat_dat->serdes = devm_phy_optional_get(dev, "serdes");
+ if (IS_ERR(plat_dat->serdes))
+ return dev_err_probe(dev, PTR_ERR(plat_dat->serdes),
"Failed to get serdes phy\n");
ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
@@ -816,12 +785,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (data->dma_addr_width)
plat_dat->host_dma_width = data->dma_addr_width;
- if (ethqos->serdes_phy) {
- plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
- plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
- plat_dat->flags |= STMMAC_FLAG_SERDES_SUPPORTS_2500M;
- }
-
/* 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;
--
2.47.3
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-11 17:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260311-qcom-sa8255p-emac-v8-0-58227bcf1018@oss.qualcomm.com>
2026-03-11 17:03 ` [PATCH net-next v8 2/6] net: stmmac: qcom-ethqos: use generic device properties Bartosz Golaszewski
2026-03-11 17:13 ` Russell King (Oracle)
2026-03-11 17:18 ` Bartosz Golaszewski
2026-03-11 17:46 ` Russell King (Oracle)
2026-03-11 17:03 ` [PATCH net-next v8 3/6] net: stmmac: qcom-ethqos: wrap emac driver data in additional structure Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 4/6] net: stmmac: qcom-ethqos: split power management fields into a separate structure Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 5/6] net: stmmac: qcom-ethqos: split power management context into a separate struct Bartosz Golaszewski
2026-03-11 17:03 ` [PATCH net-next v8 6/6] net: stmmac: qcom-ethqos: add support for sa8255p Bartosz Golaszewski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox