Commit 35fa0dda0ccee8075b1ef8922e930d5dcdea9f5e
Committed by
Tom Rini
1 parent
4de96c79ad
Exists in
v2017.01-smarct4x
and in
37 other branches
net: phy: marvell: add errata w/a for 88E151* chips
As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512/88E1514 Rev A0, Errata Section 3.1 Marvell PHY has an errata which requires that certain registers get written in order to restart autonegotiation. Signed-off-by: Hao Zhang <hzhang@ti.com> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> Reviewed-by: Stefan Roese <sr@denx.de>
Showing 1 changed file with 52 additions and 1 deletions Side-by-side Diff
drivers/net/phy/marvell.c
... | ... | @@ -276,6 +276,57 @@ |
276 | 276 | return 0; |
277 | 277 | } |
278 | 278 | |
279 | +/** | |
280 | + * m88e1518_phy_writebits - write bits to a register | |
281 | + */ | |
282 | +void m88e1518_phy_writebits(struct phy_device *phydev, | |
283 | + u8 reg_num, u16 offset, u16 len, u16 data) | |
284 | +{ | |
285 | + u16 reg, mask; | |
286 | + | |
287 | + if ((len + offset) >= 16) | |
288 | + mask = 0 - (1 << offset); | |
289 | + else | |
290 | + mask = (1 << (len + offset)) - (1 << offset); | |
291 | + | |
292 | + reg = phy_read(phydev, MDIO_DEVAD_NONE, reg_num); | |
293 | + | |
294 | + reg &= ~mask; | |
295 | + reg |= data << offset; | |
296 | + | |
297 | + phy_write(phydev, MDIO_DEVAD_NONE, reg_num, reg); | |
298 | +} | |
299 | + | |
300 | +static int m88e1518_config(struct phy_device *phydev) | |
301 | +{ | |
302 | + /* | |
303 | + * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 | |
304 | + * /88E1514 Rev A0, Errata Section 3.1 | |
305 | + */ | |
306 | + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { | |
307 | + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); /* page 0xff */ | |
308 | + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B); | |
309 | + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144); | |
310 | + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28); | |
311 | + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146); | |
312 | + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233); | |
313 | + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D); | |
314 | + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C); | |
315 | + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159); | |
316 | + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); /* reg page 0 */ | |
317 | + phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); /* reg page 18 */ | |
318 | + /* Write HWCFG_MODE = SGMII to Copper */ | |
319 | + m88e1518_phy_writebits(phydev, 20, 0, 3, 1); | |
320 | + | |
321 | + /* Phy reset */ | |
322 | + m88e1518_phy_writebits(phydev, 20, 15, 1, 1); | |
323 | + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); /* reg page 18 */ | |
324 | + udelay(100); | |
325 | + } | |
326 | + | |
327 | + return m88e1111s_config(phydev); | |
328 | +} | |
329 | + | |
279 | 330 | /* Marvell 88E1118 */ |
280 | 331 | static int m88e1118_config(struct phy_device *phydev) |
281 | 332 | { |
... | ... | @@ -493,7 +544,7 @@ |
493 | 544 | .uid = 0x1410dd1, |
494 | 545 | .mask = 0xffffff0, |
495 | 546 | .features = PHY_GBIT_FEATURES, |
496 | - .config = &m88e1111s_config, | |
547 | + .config = &m88e1518_config, | |
497 | 548 | .startup = &m88e1011s_startup, |
498 | 549 | .shutdown = &genphy_shutdown, |
499 | 550 | }; |