[PATCH 2/3] net: stmmac: qcom-ethqos: configure USXGMII rates
Zhangfei Gao
zhangfei.gao at oss.qualcomm.com
Wed Sep 23 01:49:20 PDT 2026
Program the Qualcomm EMAC wrapper for the negotiated USXGMII media
rate. The serial SerDes lane remains at the USXGMII rate, while the
wrapper clock and IO macro settings follow the
10/100/1000/2500/5000/10000M MAC rate.
Without the low-speed settings, a 100M link is reported by the PHY but
the wrapper rejects it as an unsupported USXGMII speed.
USXGMII also defaults to phylink in-band mode because the QCOM host
requires the PHY-generated in-band link status.
Signed-off-by: Zhangfei Gao <zhangfei.gao at oss.qualcomm.com>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 65 ++++++++++++++++++-
1 file changed, 62 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 280f9289753da..54a6c98e42057 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -38,6 +38,7 @@
#define RGMII_CONFIG_GPIO_CFG_TX_INT GENMASK(19, 17)
#define RGMII_CONFIG_MAX_SPD_PRG_9 GENMASK(16, 8)
#define RGMII_CONFIG_MAX_SPD_PRG_2 GENMASK(7, 6)
+#define RGMII_CONFIG_MAX_SPD_PRG_2_V4 GENMASK(9, 6)
#define RGMII_CONFIG_INTF_SEL GENMASK(5, 4)
#define RGMII_CONFIG_BYPASS_TX_ID_EN BIT(3)
#define RGMII_CONFIG_LOOPBACK_EN BIT(2)
@@ -84,6 +85,12 @@
#define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL BIT(6)
#define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN BIT(5)
#define RGMII_CONFIG2_MODE_EN_VIA_GMII BIT(21)
+#define RGMII_CONFIG2_MAX_SPD_PRG_3 GENMASK(20, 17)
+
+/* RGMII_IO_MACRO_SCRATCH_2 fields */
+#define RGMII_SCRATCH2_MAX_SPD_PRG_4 GENMASK(5, 2)
+#define RGMII_SCRATCH2_MAX_SPD_PRG_5 GENMASK(9, 6)
+#define RGMII_SCRATCH2_MAX_SPD_PRG_6 GENMASK(13, 10)
/* EMAC_WRAPPER_SGMII_PHY_CNTRL0 fields */
#define SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL GENMASK(6, 5)
@@ -135,6 +142,7 @@ struct qcom_ethqos {
struct clk *eee_clk;
struct phy *serdes_phy;
phy_interface_t phy_mode;
+ int speed;
const struct ethqos_emac_por *rgmii_por;
unsigned int num_rgmii_por;
@@ -557,9 +565,56 @@ static void ethqos_configure_usxgmii(struct qcom_ethqos *ethqos)
rgmii_updatel(ethqos, USXGMII_CLK_BLK_CLK_EN, 0,
EMAC_WRAPPER_USXGMII_MUX_SEL);
- rgmii_updatel(ethqos, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
- USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
- EMAC_WRAPPER_USXGMII_MUX_SEL);
+ switch (ethqos->speed) {
+ case SPEED_10000:
+ rgmii_updatel(ethqos, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
+ USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
+ EMAC_WRAPPER_USXGMII_MUX_SEL);
+ break;
+ case SPEED_5000:
+ rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, 0,
+ EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+ rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2_V4,
+ BIT(6) | BIT(7), RGMII_IO_MACRO_CONFIG);
+ rgmii_updatel(ethqos, RGMII_CONFIG2_MAX_SPD_PRG_3,
+ BIT(17) | BIT(18), RGMII_IO_MACRO_CONFIG2);
+ break;
+ case SPEED_2500:
+ rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, 0,
+ EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+ rgmii_updatel(ethqos, RGMII_CONFIG_SGMII_CLK_DVDR,
+ BIT(10) | BIT(11), RGMII_IO_MACRO_CONFIG);
+ rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_4,
+ BIT(2) | BIT(3), RGMII_IO_MACRO_SCRATCH_2);
+ rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_5, 0,
+ RGMII_IO_MACRO_SCRATCH_2);
+ break;
+ case SPEED_1000:
+ case SPEED_100:
+ rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+ RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+ RGMII_IO_MACRO_CONFIG2);
+ if (ethqos->speed == SPEED_100) {
+ rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2_V4,
+ BIT(9), RGMII_IO_MACRO_CONFIG);
+ rgmii_updatel(ethqos, RGMII_CONFIG2_MAX_SPD_PRG_3,
+ BIT(20), RGMII_IO_MACRO_CONFIG2);
+ rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_6,
+ BIT(10), RGMII_IO_MACRO_SCRATCH_2);
+ }
+ break;
+ case SPEED_10:
+ rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+ RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+ RGMII_IO_MACRO_CONFIG2);
+ break;
+ default:
+ dev_err(ðqos->pdev->dev,
+ "unsupported USXGMII speed %d\n", ethqos->speed);
+ return;
+ }
+
+ return;
}
static void
@@ -568,6 +623,7 @@ ethqos_fix_mac_speed_usxgmii(void *bsp_priv, phy_interface_t interface,
{
struct qcom_ethqos *ethqos = bsp_priv;
+ ethqos->speed = speed;
ethqos_configure_usxgmii(ethqos);
}
@@ -836,6 +892,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
plat_dat->mac_finish = ethqos_mac_finish_serdes;
break;
case PHY_INTERFACE_MODE_USXGMII:
+ plat_dat->default_an_inband = true;
+ fallthrough;
+ case PHY_INTERFACE_MODE_10GBASER:
plat_dat->fix_mac_speed = ethqos_fix_mac_speed_usxgmii;
plat_dat->mac_finish = ethqos_mac_finish_serdes;
break;
--
2.43.0
More information about the linux-arm-kernel
mailing list