net: phy: bcm7xxx: Implement EGPHY workaround for 7278
authorFlorian Fainelli <f.fainelli@gmail.com>
Fri, 20 Jan 2017 20:36:34 +0000 (12:36 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sun, 22 Jan 2017 21:58:31 +0000 (16:58 -0500)
Implement the HW design team recommended workaround in for 7278. Since
the GPHY now returns its revision information in MII_PHYS_ID[23] we need
to check whether the revision provided in flags is 0 or not.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/bcm7xxx.c

index fb11927de0ff4655a8cb2b788f4fddc7ab873901..aa01020ab1b9e0ba82e3776ab7e16d491443a260 100644 (file)
@@ -167,6 +167,31 @@ static int bcm7xxx_28nm_e0_plus_afe_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int bcm7xxx_28nm_a0_patch_afe_config_init(struct phy_device *phydev)
+{
+       /* +1 RC_CAL codes for RL centering for both LT and HT conditions */
+       bcm_phy_write_misc(phydev, AFE_RXCONFIG_2, 0xd003);
+
+       /* Cut master bias current by 2% to compensate for RC_CAL offset */
+       bcm_phy_write_misc(phydev, DSP_TAP10, 0x791b);
+
+       /* Improve hybrid leakage */
+       bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x10e3);
+
+       /* Change rx_on_tune 8 to 0xf */
+       bcm_phy_write_misc(phydev, 0x21, 0x2, 0x87f6);
+
+       /* Change 100Tx EEE bandwidth */
+       bcm_phy_write_misc(phydev, 0x22, 0x2, 0x017d);
+
+       /* Enable ffe zero detection for Vitesse interoperability */
+       bcm_phy_write_misc(phydev, 0x26, 0x2, 0x0015);
+
+       r_rc_cal_reset(phydev);
+
+       return 0;
+}
+
 static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
 {
        u8 rev = PHY_BRCM_7XXX_REV(phydev->dev_flags);
@@ -174,6 +199,12 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
        u8 count;
        int ret = 0;
 
+       /* Newer devices have moved the revision information back into a
+        * standard location in MII_PHYS_ID[23]
+        */
+       if (rev == 0)
+               rev = phydev->phy_id & ~phydev->drv->phy_id_mask;
+
        pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n",
                     phydev_name(phydev), phydev->drv->name, rev, patch);
 
@@ -197,6 +228,9 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
        case 0x10:
                ret = bcm7xxx_28nm_e0_plus_afe_config_init(phydev);
                break;
+       case 0x01:
+               ret = bcm7xxx_28nm_a0_patch_afe_config_init(phydev);
+               break;
        default:
                break;
        }