X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fphy%2Fmarvell.c;h=eab15585c31a9d160b9fb05f4e783474821db438;hb=e6e3faa5c2da591cd3e0f2047a74cfc832e7b738;hp=d2ecadc8905862dc75999381ae7fec66bc7daa78;hpb=1a4596601fd395f3afb8f82f3f840c5e00bdd57a;p=oweals%2Fu-boot.git diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d2ecadc890..eab15585c3 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -276,6 +276,85 @@ 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 + */ + + /* EEE initialization */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); + 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); + + /* SGMII-to-Copper mode initialization */ + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + /* Select page 18 */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); + + /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ + m88e1518_phy_writebits(phydev, 20, 0, 3, 1); + + /* PHY reset is necessary after changing MODE[2:0] */ + m88e1518_phy_writebits(phydev, 20, 15, 1, 1); + + /* Reset page selection */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); + + udelay(100); + } + + return m88e1111s_config(phydev); +} + +/* Marvell 88E1510 */ +static int m88e1510_config(struct phy_device *phydev) +{ + /* Select page 3 */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 3); + + /* Enable INTn output on LED[2] */ + m88e1518_phy_writebits(phydev, 18, 7, 1, 1); + + /* Configure LEDs */ + m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */ + m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */ + + /* Reset page selection */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); + + return m88e1518_config(phydev); +} + /* Marvell 88E1118 */ static int m88e1118_config(struct phy_device *phydev) { @@ -488,12 +567,22 @@ static struct phy_driver M88E1149S_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver M88E1510_driver = { + .name = "Marvell 88E1510", + .uid = 0x1410dd0, + .mask = 0xffffff0, + .features = PHY_GBIT_FEATURES, + .config = &m88e1510_config, + .startup = &m88e1011s_startup, + .shutdown = &genphy_shutdown, +}; + static struct phy_driver M88E1518_driver = { .name = "Marvell 88E1518", .uid = 0x1410dd1, .mask = 0xffffff0, .features = PHY_GBIT_FEATURES, - .config = &m88e1111s_config, + .config = &m88e1518_config, .startup = &m88e1011s_startup, .shutdown = &genphy_shutdown, }; @@ -518,6 +607,7 @@ int phy_marvell_init(void) phy_register(&M88E1118R_driver); phy_register(&M88E1111S_driver); phy_register(&M88E1011S_driver); + phy_register(&M88E1510_driver); phy_register(&M88E1518_driver); return 0;