From b5c662f1fd1f894a49e3f95582db5d48999e98ce Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Mon, 2 Jun 2025 17:18:13 +0300
Subject: [PATCH] net: pcs: ipq-uniphy: control MISC2 register for 2.5G support

When 2500base-x mode is enabled MISC2 regsister needs to have different
value than for other 1G modes.

Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
 drivers/net/pcs/pcs-qcom-ipq9574.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

--- a/drivers/net/pcs/pcs-qcom-ipq9574.c
+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
@@ -22,6 +22,11 @@
 #define PCS_CALIBRATION			0x1e0
 #define PCS_CALIBRATION_DONE		BIT(7)
 
+#define PCS_MISC2			0x218
+#define PCS_MISC2_MODE_MASK		GENMASK(6, 5)
+#define PCS_MISC2_MODE_SGMII		FIELD_PREP(PCS_MISC2_MODE_MASK, 0x1)
+#define PCS_MISC2_MODE_SGMII_PLUS	FIELD_PREP(PCS_MISC2_MODE_MASK, 0x2)
+
 #define PCS_MODE_CTRL			0x46c
 #define PCS_MODE_SEL_MASK		GENMASK(12, 8)
 #define PCS_MODE_SGMII			FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
@@ -275,7 +280,7 @@ static int ipq_pcs_config_mode(struct ip
 			       phy_interface_t interface)
 {
 	unsigned long rate = 125000000;
-	unsigned int val, mask;
+	unsigned int val, mask, misc2 = 0;
 	int ret;
 
 	/* Configure PCS interface mode */
@@ -283,6 +288,7 @@ static int ipq_pcs_config_mode(struct ip
 	switch (interface) {
 	case PHY_INTERFACE_MODE_SGMII:
 		val = PCS_MODE_SGMII;
+		misc2 = PCS_MISC2_MODE_SGMII;
 		break;
 	case PHY_INTERFACE_MODE_QSGMII:
 		val = PCS_MODE_QSGMII;
@@ -290,9 +296,11 @@ static int ipq_pcs_config_mode(struct ip
 	case PHY_INTERFACE_MODE_1000BASEX:
 		mask |= PCS_MODE_SGMII_MODE_MASK;
 		val = PCS_MODE_SGMII | PCS_MODE_SGMII_MODE_1000BASEX;
+		misc2 = PCS_MISC2_MODE_SGMII;
 		break;
 	case PHY_INTERFACE_MODE_2500BASEX:
 		val = PCS_MODE_2500BASEX;
+		misc2 = PCS_MISC2_MODE_SGMII_PLUS;
 		rate = 312500000;
 		break;
 	case PHY_INTERFACE_MODE_USXGMII:
@@ -315,6 +323,13 @@ static int ipq_pcs_config_mode(struct ip
 		if (ret)
 			return ret;
 	}
+
+	if (misc2) {
+		ret = regmap_update_bits(qpcs->regmap, PCS_MISC2,
+					 PCS_MISC2_MODE_MASK, misc2);
+		if (ret)
+			return ret;
+	}
 
 	/* PCS PLL reset */
 	ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
