Browse Source

net: phy: Add AFE settings to the Broadcom Cygnus phy

Added the AFE (Analog Front End) settings for stability to the
Broadcom Cygnus phy. This improves the time take to perform
auto negotiation.

Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Arun Parameswaran 6 years ago
parent
commit
d7e8ac6f45
1 changed files with 63 additions and 1 deletions
  1. 63 1
      drivers/net/phy/broadcom.c

+ 63 - 1
drivers/net/phy/broadcom.c

@@ -30,6 +30,29 @@
 #define MIIM_BCM54XX_EXP_SEL_SSD	0x0e00	/* Secondary SerDes select */
 #define MIIM_BCM54XX_EXP_SEL_ER		0x0f00	/* Expansion register select */
 
+#define MIIM_BCM_AUXCNTL_SHDWSEL_MISC	0x0007
+#define MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN	0x0800
+
+#define MIIM_BCM_CHANNEL_WIDTH    0x2000
+
+static void bcm_phy_write_misc(struct phy_device *phydev,
+			       u16 reg, u16 chl, u16 value)
+{
+	int reg_val;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL,
+		  MIIM_BCM_AUXCNTL_SHDWSEL_MISC);
+
+	reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL);
+	reg_val |= MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, reg_val);
+
+	reg_val = (chl * MIIM_BCM_CHANNEL_WIDTH) | reg;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, reg_val);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA, value);
+}
+
 /* Broadcom BCM5461S */
 static int bcm5461_config(struct phy_device *phydev)
 {
@@ -152,11 +175,50 @@ static int bcm_cygnus_startup(struct phy_device *phydev)
 	return genphy_parse_link(phydev);
 }
 
+static void bcm_cygnus_afe(struct phy_device *phydev)
+{
+	/* ensures smdspclk is enabled */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, 0x0c30);
+
+	/* AFE_VDAC_ICTRL_0 bit 7:4 Iq=1100 for 1g 10bt, normal modes */
+	bcm_phy_write_misc(phydev, 0x39, 0x01, 0xA7C8);
+
+	/* AFE_HPF_TRIM_OTHERS bit11=1, short cascode for all modes*/
+	bcm_phy_write_misc(phydev, 0x3A, 0x00, 0x0803);
+
+	/* AFE_TX_CONFIG_1 bit 7:4 Iq=1100 for test modes */
+	bcm_phy_write_misc(phydev, 0x3A, 0x01, 0xA740);
+
+	/* AFE TEMPSEN_OTHERS rcal_HT, rcal_LT 10000 */
+	bcm_phy_write_misc(phydev, 0x3A, 0x03, 0x8400);
+
+	/* AFE_FUTURE_RSV bit 2:0 rccal <2:0>=100 */
+	bcm_phy_write_misc(phydev, 0x3B, 0x00, 0x0004);
+
+	/* Adjust bias current trim to overcome digital offSet */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x02);
+
+	/* make rcal=100, since rdb default is 000 */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B1);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010);
+
+	/* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010);
+
+	/* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0000);
+}
+
 static int bcm_cygnus_config(struct phy_device *phydev)
 {
 	genphy_config_aneg(phydev);
-
 	phy_reset(phydev);
+	/* AFE settings for PHY stability */
+	bcm_cygnus_afe(phydev);
+	/* Forcing aneg after applying the AFE settings */
+	genphy_restart_aneg(phydev);
 
 	return 0;
 }