diff mbox series

[1/2] net: phy: micrel: add support for DLL setup on ksz9131

Message ID 1606987111-19754-2-git-send-email-claudiu.beznea@microchip.com
State Accepted
Commit c6df0e2ffdc468ce34a7bc77fa5a298e0359e7a0
Delegated to: Eugen Hristev
Headers show
Series add support for dll setup on ksz9131 | expand

Commit Message

Claudiu Beznea Dec. 3, 2020, 9:18 a.m. UTC
Add support for DLL setup on KSZ9131.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/net/phy/micrel_ksz90x1.c | 63 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index f0032e8ce166..d6694c5cd88f 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -396,9 +396,70 @@  static struct phy_driver ksz9031_driver = {
 /*
  * KSZ9131
  */
+
+#define KSZ9131RN_MMD_COMMON_CTRL_REG	2
+#define KSZ9131RN_RXC_DLL_CTRL		76
+#define KSZ9131RN_TXC_DLL_CTRL		77
+#define KSZ9131RN_DLL_CTRL_BYPASS	BIT_MASK(12)
+#define KSZ9131RN_DLL_ENABLE_DELAY	0
+#define KSZ9131RN_DLL_DISABLE_DELAY	BIT(12)
+
+static int ksz9131_config_rgmii_delay(struct phy_device *phydev)
+{
+	struct phy_driver *drv = phydev->drv;
+	u16 rxcdll_val, txcdll_val, val;
+	int ret;
+
+	switch (phydev->interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+		rxcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+		txcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		rxcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+		txcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		rxcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+		txcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		rxcdll_val = KSZ9131RN_DLL_DISABLE_DELAY;
+		txcdll_val = KSZ9131RN_DLL_ENABLE_DELAY;
+		break;
+	default:
+		return 0;
+	}
+
+	val = drv->readext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
+			   KSZ9131RN_RXC_DLL_CTRL);
+	val &= ~KSZ9131RN_DLL_CTRL_BYPASS;
+	val |= rxcdll_val;
+	ret = drv->writeext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
+			    KSZ9131RN_RXC_DLL_CTRL, val);
+	if (ret)
+		return ret;
+
+	val = drv->readext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
+			   KSZ9131RN_TXC_DLL_CTRL);
+
+	val &= ~KSZ9131RN_DLL_CTRL_BYPASS;
+	val |= txcdll_val;
+	ret = drv->writeext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
+			    KSZ9131RN_TXC_DLL_CTRL, val);
+
+	return ret;
+}
+
 static int ksz9131_config(struct phy_device *phydev)
 {
-	/* TBD: Implement Skew values for dts */
+	int ret;
+
+	if (phy_interface_is_rgmii(phydev)) {
+		ret = ksz9131_config_rgmii_delay(phydev);
+		if (ret)
+			return ret;
+	}
 
 	/* add an option to disable the gigabit feature of this PHY */
 	if (env_get("disable_giga")) {