Commit 35fa0dda0ccee8075b1ef8922e930d5dcdea9f5e

Authored by Hao Zhang
Committed by Tom Rini
1 parent 4de96c79ad

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 };