]> git.sur5r.net Git - u-boot/blobdiff - drivers/net/phy/marvell.c
ARM: UniPhier: optimize kicking secondary CPUs code
[u-boot] / drivers / net / phy / marvell.c
index d2ecadc8905862dc75999381ae7fec66bc7daa78..9437c3bbccd3bdc1695441673c289cc975445751 100644 (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,
 };