From: George Moussalem <george.moussalem@outlook.com>
Date: Fri, 24 Jan 2025 17:18:12 +0400
Subject: [PATCH] net: phy: qcom: add IPQ5018 initvals and CDT feature

The Cable Diagnostics Test for IPQ5018 follows the same logic as qca808x.
However, the IPQ5018 GE PHY has its own threshold values. So let's set the
CDT thresholds for the IPQ5018 internal GE PHY. While add it, add and set
thesholds for MSE for signal quality measurement and 8023az for EEE.

Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
--- a/drivers/net/phy/qcom/ipq5018.c
+++ b/drivers/net/phy/qcom/ipq5018.c
@@ -17,6 +17,38 @@
 #define IPQ5018_PHY_MMD1_MDAC			0x8100
 #define  IPQ5018_PHY_DAC_MASK			GENMASK(15,8)
 
+#define IPQ5018_PHY_MMD1_MSE_THRESH1			0x1000
+#define IPQ5018_PHY_MMD1_MSE_THRESH2			0x1001
+#define IPQ5018_PHY_MMD3_AZ_CTRL1				0x8008
+#define IPQ5018_PHY_MMD3_AZ_CTRL2				0x8009
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3		0x8074
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4		0x8075
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5		0x8076
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6		0x8077
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7		0x8078
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9		0x807a
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13		0x807e
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL14		0x807f
+
+#define IPQ5018_PHY_MMD1_MSE_THRESH1_VAL		0xf1
+#define IPQ5018_PHY_MMD1_MSE_THRESH2_VAL		0x1f6
+#define IPQ5018_PHY_MMD3_AZ_CTRL1_VAL			0x7880
+#define IPQ5018_PHY_MMD3_AZ_CTRL2_VAL			0xc8
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3_VAL	0xc040
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4_VAL	0xa060
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5_VAL	0xc040
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6_VAL	0xa060
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7_VAL	0xc24c
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9_VAL	0xc060
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13_VAL	0xb060
+#define IPQ5018_PHY_MMD3_NEAR_ECHO_THRESH_VAL	0x90b0
+
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE				0x1
+#define  IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK		GENMASK(7,4)
+#define  IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT	0x50
+
+#define IPQ5018_PHY_DEBUG_ANA_DAC_FILTER		0xa080
+
 struct ipq5018_phy {
 	int num_clks;
 	struct clk_bulk_data *clks;
@@ -129,6 +161,24 @@ static int ipq5018_soft_reset(struct phy
 
 static int ipq5018_cable_test_start(struct phy_device *phydev)
 {
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13,
+				  IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3,
+				  IPQ5018_PHY_MMD3_NEAR_ECHO_THRESH_VAL);
+
 	/* we do all the (time consuming) work later */
 	return 0;
 }
@@ -136,8 +186,30 @@ static int ipq5018_cable_test_start(stru
 static int ipq5018_config_init(struct phy_device *phydev)
 {
 	struct ipq5018_phy *priv = phydev->priv;
+	u16 val = 0;
 	int ret;
 
+	/* set LDO efuse: first temporarily store ANA_DAC_FILTER value from 
+	   debug register as it will be reset once the ANA_LDO_EFUSE register
+	   is written to */
+	val = at803x_debug_reg_read(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER);
+	at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE,
+						  IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK,
+						  IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT);
+	at803x_debug_reg_write(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER, val);
+
+	/* set 8023AZ CTRL values */
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_AZ_CTRL1,
+				  IPQ5018_PHY_MMD3_AZ_CTRL1_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_AZ_CTRL2,
+				  IPQ5018_PHY_MMD3_AZ_CTRL2_VAL);
+
+	/* set MSE threshold values */
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH1,
+				  IPQ5018_PHY_MMD1_MSE_THRESH1_VAL);
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH2,
+				  IPQ5018_PHY_MMD1_MSE_THRESH2_VAL);
+
 	/* setting mdac in MMD1 */
 	if (priv->mdac) {
 		ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MDAC,
