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>
This commit is contained in:
Hao Zhang 2014-10-30 18:59:43 +02:00 committed by Tom Rini
parent 4de96c79ad
commit 35fa0dda0c

View file

@ -276,6 +276,57 @@ static int m88e1111s_config(struct phy_device *phydev)
return 0;
}
/**
* m88e1518_phy_writebits - write bits to a register
*/
void m88e1518_phy_writebits(struct phy_device *phydev,
u8 reg_num, u16 offset, u16 len, u16 data)
{
u16 reg, mask;
if ((len + offset) >= 16)
mask = 0 - (1 << offset);
else
mask = (1 << (len + offset)) - (1 << offset);
reg = phy_read(phydev, MDIO_DEVAD_NONE, reg_num);
reg &= ~mask;
reg |= data << offset;
phy_write(phydev, MDIO_DEVAD_NONE, reg_num, reg);
}
static int m88e1518_config(struct phy_device *phydev)
{
/*
* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
* /88E1514 Rev A0, Errata Section 3.1
*/
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); /* page 0xff */
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); /* reg page 0 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); /* reg page 18 */
/* Write HWCFG_MODE = SGMII to Copper */
m88e1518_phy_writebits(phydev, 20, 0, 3, 1);
/* Phy reset */
m88e1518_phy_writebits(phydev, 20, 15, 1, 1);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); /* reg page 18 */
udelay(100);
}
return m88e1111s_config(phydev);
}
/* Marvell 88E1118 */
static int m88e1118_config(struct phy_device *phydev)
{
@ -493,7 +544,7 @@ static struct phy_driver M88E1518_driver = {
.uid = 0x1410dd1,
.mask = 0xffffff0,
.features = PHY_GBIT_FEATURES,
.config = &m88e1111s_config,
.config = &m88e1518_config,
.startup = &m88e1011s_startup,
.shutdown = &genphy_shutdown,
};