mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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®