Merge git://git.denx.de/u-boot-marvell
[oweals/u-boot.git] / drivers / net / phy / broadcom.c
index 9871cc3edd7c4df6f688bff425a73814fe8eaa85..3399fd236625727a5f120158f0dad6494aa44c57 100644 (file)
@@ -1,12 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Broadcom PHY drivers
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * Copyright 2010-2011 Freescale Semiconductor, Inc.
  * author Andy Fleming
  */
-#include <config.h>
 #include <common.h>
 #include <phy.h>
 
 #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 +173,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;
 }