diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/broadcom.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index bddf4a42ae68..74914335f72c 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #define BRCM_PHY_MODEL(phydev) \ | 25 | #define BRCM_PHY_MODEL(phydev) \ |
26 | ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) | 26 | ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) |
27 | 27 | ||
28 | #define BRCM_PHY_REV(phydev) \ | ||
29 | ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask)) | ||
30 | |||
28 | 31 | ||
29 | #define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */ | 32 | #define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */ |
30 | #define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */ | 33 | #define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */ |
@@ -95,11 +98,16 @@ | |||
95 | #define BCM_LED_SRC_OFF 0xe /* Tied high */ | 98 | #define BCM_LED_SRC_OFF 0xe /* Tied high */ |
96 | #define BCM_LED_SRC_ON 0xf /* Tied low */ | 99 | #define BCM_LED_SRC_ON 0xf /* Tied low */ |
97 | 100 | ||
101 | |||
98 | /* | 102 | /* |
99 | * BCM5482: Shadow registers | 103 | * BCM5482: Shadow registers |
100 | * Shadow values go into bits [14:10] of register 0x1c to select a shadow | 104 | * Shadow values go into bits [14:10] of register 0x1c to select a shadow |
101 | * register to access. | 105 | * register to access. |
102 | */ | 106 | */ |
107 | /* 00101: Spare Control Register 3 */ | ||
108 | #define BCM54XX_SHD_SCR3 0x05 | ||
109 | #define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001 | ||
110 | |||
103 | #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ | 111 | #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ |
104 | /* LED3 / ~LINKSPD[2] selector */ | 112 | /* LED3 / ~LINKSPD[2] selector */ |
105 | #define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4) | 113 | #define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4) |
@@ -112,6 +120,7 @@ | |||
112 | #define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */ | 120 | #define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */ |
113 | #define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */ | 121 | #define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */ |
114 | 122 | ||
123 | |||
115 | /* | 124 | /* |
116 | * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17) | 125 | * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17) |
117 | */ | 126 | */ |
@@ -309,6 +318,37 @@ error: | |||
309 | return err ? err : err2; | 318 | return err ? err : err2; |
310 | } | 319 | } |
311 | 320 | ||
321 | static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) | ||
322 | { | ||
323 | u32 val, orig; | ||
324 | |||
325 | /* Abort if we are using an untested phy. */ | ||
326 | if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || | ||
327 | BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) | ||
328 | return; | ||
329 | |||
330 | val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3); | ||
331 | if (val < 0) | ||
332 | return; | ||
333 | |||
334 | orig = val; | ||
335 | |||
336 | if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { | ||
337 | if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || | ||
338 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && | ||
339 | BRCM_PHY_REV(phydev) >= 0x3) { | ||
340 | /* Here, bit 0 _disables_ CLK125 when set */ | ||
341 | val |= BCM54XX_SHD_SCR3_DEF_CLK125; | ||
342 | } else { | ||
343 | /* Here, bit 0 _enables_ CLK125 when set */ | ||
344 | val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | if (orig != val) | ||
349 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val); | ||
350 | } | ||
351 | |||
312 | static int bcm54xx_config_init(struct phy_device *phydev) | 352 | static int bcm54xx_config_init(struct phy_device *phydev) |
313 | { | 353 | { |
314 | int reg, err; | 354 | int reg, err; |
@@ -336,6 +376,9 @@ static int bcm54xx_config_init(struct phy_device *phydev) | |||
336 | (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) | 376 | (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) |
337 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); | 377 | bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); |
338 | 378 | ||
379 | if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) | ||
380 | bcm54xx_adjust_rxrefclk(phydev); | ||
381 | |||
339 | bcm54xx_phydsp_config(phydev); | 382 | bcm54xx_phydsp_config(phydev); |
340 | 383 | ||
341 | return 0; | 384 | return 0; |