aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/broadcom.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2009-11-02 09:28:04 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-03 02:39:09 -0500
commit47b1b53b41d63f27b308981fde307d415e514431 (patch)
treea0e9a1b9ad067f73785325622aaca6322a7f021e /drivers/net/phy/broadcom.c
parent303fc9218246a748304c005e629d658927cf12d0 (diff)
broadcom: Isolate phy dsp accesses
This patch consolidates the code that requires the SMDSP clock to be enabled into a single function that (hopefully) makes the dependency obvious. 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.c90
1 files changed, 42 insertions, 48 deletions
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index f81e53222230..9e574ceacf43 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -237,53 +237,78 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
237 return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); 237 return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
238} 238}
239 239
240/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
240static int bcm50610_a0_workaround(struct phy_device *phydev) 241static int bcm50610_a0_workaround(struct phy_device *phydev)
241{ 242{
242 int err; 243 int err;
243 244
244 err = bcm54xx_auxctl_write(phydev,
245 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
246 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
247 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
248 if (err < 0)
249 return err;
250
251 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08, 245 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
252 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ | 246 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ |
253 MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE); 247 MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE);
254 if (err < 0) 248 if (err < 0)
255 goto error; 249 return err;
256 250
257 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0, 251 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0,
258 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN | 252 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
259 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF); 253 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
260 if (err < 0) 254 if (err < 0)
261 goto error; 255 return err;
262 256
263 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3, 257 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3,
264 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ); 258 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
265 if (err < 0) 259 if (err < 0)
266 goto error; 260 return err;
267 261
268 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, 262 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75,
269 MII_BCM54XX_EXP_EXP75_VDACCTRL); 263 MII_BCM54XX_EXP_EXP75_VDACCTRL);
270 if (err < 0) 264 if (err < 0)
271 goto error; 265 return err;
272 266
273 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96, 267 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96,
274 MII_BCM54XX_EXP_EXP96_MYST); 268 MII_BCM54XX_EXP_EXP96_MYST);
275 if (err < 0) 269 if (err < 0)
276 goto error; 270 return err;
277 271
278 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97, 272 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97,
279 MII_BCM54XX_EXP_EXP97_MYST); 273 MII_BCM54XX_EXP_EXP97_MYST);
280 274
275 return err;
276}
277
278static int bcm54xx_phydsp_config(struct phy_device *phydev)
279{
280 int err, err2;
281
282 /* Enable the SMDSP clock */
283 err = bcm54xx_auxctl_write(phydev,
284 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
285 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
286 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
287 if (err < 0)
288 return err;
289
290 if (phydev->drv->phy_id == PHY_ID_BCM50610)
291 err = bcm50610_a0_workaround(phydev);
292
293 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
294 int val;
295
296 val = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
297 if (val < 0)
298 goto error;
299
300 val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
301 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, val);
302 }
303
281error: 304error:
282 bcm54xx_auxctl_write(phydev, 305 /* Disable the SMDSP clock */
283 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL, 306 err2 = bcm54xx_auxctl_write(phydev,
284 MII_BCM54XX_AUXCTL_ACTL_TX_6DB); 307 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
308 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
285 309
286 return err; 310 /* Return the first error reported. */
311 return err ? err : err2;
287} 312}
288 313
289static int bcm54xx_config_init(struct phy_device *phydev) 314static int bcm54xx_config_init(struct phy_device *phydev)
@@ -308,38 +333,7 @@ static int bcm54xx_config_init(struct phy_device *phydev)
308 if (err < 0) 333 if (err < 0)
309 return err; 334 return err;
310 335
311 if (phydev->drv->phy_id == PHY_ID_BCM50610) { 336 bcm54xx_phydsp_config(phydev);
312 err = bcm50610_a0_workaround(phydev);
313 if (err < 0)
314 return err;
315 }
316
317 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
318 int err2;
319
320 err = bcm54xx_auxctl_write(phydev,
321 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
322 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
323 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
324 if (err < 0)
325 return err;
326
327 reg = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
328 if (reg < 0)
329 goto error;
330
331 reg |= MII_BCM54XX_EXP_EXP75_CM_OSC;
332 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, reg);
333
334error:
335 err2 = bcm54xx_auxctl_write(phydev,
336 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
337 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
338 if (err)
339 return err;
340 if (err2)
341 return err2;
342 }
343 337
344 return 0; 338 return 0;
345} 339}