Port from tsec.c file to add support for cis8201, cis8204, dm9161,
dp83865, ksz804, lxt971, rtl8211b.

Signed-off-by: Mingkai Hu <mingkai...@freescale.com>
---
 drivers/net/fsl_phy.c |  356 ++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/net/fsl_phy.h |   57 ++++++++
 drivers/net/tsec.c    |   24 ++++
 3 files changed, 436 insertions(+), 1 deletions(-)

diff --git a/drivers/net/fsl_phy.c b/drivers/net/fsl_phy.c
index ad9d65e..3a8ebbc 100644
--- a/drivers/net/fsl_phy.c
+++ b/drivers/net/fsl_phy.c
@@ -457,6 +457,211 @@ static int bcm5482_startup(struct mii_info *mii_info)
        return 0;
 }
 
+/* CIS8201 */
+static int cis8201_config(struct mii_info *mii_info)
+{
+       /* Override PHY config settings */
+       tsec_phy_write(mii_info, 0, MIIM_CIS8201_AUX_CONSTAT,
+                       MIIM_CIS8201_AUXCONSTAT_INIT);
+       /* Set up the interface mode */
+       tsec_phy_write(mii_info, 0, MIIM_CIS8201_EXT_CON1,
+                       MIIM_CIS8201_EXTCON1_INIT);
+       tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT);
+
+       return 0;
+}
+
+static int cis8201_parse_status(struct mii_info *mii_info)
+{
+       int speed;
+       int mii_reg;
+
+       mii_reg = tsec_phy_read(mii_info, 0, MIIM_CIS8201_AUX_CONSTAT);
+
+       if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX)
+               mii_info->duplex = DUPLEX_FULL;
+       else
+               mii_info->duplex = DUPLEX_HALF;
+
+       speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED;
+       switch (speed) {
+       case MIIM_CIS8201_AUXCONSTAT_GBIT:
+               mii_info->speed = SPEED_1000;
+               break;
+       case MIIM_CIS8201_AUXCONSTAT_100:
+               mii_info->speed = SPEED_100;
+               break;
+       default:
+               mii_info->speed = SPEED_10;
+               break;
+       }
+
+       return 0;
+}
+
+static int cis8201_startup(struct mii_info *mii_info)
+{
+       genphy_update_link(mii_info);
+       cis8201_parse_status(mii_info);
+
+       return 0;
+}
+
+/* CIS8204 */
+static int __cis8204_fixled(struct mii_info *mii_info)
+{
+       return 0;
+}
+
+int cis8204_fixled(struct mii_info *mii_info)
+       __attribute__((weak, alias("__cis8204_fixled")));
+
+static int cis8204_config(struct mii_info *mii_info)
+{
+       /* Override PHY config settings */
+       tsec_phy_write(mii_info, 0, MIIM_CIS8201_AUX_CONSTAT,
+                       MIIM_CIS8201_AUXCONSTAT_INIT);
+       /* Configure some basic stuff */
+       tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT);
+
+       cis8204_fixled(mii_info);
+
+       if (mii_info->flags & TSEC_REDUCED)
+               tsec_phy_write(mii_info, 0, MIIM_CIS8204_EPHY_CON,
+                               MIIM_CIS8204_EPHYCON_INIT |
+                               MIIM_CIS8204_EPHYCON_RGMII);
+       else
+               tsec_phy_write(mii_info, 0, MIIM_CIS8204_EPHY_CON,
+                               MIIM_CIS8204_EPHYCON_INIT);
+
+       return 0;
+}
+
+/* Davicom DM9161E */
+static int dm9161_config(struct mii_info *mii_info)
+{
+       tsec_phy_write(mii_info, 0, MII_BMCR, MIIM_DM9161_CR_STOP);
+       /* Do not bypass the scrambler/descrambler */
+       tsec_phy_write(mii_info, 0, MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT);
+       /* Clear 10BTCSR to default */
+       tsec_phy_write(mii_info, 0, MIIM_DM9161_10BTCSR, 
MIIM_DM9161_10BTCSR_INIT);
+
+       tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT);
+       /* Restart Auto Negotiation */
+       tsec_phy_write(mii_info, 0, MII_BMCR, MIIM_DM9161_CR_RSTAN);
+
+       return 0;
+}
+
+static int dm9161_parse_status(struct mii_info *mii_info)
+{
+       int mii_reg;
+
+       mii_reg = tsec_phy_read(mii_info, 0, MIIM_DM9161_SCSR);
+
+       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
+               mii_info->speed = SPEED_100;
+       else
+               mii_info->speed = SPEED_10;
+
+       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
+               mii_info->duplex = DUPLEX_FULL;
+       else
+               mii_info->duplex = DUPLEX_HALF;
+
+       return 0;
+}
+
+static int dm9161_startup(struct mii_info *mii_info)
+{
+       genphy_update_link(mii_info);
+       dm9161_parse_status(mii_info);
+
+       return 0;
+}
+
+/* NatSemi DP83865 */
+static int dp83865_config(struct mii_info *mii_info)
+{
+       return tsec_phy_write(mii_info, 0, MII_BMCR, MIIM_DP83865_CR_INIT);
+}
+
+static int dp83865_parse_status(struct mii_info *mii_info)
+{
+       int mii_reg;
+
+       mii_reg = tsec_phy_read(mii_info, 0, MIIM_DP83865_LANR);
+
+       switch (mii_reg & MIIM_DP83865_SPD_MASK) {
+
+       case MIIM_DP83865_SPD_1000:
+               mii_info->speed = SPEED_1000;
+               break;
+
+       case MIIM_DP83865_SPD_100:
+               mii_info->speed = SPEED_100;
+               break;
+
+       default:
+               mii_info->speed = SPEED_10;
+               break;
+
+       }
+
+       if (mii_reg & MIIM_DP83865_DPX_FULL)
+               mii_info->duplex = DUPLEX_FULL;
+       else
+               mii_info->duplex = DUPLEX_HALF;
+
+       return 0;
+}
+
+static int dp83865_startup(struct mii_info *mii_info)
+{
+       genphy_update_link(mii_info);
+       dp83865_parse_status(mii_info);
+
+       return 0;
+}
+
+/* LXT971 */
+static int lxt971_parse_status(struct mii_info *mii_info)
+{
+       int mii_reg;
+       int speed;
+
+       mii_reg = tsec_phy_read(mii_info, 0, MIIM_LXT971_SR2);
+       speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
+
+       switch (speed) {
+       case MIIM_LXT971_SR2_10HDX:
+               mii_info->speed = SPEED_10;
+               mii_info->duplex = DUPLEX_HALF;
+               break;
+       case MIIM_LXT971_SR2_10FDX:
+               mii_info->speed = SPEED_10;
+               mii_info->duplex = DUPLEX_FULL;
+               break;
+       case MIIM_LXT971_SR2_100HDX:
+               mii_info->speed = SPEED_100;
+               mii_info->duplex = DUPLEX_HALF;
+               break;
+       default:
+               mii_info->speed = SPEED_100;
+               mii_info->duplex = DUPLEX_FULL;
+       }
+
+       return 0;
+}
+
+static int lxt971_startup(struct mii_info *mii_info)
+{
+       genphy_update_link(mii_info);
+       lxt971_parse_status(mii_info);
+
+       return 0;
+}
+
 /* Marvell 88E1011S */
 static int m88e1011s_config(struct mii_info *mii_info)
 {
@@ -747,7 +952,86 @@ static int vsc8211_startup(struct mii_info *mii_info)
 
        return 0;
 }
- 
+
+/* RealTek RTL8211B */
+static int rtl8211b_config(struct mii_info *mii_info)
+{
+       tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET);
+       tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT);
+       tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT);
+       tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET);
+       tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT);
+
+       return 0;
+}
+
+static int rtl8211b_parse_status(struct mii_info *mii_info)
+{
+       unsigned int speed;
+       unsigned int mii_reg;
+
+       mii_reg = tsec_phy_read(mii_info, 0, MIIM_RTL8211B_PHY_STATUS);
+
+       if (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
+               int i = 0;
+
+               /* in case of timeout ->link is cleared */
+               mii_info->link = 1;
+               puts("Waiting for PHY realtime link");
+               while (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
+                       /* Timeout reached ? */
+                       if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+                               puts(" TIMEOUT !\n");
+                               mii_info->link = 0;
+                               break;
+                       }
+
+                       if ((i++ % 1000) == 0) {
+                               putc('.');
+                       }
+                       udelay(1000);   /* 1 ms */
+                       mii_reg = tsec_phy_read(mii_info, 0,
+                                       MIIM_RTL8211B_PHY_STATUS);
+               }
+               puts(" done\n");
+               udelay(500000); /* another 500 ms (results in faster booting) */
+       } else {
+               if (mii_reg & MIIM_RTL8211B_PHYSTAT_LINK)
+                       mii_info->link = 1;
+               else
+                       mii_info->link = 0;
+       }
+
+       if (mii_reg & MIIM_RTL8211B_PHYSTAT_DUPLEX)
+               mii_info->duplex = DUPLEX_FULL;
+       else
+               mii_info->duplex = DUPLEX_HALF;
+
+       speed = (mii_reg & MIIM_RTL8211B_PHYSTAT_SPEED);
+
+       switch (speed) {
+       case MIIM_RTL8211B_PHYSTAT_GBIT:
+               mii_info->speed = SPEED_1000;
+               break;
+       case MIIM_RTL8211B_PHYSTAT_100:
+               mii_info->speed = SPEED_100;
+               break;
+       default:
+               mii_info->speed = SPEED_10;
+       }
+
+       return 0;
+}
+
+static int rtl8211b_startup(struct mii_info *mii_info)
+{
+       /* Read the Status (2x to make sure link is right) */
+       genphy_update_link(mii_info);
+       rtl8211b_parse_status(mii_info);
+
+       return 0;
+}
+
 /* Vitesse VSC8244 */
 static int vsc8244_parse_status(struct mii_info *mii_info)
 {
@@ -840,6 +1124,60 @@ static struct phy_info phy_info_BCM5482S = {
        &genphy_shutdown,
 };
 
+static struct phy_info phy_info_CIS8201 = {
+       "CIS8201",
+       0xfc410,
+       0xffff0,
+       &cis8201_config,
+       &cis8201_startup,
+       &genphy_shutdown,
+};
+
+static struct phy_info phy_info_CIS8204 = {
+       "Cicada Cis8204",
+       0xfc440,
+       0xffff0,
+       &cis8204_config,
+       &cis8201_startup,
+       &genphy_shutdown,
+};
+
+static struct phy_info phy_info_DM9161 = {
+       "Davicom DM9161E",
+       0x181b880,
+       0xffffff0,
+       &dm9161_config,
+       &dm9161_startup,
+       &genphy_shutdown,
+};
+
+static struct phy_info phy_info_DP83865 = {
+       "NatSemi DP83865",
+       0x20005c70,
+       0xfffffff0,
+       &dp83865_config,
+       &dp83865_startup,
+       &genphy_shutdown,
+};
+
+static struct phy_info phy_info_KSZ804 = {
+       "Micrel KSZ804",
+       0x221510,
+       0xfffff0,
+       &genphy_config,
+       &genphy_startup,
+       &genphy_shutdown,
+};
+
+static struct phy_info phy_info_LXT971 = {
+       "LXT971",
+       0x1378e0,
+       0xfffff0,
+       &genphy_config,
+       &lxt971_startup,
+       &genphy_shutdown,
+};
+
 static struct phy_info phy_info_M88E1011S = {
        "Marvell 88E1011S",
        0x1410c60,
@@ -894,6 +1232,15 @@ static struct phy_info phy_info_M88E1149S = {
        &genphy_shutdown,
 };
 
+static struct phy_info phy_info_RTL8211B = {
+       "RealTek RTL8211B",
+       0x1cc910,
+       0xfffff0,
+       &rtl8211b_config,
+       &rtl8211b_startup,
+       &genphy_shutdown,
+};
+
 static struct phy_info phy_info_VSC8211 = {
        "Vitesse VSC8211",
        0xfc4b0,
@@ -961,12 +1308,19 @@ static struct phy_info *phy_info[] = {
        &phy_info_BCM5461S,
        &phy_info_BCM5464S,
        &phy_info_BCM5482S,
+       &phy_info_CIS8201,
+       &phy_info_CIS8204,
+       &phy_info_DM9161,
+       &phy_info_DP83865,
+       &phy_info_KSZ804,
+       &phy_info_LXT971,
        &phy_info_M88E1011S,
        &phy_info_M88E1111S,
        &phy_info_M88E1118,
        &phy_info_M88E1121R,
        &phy_info_M88E1145,
        &phy_info_M88E1149S,
+       &phy_info_RTL8211B,
        &phy_info_VSC8211,
        &phy_info_VSC8221,
        &phy_info_VSC8244,
diff --git a/drivers/net/fsl_phy.h b/drivers/net/fsl_phy.h
index 5e6d236..ba284e6 100644
--- a/drivers/net/fsl_phy.h
+++ b/drivers/net/fsl_phy.h
@@ -134,6 +134,54 @@
 #define MIIM_CIS8201_EXT_CON1          0x17
 #define MIIM_CIS8201_EXTCON1_INIT      0x0000
 
+/* Cicada 8204 Extended PHY Control Register 1 */
+#define MIIM_CIS8204_EPHY_CON          0x17
+#define MIIM_CIS8204_EPHYCON_INIT      0x0006
+#define MIIM_CIS8204_EPHYCON_RGMII     0x1100
+
+/* Cicada 8204 Serial LED Control Register */
+#define MIIM_CIS8204_SLED_CON          0x1b
+#define MIIM_CIS8204_SLEDCON_INIT      0x1115
+
+#define MIIM_GBIT_CON          0x09
+#define MIIM_GBIT_CON_ADVERT   0x0e00
+
+/* DM9161 Control register values */
+#define MIIM_DM9161_CR_STOP    0x0400
+#define MIIM_DM9161_CR_RSTAN   0x1200
+
+#define MIIM_DM9161_SCR                0x10
+#define MIIM_DM9161_SCR_INIT   0x0610
+
+/* DM9161 Specified Configuration and Status Register */
+#define MIIM_DM9161_SCSR       0x11
+#define MIIM_DM9161_SCSR_100F  0x8000
+#define MIIM_DM9161_SCSR_100H  0x4000
+#define MIIM_DM9161_SCSR_10F   0x2000
+#define MIIM_DM9161_SCSR_10H   0x1000
+
+/* DM9161 10BT Configuration/Status */
+#define MIIM_DM9161_10BTCSR    0x12
+#define MIIM_DM9161_10BTCSR_INIT       0x7800
+
+/* DP83865 Control register values */
+#define MIIM_DP83865_CR_INIT   0x9200
+
+/* DP83865 Link and Auto-Neg Status Register */
+#define MIIM_DP83865_LANR      0x11
+#define MIIM_DP83865_SPD_MASK  0x0018
+#define MIIM_DP83865_SPD_1000  0x0010
+#define MIIM_DP83865_SPD_100   0x0008
+#define MIIM_DP83865_DPX_FULL  0x0002
+
+/* LXT971 Status 2 registers */
+#define MIIM_LXT971_SR2                     0x11  /* Status Register 2  */
+#define MIIM_LXT971_SR2_SPEED_MASK 0x4200
+#define MIIM_LXT971_SR2_10HDX     0x0000  /*  10 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_10FDX     0x0200  /*  10 Mbit full duplex selected */
+#define MIIM_LXT971_SR2_100HDX    0x4000  /* 100 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_100FDX    0x4200  /* 100 Mbit full duplex selected */
+
 /* 88E1011 PHY Status Register */
 #define MIIM_88E1011_PHY_STATUS                0x11
 #define MIIM_88E1011_PHYSTAT_SPEED     0xc000
@@ -170,6 +218,15 @@
 #define MIIM_88E1145_PHY_PAGE  29
 #define MIIM_88E1145_PHY_CAL_OV 30
 
+/* RTL8211B PHY Status Register */
+#define MIIM_RTL8211B_PHY_STATUS       0x11
+#define MIIM_RTL8211B_PHYSTAT_SPEED    0xc000
+#define MIIM_RTL8211B_PHYSTAT_GBIT     0x8000
+#define MIIM_RTL8211B_PHYSTAT_100      0x4000
+#define MIIM_RTL8211B_PHYSTAT_DUPLEX   0x2000
+#define MIIM_RTL8211B_PHYSTAT_SPDDONE  0x0800
+#define MIIM_RTL8211B_PHYSTAT_LINK     0x0400
+
 /* Entry for Vitesse VSC8244 regs starts here */
 /* Vitesse VSC8244 Auxiliary Control/Status Register */
 #define MIIM_VSC8244_AUX_CONSTAT       0x1c
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 6ed3e09..fd8829d 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -190,6 +190,30 @@ tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 
set)
 }
 #endif /* Multicast TFTP ? */
 
+/*
+ * Hack to write all 4 PHYs with the LED values
+ */
+int cis8204_fixled(struct mii_info *mii_info)
+{
+       uint phyid;
+       tsec_mii_t *regbase = mii_info->phyregs;
+       int timeout = 1000000;
+
+       for (phyid = 0; phyid < 4; phyid++) {
+               out_be32(&regbase->miimadd, (phyid << 8) | 
MIIM_CIS8204_SLED_CON);
+               out_be32(&regbase->miimcon, MIIM_CIS8204_SLEDCON_INIT);
+               asm("sync");
+
+               timeout = 1000000;
+               while ((in_be32(&regbase->miimind) & MIIMIND_BUSY) && 
timeout--) ;
+       }
+
+       tsec_phy_write(mii_info, 0, MIIM_CIS8204_SLED_CON,
+                       MIIM_CIS8204_SLEDCON_INIT);
+
+       return 0;
+}
+
 /* Initialized required registers to appropriate values, zeroing
  * those we don't care about (unless zero is bad, in which case,
  * choose a more appropriate value)
-- 
1.6.4


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to