diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2009-11-02 14:32:12 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-02 23:39:13 -0800 |
commit | c704dc23cac0e433796bfe0a1fe2f1a64da11ac7 (patch) | |
tree | 8fad42adbda6d2911dcb3907b20d440625d292b7 /drivers/net/phy | |
parent | 32e5a8d651c0dbb02bf82ca954206282e44c4b11 (diff) |
tg3 / broadcom: Add APD support for GPHYs
This patch adds an RXC auto power-down feature to the code that supports
the gphys.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/broadcom.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 74914335f72..7b10495fe8f 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -107,6 +107,11 @@ /* 00101: Spare Control Register 3 */ #define BCM54XX_SHD_SCR3 0x05 #define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001 +#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002 + +/* 01010: Auto Power-Down */ +#define BCM54XX_SHD_APD 0x0a +#define BCM54XX_SHD_APD_EN 0x0020 #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ /* LED3 / ~LINKSPD[2] selector */ @@ -321,9 +326,11 @@ error: static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) { u32 val, orig; + bool clk125en = true; /* Abort if we are using an untested phy. */ - if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || + if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 || + BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) return; @@ -333,20 +340,45 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) orig = val; - if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { - if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || - BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && - BRCM_PHY_REV(phydev) >= 0x3) { - /* Here, bit 0 _disables_ CLK125 when set */ - val |= BCM54XX_SHD_SCR3_DEF_CLK125; - } else { + if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || + BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && + BRCM_PHY_REV(phydev) >= 0x3) { + /* + * Here, bit 0 _disables_ CLK125 when set. + * This bit is set by default. + */ + clk125en = false; + } else { + if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { /* Here, bit 0 _enables_ CLK125 when set */ val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; + clk125en = false; } } + if (clk125en == false || + (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) + val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS; + else + val |= BCM54XX_SHD_SCR3_DLLAPD_DIS; + if (orig != val) bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val); + + val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD); + if (val < 0) + return; + + orig = val; + + if (clk125en == false || + (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) + val |= BCM54XX_SHD_APD_EN; + else + val &= ~BCM54XX_SHD_APD_EN; + + if (orig != val) + bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val); } static int bcm54xx_config_init(struct phy_device *phydev) @@ -376,7 +408,8 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); - if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) + if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) || + (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); bcm54xx_phydsp_config(phydev); |