diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-03-05 18:43:08 -0800 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-05 18:43:09 -0800 |
| commit | 2a13309fa840fa7d651e6df0e174023003829461 (patch) | |
| tree | c53f6ab3be46358f9b438ec51399a0d574b0ba2b | |
| parent | 46cb1fcdb75b2dab2f3ed62caad04fe939549943 (diff) | |
| parent | 038a8e8eb90d4dd06ce6bda825970c71af09f4b0 (diff) | |
Merge branch 'net-stmmac-qcom-ethqos-further-serdes-reorganisation'
Russell King says:
====================
net: stmmac: qcom-ethqos: further serdes reorganisation
This is part 2 of the qcom-ethqos series, part 1 and patch 2 of part 2
has now been merged.
This part of the series focuses on the generic PHY driver, but these
changes have dependencies on the ethernet driver, hence why
it will need to go via net-next. Furthermore, subsequent changes
depend on these patches.
The underlying ideas here are:
- get rid of the driver using phy_set_speed() with SPEED_1000 and
SPEED_2500 which makes no sense for an ethernet SerDes due to the
PCS 8B10B data encoding, which inflates the data rate at the SerDes
compared to the MAC. This is replaced with phy_set_mode_ext().
- allow phy_power_on() / phy_set_mode*() to be called in any order.
Mohd has tested this series, although not in the resulting merge order.
====================
Link: https://patch.msgid.link/aacD3osfaZkLsGxm@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 31 | ||||
| -rw-r--r-- | drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 73 |
2 files changed, 41 insertions, 63 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index ad5b5d950fff..cb1c074c2053 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -105,7 +105,6 @@ struct qcom_ethqos { struct clk *link_clk; struct phy *serdes_phy; - int serdes_speed; phy_interface_t phy_mode; const struct ethqos_emac_por *rgmii_por; @@ -591,14 +590,6 @@ static void ethqos_configure_rgmii(struct qcom_ethqos *ethqos, ethqos_rgmii_macro_init(ethqos, 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); - ethqos->serdes_speed = speed; - } -} - static void ethqos_pcs_set_inband(struct stmmac_priv *priv, bool enable) { stmmac_pcs_ctrl_ane(priv, enable, 0); @@ -656,16 +647,8 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv) return ret; ret = phy_power_on(ethqos->serdes_phy); - if (ret) { - phy_exit(ethqos->serdes_phy); - return ret; - } - - ret = phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed); - if (ret) { - phy_power_off(ethqos->serdes_phy); + if (ret) phy_exit(ethqos->serdes_phy); - } return ret; } @@ -683,15 +666,16 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv, 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) - ethqos_set_serdes_speed(ethqos, SPEED_1000); - else if (interface == PHY_INTERFACE_MODE_2500BASEX) - ethqos_set_serdes_speed(ethqos, SPEED_2500); + if (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_2500BASEX) + ret = phy_set_mode_ext(ethqos->serdes_phy, PHY_MODE_ETHERNET, + interface); - return 0; + return ret; } static int ethqos_clks_config(void *priv, bool enabled) @@ -819,7 +803,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy), "Failed to get serdes phy\n"); - ethqos->serdes_speed = SPEED_1000; ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface, SPEED_1000); diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c index 4ea3dce7719f..f48faa2929a6 100644 --- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c +++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c @@ -29,7 +29,7 @@ struct qcom_dwmac_sgmii_phy_data { struct regmap *regmap; struct clk *refclk; - int speed; + phy_interface_t interface; }; static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap) @@ -223,15 +223,18 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy) struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); struct device *dev = phy->dev.parent; - switch (data->speed) { - case SPEED_10: - case SPEED_100: - case SPEED_1000: + switch (data->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + /* 1.25Gbps mode */ qcom_dwmac_sgmii_phy_init_1g(data->regmap); break; - case SPEED_2500: + case PHY_INTERFACE_MODE_2500BASEX: + /* 3.125Gbps mode */ qcom_dwmac_sgmii_phy_init_2p5g(data->regmap); break; + default: + return -EINVAL; } if (qcom_dwmac_sgmii_phy_poll_status(data->regmap, @@ -268,8 +271,17 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy) static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy) { struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(data->refclk); + if (ret < 0) + return ret; + + ret = qcom_dwmac_sgmii_phy_calibrate(phy); + if (ret < 0) + clk_disable_unprepare(data->refclk); - return clk_prepare_enable(data->refclk); + return ret; } static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy) @@ -287,17 +299,17 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy) return 0; } -static int qcom_dwmac_sgmii_phy_speed(enum phy_mode mode, int submode) +static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode, + int submode, + union phy_configure_opts *opts) { if (mode != PHY_MODE_ETHERNET) return -EINVAL; if (submode == PHY_INTERFACE_MODE_SGMII || - submode == PHY_INTERFACE_MODE_1000BASEX) - return SPEED_1000; - - if (submode == PHY_INTERFACE_MODE_2500BASEX) - return SPEED_2500; + submode == PHY_INTERFACE_MODE_1000BASEX || + submode == PHY_INTERFACE_MODE_2500BASEX) + return 0; return -EINVAL; } @@ -306,42 +318,25 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); - int speed; - - speed = qcom_dwmac_sgmii_phy_speed(mode, submode); - if (speed < 0) - return speed; + int ret; - if (speed != data->speed) - data->speed = speed; - - return qcom_dwmac_sgmii_phy_calibrate(phy); -} + ret = qcom_dwmac_sgmii_phy_validate(phy, mode, submode, NULL); + if (ret) + return ret; -static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed) -{ - struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy); + if (submode != data->interface) + data->interface = submode; - if (speed != data->speed) - data->speed = speed; + if (phy->power_count == 0) + return 0; return qcom_dwmac_sgmii_phy_calibrate(phy); } -static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode, - int submode, - union phy_configure_opts *opts) -{ - int ret = qcom_dwmac_sgmii_phy_speed(mode, submode); - - return ret < 0 ? ret : 0; -} - static const struct phy_ops qcom_dwmac_sgmii_phy_ops = { .power_on = qcom_dwmac_sgmii_phy_power_on, .power_off = qcom_dwmac_sgmii_phy_power_off, .set_mode = qcom_dwmac_sgmii_phy_set_mode, - .set_speed = qcom_dwmac_sgmii_phy_set_speed, .validate = qcom_dwmac_sgmii_phy_validate, .calibrate = qcom_dwmac_sgmii_phy_calibrate, .owner = THIS_MODULE, @@ -367,7 +362,7 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - data->speed = SPEED_10; + data->interface = PHY_INTERFACE_MODE_SGMII; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) |
