net: phy: microchip_t1: add lan87xx_config_rgmii_delay for lan87xx phy
authorYuiko Oshino <yuiko.oshino@microchip.com>
Mon, 1 Nov 2021 16:21:19 +0000 (12:21 -0400)
committerJakub Kicinski <kuba@kernel.org>
Wed, 3 Nov 2021 00:16:27 +0000 (17:16 -0700)
Add a function to initialize phy rgmii delay according to phydev->interface.

Signed-off-by: Yuiko Oshino <yuiko.oshino@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20211101162119.29275-1-yuiko.oshino@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/microchip_t1.c

index a4de3d2..bc50224 100644 (file)
 #define LAN87XX_MASK_LINK_UP                    (0x0004)
 #define LAN87XX_MASK_LINK_DOWN                  (0x0002)
 
+/* MISC Control 1 Register */
+#define LAN87XX_CTRL_1                          (0x11)
+#define LAN87XX_MASK_RGMII_TXC_DLY_EN           (0x4000)
+#define LAN87XX_MASK_RGMII_RXC_DLY_EN           (0x2000)
+
 /* phyaccess nested types */
 #define        PHYACC_ATTR_MODE_READ           0
 #define        PHYACC_ATTR_MODE_WRITE          1
@@ -112,6 +117,43 @@ static int access_ereg_modify_changed(struct phy_device *phydev,
        return rc;
 }
 
+static int lan87xx_config_rgmii_delay(struct phy_device *phydev)
+{
+       int rc;
+
+       if (!phy_interface_is_rgmii(phydev))
+               return 0;
+
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                        PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, 0);
+       if (rc < 0)
+               return rc;
+
+       switch (phydev->interface) {
+       case PHY_INTERFACE_MODE_RGMII:
+               rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
+               rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
+               rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
+               rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+               rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
+               rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+               rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
+               rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
+               break;
+       default:
+               return 0;
+       }
+
+       return access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
+                          PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, rc);
+}
+
 static int lan87xx_phy_init(struct phy_device *phydev)
 {
        static const struct access_ereg_val init[] = {
@@ -185,7 +227,7 @@ static int lan87xx_phy_init(struct phy_device *phydev)
                        return rc;
        }
 
-       return 0;
+       return lan87xx_config_rgmii_delay(phydev);
 }
 
 static int lan87xx_phy_config_intr(struct phy_device *phydev)