summaryrefslogtreecommitdiff
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-05-30 14:45:06 +0200
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-05-30 14:45:06 +0200
commita19b0dd62d7b8efc658fa1aa685ff5665878f3ee (patch)
tree1fadf0fb3da83203ba28f209ec99e1b33e03f4d5 /drivers/net/phy
parent60985bba58e7695dac1fddae8cdbb62d8cfd1254 (diff)
parenta71d45d706a5b51c348160163b6c159632273fed (diff)
downloadu-boot-imx-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.zip
u-boot-imx-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.tar.gz
u-boot-imx-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.tar.bz2
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Conflicts: common/cmd_fpga.c drivers/usb/host/ohci-at91.c
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/teranetics.c16
-rw-r--r--drivers/net/phy/vitesse.c67
2 files changed, 81 insertions, 2 deletions
diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c
index 78447b7..84ce736 100644
--- a/drivers/net/phy/teranetics.c
+++ b/drivers/net/phy/teranetics.c
@@ -34,9 +34,21 @@ int tn2020_config(struct phy_device *phydev)
unsigned short restart_an = (MDIO_AN_CTRL1_RESTART |
MDIO_AN_CTRL1_ENABLE |
MDIO_AN_CTRL1_XNP);
+ u8 phy_hwversion;
- phy_write(phydev, 30, 93, 2);
- phy_write(phydev, MDIO_MMD_AN, MDIO_CTRL1, restart_an);
+ /*
+ * bit 15:12 of register 30.32 indicates PHY hardware
+ * version. It can be used to distinguish TN80xx from
+ * TN2020. TN2020 needs write 0x2 to 30.93, but TN80xx
+ * needs 0x1.
+ */
+ phy_hwversion = (phy_read(phydev, 30, 32) >> 12) & 0xf;
+ if (phy_hwversion <= 3) {
+ phy_write(phydev, 30, 93, 2);
+ phy_write(phydev, MDIO_MMD_AN, MDIO_CTRL1, restart_an);
+ } else {
+ phy_write(phydev, 30, 93, 1);
+ }
}
return 0;
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 6c5cb99..c283d82 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -48,6 +48,19 @@
#define MIIM_VSC8601_SKEW_CTRL 0x1c
#define PHY_EXT_PAGE_ACCESS 0x1f
+#define PHY_EXT_PAGE_ACCESS_GENERAL 0x10
+#define PHY_EXT_PAGE_ACCESS_EXTENDED3 0x3
+
+/* Vitesse VSC8574 control register */
+#define MIIM_VSC8574_MAC_SERDES_CON 0x10
+#define MIIM_VSC8574_MAC_SERDES_ANEG 0x80
+#define MIIM_VSC8574_GENERAL18 0x12
+#define MIIM_VSC8574_GENERAL19 0x13
+
+/* Vitesse VSC8574 gerenal purpose register 18 */
+#define MIIM_VSC8574_18G_SGMII 0x80f0
+#define MIIM_VSC8574_18G_QSGMII 0x80e0
+#define MIIM_VSC8574_18G_CMDSTAT 0x8000
/* CIS8201 */
static int vitesse_config(struct phy_device *phydev)
@@ -145,6 +158,49 @@ static int vsc8601_config(struct phy_device *phydev)
return 0;
}
+static int vsc8574_config(struct phy_device *phydev)
+{
+ u32 val;
+ /* configure regiser 19G for MAC */
+ phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+ PHY_EXT_PAGE_ACCESS_GENERAL);
+
+ val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19);
+ if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
+ /* set bit 15:14 to '01' for QSGMII mode */
+ val = (val & 0x3fff) | (1 << 14);
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MIIM_VSC8574_GENERAL19, val);
+ /* Enable 4 ports MAC QSGMII */
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
+ MIIM_VSC8574_18G_QSGMII);
+ } else {
+ /* set bit 15:14 to '00' for SGMII mode */
+ val = val & 0x3fff;
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19, val);
+ /* Enable 4 ports MAC SGMII */
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
+ MIIM_VSC8574_18G_SGMII);
+ }
+ val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
+ /* When bit 15 is cleared the command has completed */
+ while (val & MIIM_VSC8574_18G_CMDSTAT)
+ val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
+
+ /* Enable Serdes Auto-negotiation */
+ phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+ PHY_EXT_PAGE_ACCESS_EXTENDED3);
+ val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON);
+ val = val | MIIM_VSC8574_MAC_SERDES_ANEG;
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON, val);
+
+ phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+
+ genphy_config_aneg(phydev);
+
+ return 0;
+}
+
static struct phy_driver VSC8211_driver = {
.name = "Vitesse VSC8211",
.uid = 0xfc4b0,
@@ -185,6 +241,16 @@ static struct phy_driver VSC8234_driver = {
.shutdown = &genphy_shutdown,
};
+static struct phy_driver VSC8574_driver = {
+ .name = "Vitesse VSC8574",
+ .uid = 0x704a0,
+ .mask = 0xffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &vsc8574_config,
+ .startup = &vitesse_startup,
+ .shutdown = &genphy_shutdown,
+};
+
static struct phy_driver VSC8601_driver = {
.name = "Vitesse VSC8601",
.uid = 0x70420,
@@ -244,6 +310,7 @@ int phy_vitesse_init(void)
phy_register(&VSC8244_driver);
phy_register(&VSC8211_driver);
phy_register(&VSC8221_driver);
+ phy_register(&VSC8574_driver);
phy_register(&VSC8662_driver);
phy_register(&cis8201_driver);
phy_register(&cis8204_driver);