* [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support
@ 2026-09-23 0:04 Mohd Ayaan Anwar
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Mohd Ayaan Anwar @ 2026-09-23 0:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo, Zhangfei Gao, Mohd Ayaan Anwar
This series adds support for the Ethernet SerDes found on the Qualcomm
Nord SoC.
Nord uses a QMP v7 SerDes block, which is an updated version of the
SGMII SerDes PHY IP already handled by phy-qcom-sgmii-eth. The driver
currently supports the 1.25 Gbaud and 3.125 Gbaud configurations used by
SGMII, 1000BASE-X and 2500BASE-X. Nord additionally requires the SerDes
to operate at 10.3125 Gbaud for its 10 Gigabit Ethernet interfaces.
The series can be broadly divided into three parts:
1. Add the qcom,nord-dwmac-sgmii-phy compatible to the binding.
2. Prepare the driver for PHY modes which require different SerDes
programming and readiness checks. Existing SA8775P behaviour is
unchanged.
3. Add the QMP v7 register definitions, 10.3125 Gbaud programming
sequence and readiness checks required for USXGMII and 10GBASE-R.
The changes have been tested on the Nord Ride SX platform, which has a
MV-Q6223 switch, running in fixed link USXGMII 10G mode.
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
---
Mohd Ayaan Anwar (3):
dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible
phy: qcom: sgmii-eth: prepare for additional PHY modes
phy: qcom: sgmii-eth: add Nord USXGMII support
.../bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml | 1 +
drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h | 5 +
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h | 2 +
.../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h | 9 +
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 226 ++++++++++++++++++---
5 files changed, 219 insertions(+), 24 deletions(-)
---
base-commit: a8c591ed6b672915e0be57843f943a2a723aff40
change-id: 20260923-nord_ethernet_serdes-c486f715f383
Best regards,
--
Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible
2026-09-23 0:04 [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
@ 2026-09-23 0:04 ` Mohd Ayaan Anwar
2026-09-25 13:35 ` Lorenzo Bianconi
2026-09-25 13:59 ` Bartosz Golaszewski
2026-09-23 0:04 ` [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes Mohd Ayaan Anwar
` (2 subsequent siblings)
3 siblings, 2 replies; 9+ messages in thread
From: Mohd Ayaan Anwar @ 2026-09-23 0:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo, Zhangfei Gao, Mohd Ayaan Anwar
Add the qcom,nord-dwmac-sgmii-phy compatible to the Qualcomm DWMAC
SGMII PHY binding.
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
index e573abcb937df914ced25ec87add7955bbba7b87..f2df9983d9536654e838bae4e1e23b832cdaea3c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
@@ -21,6 +21,7 @@ properties:
- qcom,qcs8300-dwmac-sgmii-phy
- const: qcom,sa8775p-dwmac-sgmii-phy
- const: qcom,sa8775p-dwmac-sgmii-phy
+ - const: qcom,nord-dwmac-sgmii-phy
reg:
items:
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes
2026-09-23 0:04 [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
@ 2026-09-23 0:04 ` Mohd Ayaan Anwar
2026-09-25 13:49 ` Lorenzo Bianconi
2026-09-23 0:04 ` [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
2026-09-23 8:58 ` [PATCH 0/3] " Zhangfei Gao
3 siblings, 1 reply; 9+ messages in thread
From: Mohd Ayaan Anwar @ 2026-09-23 0:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo, Zhangfei Gao, Mohd Ayaan Anwar
Prepare the SGMII Ethernet PHY driver for PHY modes that require a
different SerDes programming sequence. Move the SGMII readiness checks
into a helper so additional modes can provide their own status checks,
and select the initial interface mode through per-compatible match data
rather than hardcoding SGMII during probe.
This does not change existing SA8775P behavior.
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 70 ++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 24 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 7137200c3f310a4d2642bb9bdbe3adb7589b2241..029dafacee7853648ef24afd0d9c4b83a549badf 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -41,6 +41,10 @@ struct qcom_dwmac_sgmii_phy_data {
phy_interface_t interface;
};
+struct qcom_dwmac_sgmii_phy_match_data {
+ phy_interface_t default_interface;
+};
+
static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
{
regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
@@ -227,47 +231,31 @@ qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
val & bit, 1500, 750000);
}
-static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
+static int qcom_dwmac_sgmii_phy_poll_sgmii_ready(struct device *dev,
+ struct regmap *regmap)
{
- struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
- struct device *dev = phy->dev.parent;
-
- 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 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,
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
QSERDES_QMP_PLL + QSERDES_V5_COM_C_READY_STATUS,
QSERDES_COM_C_READY)) {
dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
return -ETIMEDOUT;
}
- if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
QSERDES_PCS_READY)) {
dev_err(dev, "PCS_READY timed-out");
return -ETIMEDOUT;
}
- if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
QSERDES_PCS_SGMIIPHY_READY)) {
dev_err(dev, "SGMIIPHY_READY timed-out");
return -ETIMEDOUT;
}
- if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
QSERDES_QMP_PLL + QSERDES_V5_COM_CMN_STATUS,
QSERDES_COM_C_PLL_LOCKED)) {
dev_err(dev, "PLL Lock Status timed-out");
@@ -277,6 +265,28 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
return 0;
}
+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->interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ /* 1.25Gbps mode */
+ qcom_dwmac_sgmii_phy_init_1g(data->regmap);
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ /* 3.125Gbps mode */
+ qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
+}
+
static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
@@ -374,6 +384,7 @@ static const struct regmap_config qcom_dwmac_sgmii_phy_regmap_cfg = {
static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
{
+ const struct qcom_dwmac_sgmii_phy_match_data *match_data;
struct qcom_dwmac_sgmii_phy_data *data;
struct device *dev = &pdev->dev;
struct phy_provider *provider;
@@ -385,7 +396,11 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->interface = PHY_INTERFACE_MODE_SGMII;
+ match_data = device_get_match_data(dev);
+ if (!match_data)
+ return -EINVAL;
+
+ data->interface = match_data->default_interface;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
@@ -419,8 +434,15 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
return 0;
}
+static const struct qcom_dwmac_sgmii_phy_match_data sa8775p_match_data = {
+ .default_interface = PHY_INTERFACE_MODE_SGMII,
+};
+
static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
- { .compatible = "qcom,sa8775p-dwmac-sgmii-phy" },
+ {
+ .compatible = "qcom,sa8775p-dwmac-sgmii-phy",
+ .data = &sa8775p_match_data,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, qcom_dwmac_sgmii_phy_of_match);
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support
2026-09-23 0:04 [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
2026-09-23 0:04 ` [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes Mohd Ayaan Anwar
@ 2026-09-23 0:04 ` Mohd Ayaan Anwar
2026-09-25 13:59 ` Lorenzo Bianconi
2026-09-23 8:58 ` [PATCH 0/3] " Zhangfei Gao
3 siblings, 1 reply; 9+ messages in thread
From: Mohd Ayaan Anwar @ 2026-09-23 0:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo, Zhangfei Gao, Mohd Ayaan Anwar
Nord uses a QMP v7 SerDes block which is an updated version of the
SGMII SerDes PHY IP.
The SGMII SerDes PHY supports multiple operating modes by programming
different SerDes line rates. The driver currently handles SGMII and
2500BASE-X configurations only.
Add support for configuring the SerDes to operate at 10.3125 Gbaud,
enabling both USXGMII and 10GBASE-R PHY interface modes. Finally, add a
driver compatible for Nord.
Select USXGMII as the initial interface mode for Nord. phy_power_on()
can run before the consumer calls set_mode(), so this ensures that the
first calibration selects the 10.3125 Gbaud programming sequence.
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h | 5 +
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h | 2 +
.../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h | 9 ++
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 166 ++++++++++++++++++++-
4 files changed, 177 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
index 4d8c962f5e0f52974f3edd5d1acdd8da535de200..67ab2fe085de3d90520cfc43cc0ac7abaab1f21d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
@@ -10,11 +10,16 @@
#define QPHY_PCS_POWER_DOWN_CONTROL 0x004
#define QPHY_PCS_SW_RESET 0x008
#define QPHY_PCS_LINE_RESET_TIME 0x00c
+#define QPHY_PCS_RETIME_BUFFER_EN 0x018
#define QPHY_PCS_TX_LARGE_AMP_DRV_LVL 0x020
+#define QPHY_PCS_TX_LARGE_AMP_POST_EMP_LVL 0x024
#define QPHY_PCS_TX_SMALL_AMP_DRV_LVL 0x028
+#define QPHY_PCS_TX_SMALL_AMP_POST_EMP_LVL 0x02c
+#define QPHY_PCS_RX_SIGDET_CTRL2 0x08c
#define QPHY_PCS_PCS_READY_STATUS 0x094
#define QPHY_PCS_TX_MID_TERM_CTRL1 0x0d8
#define QPHY_PCS_TX_MID_TERM_CTRL2 0x0dc
+#define QPHY_PCS_SGMII_MISC_CTRL7 0x114
#define QPHY_PCS_SGMII_MISC_CTRL8 0x118
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
index 7430f49214779855df1cf40acac96440957f9e6d..e8b4a26b361adab6e2b0bd3c91e719f84d1ffbc1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
@@ -58,6 +58,7 @@
#define QSERDES_V7_COM_CLK_ENABLE1 0xe0
#define QSERDES_V7_COM_SYS_CLK_CTRL 0xe4
#define QSERDES_V7_COM_SYSCLK_BUF_ENABLE 0xe8
+#define QSERDES_V7_COM_PLL_EN 0xec
#define QSERDES_V7_COM_PLL_IVCO 0xf4
#define QSERDES_V7_COM_PLL_IVCO_MODE1 0xf8
#define QSERDES_V7_COM_SYSCLK_EN_SEL 0x110
@@ -75,6 +76,7 @@
#define QSERDES_V7_COM_CMN_MISC_1 0x184
#define QSERDES_V7_COM_CMN_MODE 0x188
#define QSERDES_V7_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
+#define QSERDES_V7_COM_BIN_VCOCAL_HSCLK_SEL_1 0x19c
#define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
#define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
#define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
index 6ab943ff57ff666e4f23f4ad0b4eff211c6dbfd0..0c38d62284e4d0e64a27fb82c468f47aee3760bb 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
@@ -7,9 +7,11 @@
#define QCOM_PHY_QMP_QSERDES_TXRX_V7_H_
#define QSERDES_V7_TX_CLKBUF_ENABLE 0x08
+#define QSERDES_V7_TX_TX_EMP_POST1_LVL 0x0c
#define QSERDES_V7_TX_RESET_TSYNC_EN 0x1c
#define QSERDES_V7_TX_PRE_STALL_LDO_BOOST_EN 0x20
#define QSERDES_V7_TX_TX_BAND 0x24
+#define QSERDES_V7_TX_SLEW_CNTL 0x28
#define QSERDES_V7_TX_INTERFACE_SELECT 0x2c
#define QSERDES_V7_TX_RES_CODE_LANE_TX 0x34
#define QSERDES_V7_TX_RES_CODE_LANE_RX 0x38
@@ -35,26 +37,32 @@
#define QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_LOW 0x3c
#define QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_HIGH 0x40
#define QSERDES_V7_RX_UCDR_PI_CONTROLS 0x44
+#define QSERDES_V7_RX_UCDR_PI_CTRL2 0x48
#define QSERDES_V7_RX_UCDR_SB2_THRESH1 0x4c
#define QSERDES_V7_RX_UCDR_SB2_THRESH2 0x50
#define QSERDES_V7_RX_UCDR_SB2_GAIN1 0x54
#define QSERDES_V7_RX_UCDR_SB2_GAIN2 0x58
#define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE 0x60
+#define QSERDES_V7_RX_RX_TERM_BW 0x80
#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1 0xc4
#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2 0xc8
#define QSERDES_V7_RX_TX_ADAPT_POST_THRESH 0xcc
#define QSERDES_V7_RX_VGA_CAL_CNTRL1 0xd4
#define QSERDES_V7_RX_VGA_CAL_CNTRL2 0xd8
#define QSERDES_V7_RX_GM_CAL 0xdc
+#define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL1 0xe8
#define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL2 0xec
#define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL3 0xf0
#define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL4 0xf4
#define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW 0xf8
#define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH 0xfc
+#define QSERDES_V7_RX_RX_IDAC_MEASURE_TIME 0x100
#define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_V7_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114
#define QSERDES_V7_RX_SIGDET_ENABLES 0x118
#define QSERDES_V7_RX_SIGDET_CNTRL 0x11c
#define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_V7_RX_RX_BAND 0x128
#define QSERDES_V7_RX_RX_MODE_00_LOW 0x15c
#define QSERDES_V7_RX_RX_MODE_00_HIGH 0x160
#define QSERDES_V7_RX_RX_MODE_00_HIGH2 0x164
@@ -75,6 +83,7 @@
#define QSERDES_V7_RX_DCC_CTRL1 0x1a8
#define QSERDES_V7_RX_VTH_CODE 0x1b0
#define QSERDES_V7_RX_SIGDET_CAL_CTRL1 0x1e4
+#define QSERDES_V7_RX_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x1e8
#define QSERDES_V7_RX_SIGDET_CAL_TRIM 0x1f8
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 029dafacee7853648ef24afd0d9c4b83a549badf..3c68bfe0ea443ef5cf7f17cead4974862dc04884 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -15,7 +15,9 @@
#include "phy-qcom-qmp-pcs-sgmii.h"
#include "phy-qcom-qmp-qserdes-com-v5.h"
+#include "phy-qcom-qmp-qserdes-com-v7.h"
#include "phy-qcom-qmp-qserdes-txrx-v5.h"
+#include "phy-qcom-qmp-qserdes-txrx-v7.h"
#define QSERDES_QMP_PLL 0x0
#define QSERDES_RX 0x600
@@ -221,6 +223,114 @@ static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)
regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
}
+static void qcom_dwmac_sgmii_phy_init_10g(struct regmap *regmap)
+{
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01);
+
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BG_TIMER, 0x0A);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_IVCO, 0x0F);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x07);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CLK_ENABLE1, 0x0F);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CP_CTRL_MODE0, 0x08);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_RCTRL_MODE0, 0x16);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_CCTRL_MODE0, 0x36);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_INTEGLOOP_GAIN0_MODE0, 0x1F);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_EN, 0x03);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_SYSCLK_EN_SEL, 0x1A);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_LOCK_CMP1_MODE0, 0x23);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_LOCK_CMP2_MODE0, 0x43);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DEC_START_MODE0, 0x43);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START1_MODE0, 0x00);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START2_MODE0, 0x38);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START3_MODE0, 0x02);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE1_MODE0, 0xE6);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE2_MODE0, 0x01);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE_INITVAL2, 0x00);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_HSCLK_SEL_1, 0x00);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_HSCLK_HS_SWITCH_SEL_1, 0x00);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_CORE_CLK_DIV_MODE0, 0x04);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CORE_CLK_EN, 0x30);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CMN_CONFIG_1, 0x16);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xD7);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0F);
+ regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x11);
+
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_CLKBUF_ENABLE, 0x0D);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TX_BAND, 0x04);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_SLEW_CNTL, 0x08);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RES_CODE_LANE_OFFSET_RX, 0x09);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_1, 0xF5);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_2, 0x06);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_3, 0x3F);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_4, 0x3F);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_5, 0x5F);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RCV_DETECT_LVL_2, 0x12);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TRAN_DRVR_EMP_EN, 0x0F);
+ regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TX_EMP_POST1_LVL, 0x2B);
+
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FO_GAIN, 0x0D);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SO_GAIN, 0x03);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_PI_CONTROLS, 0x81);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_PI_CTRL2, 0x81);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SB2_THRESH1, 0x11);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SB2_THRESH2, 0x22);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_TERM_BW, 0x03);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_VGA_CAL_CNTRL2, 0x08);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_GM_CAL, 0x0F);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL4, 0x5A);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW, 0x80);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_MEASURE_TIME, 0x20);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CNTRL, 0x0F);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_BAND, 0x18);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_LOW, 0x1F);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH, 0xBF);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH2, 0xFF);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH3, 0xDF);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH4, 0xEF);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_LOW, 0xE5);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH, 0xC8);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH2, 0xC8);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH3, 0x14);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH4, 0xB6);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_LOW, 0xE0);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH, 0xC8);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH2, 0xC8);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH3, 0x3B);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH4, 0xB7);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_DCC_CTRL1, 0x0C);
+
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x00);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1A);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x00);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x0B);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CAL_CTRL1, 0x00);
+ regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_RX_SIGDET_CTRL2, 0xCC);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL7, 0x00);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x14);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_RETIME_BUFFER_EN, 0x01);
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00);
+
+ regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
+}
+
static inline int
qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
unsigned int bit)
@@ -265,6 +375,40 @@ static int qcom_dwmac_sgmii_phy_poll_sgmii_ready(struct device *dev,
return 0;
}
+static int qcom_dwmac_sgmii_phy_poll_usxgmii_ready(struct device *dev,
+ struct regmap *regmap)
+{
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
+ QSERDES_QMP_PLL + QSERDES_V7_COM_C_READY_STATUS,
+ QSERDES_COM_C_READY)) {
+ dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
+ return -ETIMEDOUT;
+ }
+
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
+ QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
+ QSERDES_PCS_READY)) {
+ dev_err(dev, "PCS_READY timed-out");
+ return -ETIMEDOUT;
+ }
+
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
+ QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
+ QSERDES_PCS_SGMIIPHY_READY)) {
+ dev_err(dev, "SGMIIPHY_READY timed-out");
+ return -ETIMEDOUT;
+ }
+
+ if (qcom_dwmac_sgmii_phy_poll_status(regmap,
+ QSERDES_QMP_PLL + QSERDES_V7_COM_CMN_STATUS,
+ QSERDES_COM_C_PLL_LOCKED)) {
+ dev_err(dev, "PLL Lock Status timed-out");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
@@ -275,16 +419,19 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
case PHY_INTERFACE_MODE_1000BASEX:
/* 1.25Gbps mode */
qcom_dwmac_sgmii_phy_init_1g(data->regmap);
- break;
+ return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
case PHY_INTERFACE_MODE_2500BASEX:
/* 3.125Gbps mode */
qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
- break;
+ return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ /* 10.3125Gbps mode */
+ qcom_dwmac_sgmii_phy_init_10g(data->regmap);
+ return qcom_dwmac_sgmii_phy_poll_usxgmii_ready(dev, data->regmap);
default:
return -EINVAL;
}
-
- return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
}
static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
@@ -340,7 +487,9 @@ static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
if (submode == PHY_INTERFACE_MODE_SGMII ||
submode == PHY_INTERFACE_MODE_1000BASEX ||
- submode == PHY_INTERFACE_MODE_2500BASEX)
+ submode == PHY_INTERFACE_MODE_2500BASEX ||
+ submode == PHY_INTERFACE_MODE_USXGMII ||
+ submode == PHY_INTERFACE_MODE_10GBASER)
return 0;
return -EINVAL;
@@ -434,12 +583,19 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
return 0;
}
+static const struct qcom_dwmac_sgmii_phy_match_data nord_match_data = {
+ .default_interface = PHY_INTERFACE_MODE_USXGMII,
+};
+
static const struct qcom_dwmac_sgmii_phy_match_data sa8775p_match_data = {
.default_interface = PHY_INTERFACE_MODE_SGMII,
};
static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
{
+ .compatible = "qcom,nord-dwmac-sgmii-phy",
+ .data = &nord_match_data,
+ }, {
.compatible = "qcom,sa8775p-dwmac-sgmii-phy",
.data = &sa8775p_match_data,
},
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support
2026-09-23 0:04 [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
` (2 preceding siblings ...)
2026-09-23 0:04 ` [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
@ 2026-09-23 8:58 ` Zhangfei Gao
3 siblings, 0 replies; 9+ messages in thread
From: Zhangfei Gao @ 2026-09-23 8:58 UTC (permalink / raw)
To: Mohd Ayaan Anwar
Cc: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo
On Wed, Sep 23, 2026 at 8:04 AM Mohd Ayaan Anwar
<mohd.anwar@oss.qualcomm.com> wrote:
>
> This series adds support for the Ethernet SerDes found on the Qualcomm
> Nord SoC.
>
> Nord uses a QMP v7 SerDes block, which is an updated version of the
> SGMII SerDes PHY IP already handled by phy-qcom-sgmii-eth. The driver
> currently supports the 1.25 Gbaud and 3.125 Gbaud configurations used by
> SGMII, 1000BASE-X and 2500BASE-X. Nord additionally requires the SerDes
> to operate at 10.3125 Gbaud for its 10 Gigabit Ethernet interfaces.
>
> The series can be broadly divided into three parts:
>
> 1. Add the qcom,nord-dwmac-sgmii-phy compatible to the binding.
> 2. Prepare the driver for PHY modes which require different SerDes
> programming and readiness checks. Existing SA8775P behaviour is
> unchanged.
> 3. Add the QMP v7 register definitions, 10.3125 Gbaud programming
> sequence and readiness checks required for USXGMII and 10GBASE-R.
>
> The changes have been tested on the Nord Ride SX platform, which has a
> MV-Q6223 switch, running in fixed link USXGMII 10G mode.
>
> Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
> ---
> Mohd Ayaan Anwar (3):
> dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible
> phy: qcom: sgmii-eth: prepare for additional PHY modes
> phy: qcom: sgmii-eth: add Nord USXGMII support
>
> .../bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml | 1 +
> drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h | 5 +
> drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h | 2 +
> .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h | 9 +
> drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 226 ++++++++++++++++++---
> 5 files changed, 219 insertions(+), 24 deletions(-)
> ---
> base-commit: a8c591ed6b672915e0be57843f943a2a723aff40
> change-id: 20260923-nord_ethernet_serdes-c486f715f383
>
> Best regards,
> --
> Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
>
Good Job,
Tested-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
Tested on both IQ10 RRD and Ride
Full test patch is in the git
https://github.com/zhangfei-gao/kernel-topics/tree/next-9.23
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
@ 2026-09-25 13:35 ` Lorenzo Bianconi
2026-09-25 13:59 ` Bartosz Golaszewski
1 sibling, 0 replies; 9+ messages in thread
From: Lorenzo Bianconi @ 2026-09-25 13:35 UTC (permalink / raw)
To: Mohd Ayaan Anwar
Cc: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
linux-arm-msm, linux-phy, devicetree, linux-kernel, Shawn Guo,
Zhangfei Gao
[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]
> Add the qcom,nord-dwmac-sgmii-phy compatible to the Qualcomm DWMAC
> SGMII PHY binding.
>
> Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> ---
> Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
> index e573abcb937df914ced25ec87add7955bbba7b87..f2df9983d9536654e838bae4e1e23b832cdaea3c 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml
> @@ -21,6 +21,7 @@ properties:
> - qcom,qcs8300-dwmac-sgmii-phy
> - const: qcom,sa8775p-dwmac-sgmii-phy
> - const: qcom,sa8775p-dwmac-sgmii-phy
> + - const: qcom,nord-dwmac-sgmii-phy
>
> reg:
> items:
>
> --
> 2.34.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes
2026-09-23 0:04 ` [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes Mohd Ayaan Anwar
@ 2026-09-25 13:49 ` Lorenzo Bianconi
0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Bianconi @ 2026-09-25 13:49 UTC (permalink / raw)
To: Mohd Ayaan Anwar
Cc: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
linux-arm-msm, linux-phy, devicetree, linux-kernel, Shawn Guo,
Zhangfei Gao
[-- Attachment #1: Type: text/plain, Size: 5682 bytes --]
> Prepare the SGMII Ethernet PHY driver for PHY modes that require a
> different SerDes programming sequence. Move the SGMII readiness checks
> into a helper so additional modes can provide their own status checks,
> and select the initial interface mode through per-compatible match data
> rather than hardcoding SGMII during probe.
>
> This does not change existing SA8775P behavior.
>
> Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
Hi Mohd,
just few nits inline. Fixing them:
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 70 ++++++++++++++++++++-----------
> 1 file changed, 46 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> index 7137200c3f310a4d2642bb9bdbe3adb7589b2241..029dafacee7853648ef24afd0d9c4b83a549badf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> +++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> @@ -41,6 +41,10 @@ struct qcom_dwmac_sgmii_phy_data {
> phy_interface_t interface;
> };
>
> +struct qcom_dwmac_sgmii_phy_match_data {
> + phy_interface_t default_interface;
nit: maybe better 'interface' instead of 'default_interface'?
> +};
> +
> static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
> {
> regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
> @@ -227,47 +231,31 @@ qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
> val & bit, 1500, 750000);
> }
>
> -static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
> +static int qcom_dwmac_sgmii_phy_poll_sgmii_ready(struct device *dev,
> + struct regmap *regmap)
nit: can you please fix the alignement here?
> {
> - struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
> - struct device *dev = phy->dev.parent;
> -
> - 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 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,
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> QSERDES_QMP_PLL + QSERDES_V5_COM_C_READY_STATUS,
> QSERDES_COM_C_READY)) {
> dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
> return -ETIMEDOUT;
> }
>
> - if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
> QSERDES_PCS_READY)) {
> dev_err(dev, "PCS_READY timed-out");
> return -ETIMEDOUT;
> }
>
> - if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
> QSERDES_PCS_SGMIIPHY_READY)) {
> dev_err(dev, "SGMIIPHY_READY timed-out");
> return -ETIMEDOUT;
> }
>
> - if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> QSERDES_QMP_PLL + QSERDES_V5_COM_CMN_STATUS,
> QSERDES_COM_C_PLL_LOCKED)) {
> dev_err(dev, "PLL Lock Status timed-out");
> @@ -277,6 +265,28 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
> return 0;
> }
>
> +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->interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + /* 1.25Gbps mode */
> + qcom_dwmac_sgmii_phy_init_1g(data->regmap);
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + /* 3.125Gbps mode */
> + qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
> +}
> +
> static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
> {
> struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
> @@ -374,6 +384,7 @@ static const struct regmap_config qcom_dwmac_sgmii_phy_regmap_cfg = {
>
> static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
> {
> + const struct qcom_dwmac_sgmii_phy_match_data *match_data;
> struct qcom_dwmac_sgmii_phy_data *data;
> struct device *dev = &pdev->dev;
> struct phy_provider *provider;
> @@ -385,7 +396,11 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
> if (!data)
> return -ENOMEM;
>
> - data->interface = PHY_INTERFACE_MODE_SGMII;
> + match_data = device_get_match_data(dev);
> + if (!match_data)
> + return -EINVAL;
> +
> + data->interface = match_data->default_interface;
>
> base = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(base))
> @@ -419,8 +434,15 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct qcom_dwmac_sgmii_phy_match_data sa8775p_match_data = {
> + .default_interface = PHY_INTERFACE_MODE_SGMII,
> +};
> +
> static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
> - { .compatible = "qcom,sa8775p-dwmac-sgmii-phy" },
> + {
> + .compatible = "qcom,sa8775p-dwmac-sgmii-phy",
> + .data = &sa8775p_match_data,
> + },
> { },
> };
> MODULE_DEVICE_TABLE(of, qcom_dwmac_sgmii_phy_of_match);
>
> --
> 2.34.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
2026-09-25 13:35 ` Lorenzo Bianconi
@ 2026-09-25 13:59 ` Bartosz Golaszewski
1 sibling, 0 replies; 9+ messages in thread
From: Bartosz Golaszewski @ 2026-09-25 13:59 UTC (permalink / raw)
To: Mohd Ayaan Anwar
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Lorenzo Bianconi, Shawn Guo, Zhangfei Gao, Vinod Koul,
Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski
On Wed, 23 Sep 2026 02:04:17 +0200, Mohd Ayaan Anwar
<mohd.anwar@oss.qualcomm.com> said:
> Add the qcom,nord-dwmac-sgmii-phy compatible to the Qualcomm DWMAC
> SGMII PHY binding.
>
> Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support
2026-09-23 0:04 ` [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
@ 2026-09-25 13:59 ` Lorenzo Bianconi
0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Bianconi @ 2026-09-25 13:59 UTC (permalink / raw)
To: Mohd Ayaan Anwar
Cc: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
linux-arm-msm, linux-phy, devicetree, linux-kernel, Shawn Guo,
Zhangfei Gao
[-- Attachment #1: Type: text/plain, Size: 18587 bytes --]
> Nord uses a QMP v7 SerDes block which is an updated version of the
> SGMII SerDes PHY IP.
>
> The SGMII SerDes PHY supports multiple operating modes by programming
> different SerDes line rates. The driver currently handles SGMII and
> 2500BASE-X configurations only.
>
> Add support for configuring the SerDes to operate at 10.3125 Gbaud,
> enabling both USXGMII and 10GBASE-R PHY interface modes. Finally, add a
> driver compatible for Nord.
>
> Select USXGMII as the initial interface mode for Nord. phy_power_on()
> can run before the consumer calls set_mode(), so this ensures that the
> first calibration selects the 10.3125 Gbaud programming sequence.
>
> Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
just trivial nits inline.
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h | 5 +
> drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h | 2 +
> .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h | 9 ++
> drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 166 ++++++++++++++++++++-
> 4 files changed, 177 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
> index 4d8c962f5e0f52974f3edd5d1acdd8da535de200..67ab2fe085de3d90520cfc43cc0ac7abaab1f21d 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-sgmii.h
> @@ -10,11 +10,16 @@
> #define QPHY_PCS_POWER_DOWN_CONTROL 0x004
> #define QPHY_PCS_SW_RESET 0x008
> #define QPHY_PCS_LINE_RESET_TIME 0x00c
> +#define QPHY_PCS_RETIME_BUFFER_EN 0x018
> #define QPHY_PCS_TX_LARGE_AMP_DRV_LVL 0x020
> +#define QPHY_PCS_TX_LARGE_AMP_POST_EMP_LVL 0x024
> #define QPHY_PCS_TX_SMALL_AMP_DRV_LVL 0x028
> +#define QPHY_PCS_TX_SMALL_AMP_POST_EMP_LVL 0x02c
> +#define QPHY_PCS_RX_SIGDET_CTRL2 0x08c
nit: can you please fix the alignement here?
> #define QPHY_PCS_PCS_READY_STATUS 0x094
> #define QPHY_PCS_TX_MID_TERM_CTRL1 0x0d8
> #define QPHY_PCS_TX_MID_TERM_CTRL2 0x0dc
> +#define QPHY_PCS_SGMII_MISC_CTRL7 0x114
> #define QPHY_PCS_SGMII_MISC_CTRL8 0x118
>
> #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
> index 7430f49214779855df1cf40acac96440957f9e6d..e8b4a26b361adab6e2b0bd3c91e719f84d1ffbc1 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v7.h
> @@ -58,6 +58,7 @@
> #define QSERDES_V7_COM_CLK_ENABLE1 0xe0
> #define QSERDES_V7_COM_SYS_CLK_CTRL 0xe4
> #define QSERDES_V7_COM_SYSCLK_BUF_ENABLE 0xe8
> +#define QSERDES_V7_COM_PLL_EN 0xec
> #define QSERDES_V7_COM_PLL_IVCO 0xf4
> #define QSERDES_V7_COM_PLL_IVCO_MODE1 0xf8
> #define QSERDES_V7_COM_SYSCLK_EN_SEL 0x110
> @@ -75,6 +76,7 @@
> #define QSERDES_V7_COM_CMN_MISC_1 0x184
> #define QSERDES_V7_COM_CMN_MODE 0x188
> #define QSERDES_V7_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
> +#define QSERDES_V7_COM_BIN_VCOCAL_HSCLK_SEL_1 0x19c
> #define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
> #define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
> #define QSERDES_V7_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
> index 6ab943ff57ff666e4f23f4ad0b4eff211c6dbfd0..0c38d62284e4d0e64a27fb82c468f47aee3760bb 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
> @@ -7,9 +7,11 @@
> #define QCOM_PHY_QMP_QSERDES_TXRX_V7_H_
>
> #define QSERDES_V7_TX_CLKBUF_ENABLE 0x08
> +#define QSERDES_V7_TX_TX_EMP_POST1_LVL 0x0c
> #define QSERDES_V7_TX_RESET_TSYNC_EN 0x1c
> #define QSERDES_V7_TX_PRE_STALL_LDO_BOOST_EN 0x20
> #define QSERDES_V7_TX_TX_BAND 0x24
> +#define QSERDES_V7_TX_SLEW_CNTL 0x28
> #define QSERDES_V7_TX_INTERFACE_SELECT 0x2c
> #define QSERDES_V7_TX_RES_CODE_LANE_TX 0x34
> #define QSERDES_V7_TX_RES_CODE_LANE_RX 0x38
> @@ -35,26 +37,32 @@
> #define QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_LOW 0x3c
> #define QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_HIGH 0x40
> #define QSERDES_V7_RX_UCDR_PI_CONTROLS 0x44
> +#define QSERDES_V7_RX_UCDR_PI_CTRL2 0x48
> #define QSERDES_V7_RX_UCDR_SB2_THRESH1 0x4c
> #define QSERDES_V7_RX_UCDR_SB2_THRESH2 0x50
> #define QSERDES_V7_RX_UCDR_SB2_GAIN1 0x54
> #define QSERDES_V7_RX_UCDR_SB2_GAIN2 0x58
> #define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE 0x60
> +#define QSERDES_V7_RX_RX_TERM_BW 0x80
nit: can you please fix the alignement here?
> #define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1 0xc4
> #define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2 0xc8
> #define QSERDES_V7_RX_TX_ADAPT_POST_THRESH 0xcc
> #define QSERDES_V7_RX_VGA_CAL_CNTRL1 0xd4
> #define QSERDES_V7_RX_VGA_CAL_CNTRL2 0xd8
> #define QSERDES_V7_RX_GM_CAL 0xdc
> +#define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL1 0xe8
> #define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL2 0xec
> #define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL3 0xf0
> #define QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL4 0xf4
> #define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW 0xf8
> #define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH 0xfc
> +#define QSERDES_V7_RX_RX_IDAC_MEASURE_TIME 0x100
> #define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
> +#define QSERDES_V7_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114
> #define QSERDES_V7_RX_SIGDET_ENABLES 0x118
> #define QSERDES_V7_RX_SIGDET_CNTRL 0x11c
> #define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL 0x124
> +#define QSERDES_V7_RX_RX_BAND 0x128
> #define QSERDES_V7_RX_RX_MODE_00_LOW 0x15c
> #define QSERDES_V7_RX_RX_MODE_00_HIGH 0x160
> #define QSERDES_V7_RX_RX_MODE_00_HIGH2 0x164
> @@ -75,6 +83,7 @@
> #define QSERDES_V7_RX_DCC_CTRL1 0x1a8
> #define QSERDES_V7_RX_VTH_CODE 0x1b0
> #define QSERDES_V7_RX_SIGDET_CAL_CTRL1 0x1e4
> +#define QSERDES_V7_RX_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x1e8
> #define QSERDES_V7_RX_SIGDET_CAL_TRIM 0x1f8
>
> #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> index 029dafacee7853648ef24afd0d9c4b83a549badf..3c68bfe0ea443ef5cf7f17cead4974862dc04884 100644
> --- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> +++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
> @@ -15,7 +15,9 @@
>
> #include "phy-qcom-qmp-pcs-sgmii.h"
> #include "phy-qcom-qmp-qserdes-com-v5.h"
> +#include "phy-qcom-qmp-qserdes-com-v7.h"
> #include "phy-qcom-qmp-qserdes-txrx-v5.h"
> +#include "phy-qcom-qmp-qserdes-txrx-v7.h"
>
> #define QSERDES_QMP_PLL 0x0
> #define QSERDES_RX 0x600
> @@ -221,6 +223,114 @@ static void qcom_dwmac_sgmii_phy_init_2p5g(struct regmap *regmap)
> regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
> }
>
> +static void qcom_dwmac_sgmii_phy_init_10g(struct regmap *regmap)
> +{
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x01);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_POWER_DOWN_CONTROL, 0x01);
> +
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BG_TIMER, 0x0A);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_IVCO, 0x0F);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x07);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CLK_ENABLE1, 0x0F);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CP_CTRL_MODE0, 0x08);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_RCTRL_MODE0, 0x16);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_CCTRL_MODE0, 0x36);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_INTEGLOOP_GAIN0_MODE0, 0x1F);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_EN, 0x03);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_SYSCLK_EN_SEL, 0x1A);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_LOCK_CMP1_MODE0, 0x23);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_LOCK_CMP2_MODE0, 0x43);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DEC_START_MODE0, 0x43);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START1_MODE0, 0x00);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START2_MODE0, 0x38);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_DIV_FRAC_START3_MODE0, 0x02);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE1_MODE0, 0xE6);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE2_MODE0, 0x01);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_VCO_TUNE_INITVAL2, 0x00);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_HSCLK_SEL_1, 0x00);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_HSCLK_HS_SWITCH_SEL_1, 0x00);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_PLL_CORE_CLK_DIV_MODE0, 0x04);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CORE_CLK_EN, 0x30);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_CMN_CONFIG_1, 0x16);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xD7);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0F);
> + regmap_write(regmap, QSERDES_QMP_PLL + QSERDES_V7_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x11);
> +
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_CLKBUF_ENABLE, 0x0D);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TX_BAND, 0x04);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_SLEW_CNTL, 0x08);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RES_CODE_LANE_OFFSET_TX, 0x09);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RES_CODE_LANE_OFFSET_RX, 0x09);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_1, 0xF5);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_2, 0x06);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_3, 0x3F);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_4, 0x3F);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_LANE_MODE_5, 0x5F);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_RCV_DETECT_LVL_2, 0x12);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TRAN_DRVR_EMP_EN, 0x0F);
> + regmap_write(regmap, QSERDES_TX + QSERDES_V7_TX_TX_EMP_POST1_LVL, 0x2B);
> +
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FO_GAIN, 0x0D);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SO_GAIN, 0x03);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_FO_GAIN, 0x0A);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x01);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_PI_CONTROLS, 0x81);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_PI_CTRL2, 0x81);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SB2_THRESH1, 0x11);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_UCDR_SB2_THRESH2, 0x22);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_TERM_BW, 0x03);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_VGA_CAL_CNTRL2, 0x08);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_GM_CAL, 0x0F);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQU_ADAPTOR_CNTRL4, 0x5A);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW, 0x80);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH, 0x01);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_IDAC_MEASURE_TIME, 0x20);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CNTRL, 0x0F);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL, 0x1E);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_BAND, 0x18);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_LOW, 0x1F);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH, 0xBF);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH2, 0xFF);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH3, 0xDF);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_00_HIGH4, 0xEF);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_LOW, 0xE5);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH, 0xC8);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH2, 0xC8);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH3, 0x14);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_01_HIGH4, 0xB6);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_LOW, 0xE0);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH, 0xC8);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH2, 0xC8);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH3, 0x3B);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_RX_MODE_10_HIGH4, 0xB7);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_DCC_CTRL1, 0x0C);
> +
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_LINE_RESET_TIME, 0x00);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_DRV_LVL, 0x03);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_DRV_LVL, 0x1A);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x00);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x0B);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL1, 0x83);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_TX_MID_TERM_CTRL2, 0x08);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CAL_CTRL1, 0x00);
> + regmap_write(regmap, QSERDES_RX + QSERDES_V7_RX_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_RX_SIGDET_CTRL2, 0xCC);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL7, 0x00);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SGMII_MISC_CTRL8, 0x14);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_RETIME_BUFFER_EN, 0x01);
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_SW_RESET, 0x00);
> +
> + regmap_write(regmap, QSERDES_PCS + QPHY_PCS_PHY_START, 0x01);
> +}
> +
> static inline int
> qcom_dwmac_sgmii_phy_poll_status(struct regmap *regmap, unsigned int reg,
> unsigned int bit)
> @@ -265,6 +375,40 @@ static int qcom_dwmac_sgmii_phy_poll_sgmii_ready(struct device *dev,
> return 0;
> }
>
> +static int qcom_dwmac_sgmii_phy_poll_usxgmii_ready(struct device *dev,
> + struct regmap *regmap)
nit: can you please fix the alignement here?
> +{
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> + QSERDES_QMP_PLL + QSERDES_V7_COM_C_READY_STATUS,
> + QSERDES_COM_C_READY)) {
> + dev_err(dev, "QSERDES_COM_C_READY_STATUS timed-out");
> + return -ETIMEDOUT;
> + }
> +
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> + QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
> + QSERDES_PCS_READY)) {
> + dev_err(dev, "PCS_READY timed-out");
> + return -ETIMEDOUT;
> + }
> +
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> + QSERDES_PCS + QPHY_PCS_PCS_READY_STATUS,
> + QSERDES_PCS_SGMIIPHY_READY)) {
> + dev_err(dev, "SGMIIPHY_READY timed-out");
> + return -ETIMEDOUT;
> + }
> +
> + if (qcom_dwmac_sgmii_phy_poll_status(regmap,
> + QSERDES_QMP_PLL + QSERDES_V7_COM_CMN_STATUS,
> + QSERDES_COM_C_PLL_LOCKED)) {
> + dev_err(dev, "PLL Lock Status timed-out");
> + return -ETIMEDOUT;
> + }
> +
> + return 0;
> +}
> +
> static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
> {
> struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
> @@ -275,16 +419,19 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
> case PHY_INTERFACE_MODE_1000BASEX:
> /* 1.25Gbps mode */
> qcom_dwmac_sgmii_phy_init_1g(data->regmap);
> - break;
> + return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
> case PHY_INTERFACE_MODE_2500BASEX:
> /* 3.125Gbps mode */
> qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
> - break;
> + return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + /* 10.3125Gbps mode */
> + qcom_dwmac_sgmii_phy_init_10g(data->regmap);
> + return qcom_dwmac_sgmii_phy_poll_usxgmii_ready(dev, data->regmap);
> default:
> return -EINVAL;
> }
> -
> - return qcom_dwmac_sgmii_phy_poll_sgmii_ready(dev, data->regmap);
> }
>
> static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
> @@ -340,7 +487,9 @@ static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
>
> if (submode == PHY_INTERFACE_MODE_SGMII ||
> submode == PHY_INTERFACE_MODE_1000BASEX ||
> - submode == PHY_INTERFACE_MODE_2500BASEX)
> + submode == PHY_INTERFACE_MODE_2500BASEX ||
> + submode == PHY_INTERFACE_MODE_USXGMII ||
> + submode == PHY_INTERFACE_MODE_10GBASER)
> return 0;
>
> return -EINVAL;
> @@ -434,12 +583,19 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct qcom_dwmac_sgmii_phy_match_data nord_match_data = {
> + .default_interface = PHY_INTERFACE_MODE_USXGMII,
> +};
> +
> static const struct qcom_dwmac_sgmii_phy_match_data sa8775p_match_data = {
> .default_interface = PHY_INTERFACE_MODE_SGMII,
> };
>
> static const struct of_device_id qcom_dwmac_sgmii_phy_of_match[] = {
> {
> + .compatible = "qcom,nord-dwmac-sgmii-phy",
> + .data = &nord_match_data,
> + }, {
> .compatible = "qcom,sa8775p-dwmac-sgmii-phy",
> .data = &sa8775p_match_data,
> },
>
> --
> 2.34.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-09-25 14:00 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 0:04 [PATCH 0/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
2026-09-23 0:04 ` [PATCH 1/3] dt-bindings: phy: qcom,sa8775p-dwmac-sgmii-phy: add Nord compatible Mohd Ayaan Anwar
2026-09-25 13:35 ` Lorenzo Bianconi
2026-09-25 13:59 ` Bartosz Golaszewski
2026-09-23 0:04 ` [PATCH 2/3] phy: qcom: sgmii-eth: prepare for additional PHY modes Mohd Ayaan Anwar
2026-09-25 13:49 ` Lorenzo Bianconi
2026-09-23 0:04 ` [PATCH 3/3] phy: qcom: sgmii-eth: add Nord USXGMII support Mohd Ayaan Anwar
2026-09-25 13:59 ` Lorenzo Bianconi
2026-09-23 8:58 ` [PATCH 0/3] " Zhangfei Gao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®