diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2009-11-02 09:32:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-03 02:39:13 -0500 |
commit | c704dc23cac0e433796bfe0a1fe2f1a64da11ac7 (patch) | |
tree | 8fad42adbda6d2911dcb3907b20d440625d292b7 /drivers/net/phy/broadcom.c | |
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/broadcom.c')
-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 74914335f72c..7b10495fe8fb 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
@@ -107,6 +107,11 @@ | |||
107 | /* 00101: Spare Control Register 3 */ | 107 | /* 00101: Spare Control Register 3 */ |
108 | #define BCM54XX_SHD_SCR3 0x05 | 108 | #define BCM54XX_SHD_SCR3 0x05 |
109 | #define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001 | 109 | #define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001 |
110 | #define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002 | ||
111 | |||
112 | /* 01010: Auto Power-Down */ | ||
113 | #define BCM54XX_SHD_APD 0x0a | ||
114 | #define BCM54XX_SHD_APD_EN 0x0020 | ||
110 | 115 | ||
111 | #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ | 116 | #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ |
112 | /* LED3 / ~LINKSPD[2] selector */ | 117 | /* LED3 / ~LINKSPD[2] selector */ |
@@ -321,9 +326,11 @@ error: | |||
321 | static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) | 326 | static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) |
322 | { | 327 | { |
323 | u32 val, orig; | 328 | u32 val, orig; |
329 | bool clk125en = true; | ||
324 | 330 | ||
325 | /* Abort if we are using an untested phy. */ | 331 | /* Abort if we are using an untested phy. */ |
326 | if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || | 332 | if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 || |
333 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || | ||
327 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) | 334 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) |
328 | return; | 335 | return; |
329 | 336 | ||
@@ -333,20 +340,45 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) | |||
333 | 340 | ||
334 | orig = val; | 341 | orig = val; |
335 | 342 | ||
336 | if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { | 343 | if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || |
337 | if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || | 344 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && |
338 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && | 345 | BRCM_PHY_REV(phydev) >= 0x3) { |
339 | BRCM_PHY_REV(phydev) >= 0x3) { | 346 | /* |
340 | /* Here, bit 0 _disables_ CLK125 when set */ | 347 | * Here, bit 0 _disables_ CLK125 when set. |
341 | val |= BCM54XX_SHD_SCR3_DEF_CLK125; | 348 | * This bit is set by default. |
342 | } else { | 349 | */ |
350 | clk125en = false; | ||
351 | } else { | ||
352 | if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { | ||
343 | /* Here, bit 0 _enables_ CLK125 when set */ | 353 | /* Here, bit 0 _enables_ CLK125 when set */ |
344 | val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; | 354 | val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; |
355 | clk125en = false; | ||
345 | } | 356 | } |
346 | } | 357 | } |
347 | 358 | ||
359 | if (clk125en == false || | ||
360 | (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) | ||
361 | val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS; | ||
362 | else | ||
363 | val |= BCM54XX_SHD_SCR3_DLLAPD_DIS; | ||
364 | |||
348 | if (orig != val) | 365 | if (orig != val) |
349 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val); | 366 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val); |
367 | |||
368 | val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD); | ||
369 | if (val < 0) | ||
370 | return; | ||
371 | |||
372 | orig = val; | ||
373 | |||
374 | if (clk125en == false || | ||
375 | (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) | ||
376 | val |= BCM54XX_SHD_APD_EN; | ||
377 | else | ||
378 | val &= ~BCM54XX_SHD_APD_EN; | ||
379 | |||
380 | if (orig != val) | ||
381 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val); | ||
350 | } | 382 | } |
351 | 383 | ||
352 | static int bcm54xx_config_init(struct phy_device *phydev) | 384 | static int bcm54xx_config_init(struct phy_device *phydev) |
@@ -376,7 +408,8 @@ static int bcm54xx_config_init(struct phy_device *phydev) | |||
376 | (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) | 408 | (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) |
377 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); | 409 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); |
378 | 410 | ||
379 | if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) | 411 | if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) || |
412 | (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) | ||
380 | bcm54xx_adjust_rxrefclk(phydev); | 413 | bcm54xx_adjust_rxrefclk(phydev); |
381 | 414 | ||
382 | bcm54xx_phydsp_config(phydev); | 415 | bcm54xx_phydsp_config(phydev); |