]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - cpu/mpc8xx/fec.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / cpu / mpc8xx / fec.c
index 34a4b20a7af3755a981f8db988f8d0a2f7c601ed..141425d8ed4bdeabdfcbf7adf0c58a03e2773f53 100644 (file)
 #include <net.h>
 #include <command.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #undef ET_DEBUG
 
-#if (CONFIG_COMMANDS & CFG_CMD_NET) && \
+#if defined(CONFIG_CMD_NET) && \
        (defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2))
 
 /* compatibility test, if only FEC_ENET defined assume ETHER on FEC1 */
@@ -38,7 +40,7 @@
 #endif
 
 /* define WANT_MII when MII support is required */
-#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
+#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
 #define WANT_MII
 #else
 #undef WANT_MII
 
 #if defined(WANT_MII)
 #include <miiphy.h>
+
+#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+#error "CONFIG_MII has to be defined!"
+#endif
+
 #endif
 
 #if defined(CONFIG_RMII) && !defined(WANT_MII)
 #error RMII support is unusable without a working PHY.
 #endif
 
-#ifdef CFG_DISCOVER_PHY
+#ifdef CONFIG_SYS_DISCOVER_PHY
 static int mii_discover_phy(struct eth_device *dev);
 #endif
 
+int fec8xx_miiphy_read(char *devname, unsigned char addr,
+               unsigned char  reg, unsigned short *value);
+int fec8xx_miiphy_write(char *devname, unsigned char  addr,
+               unsigned char  reg, unsigned short value);
+
 static struct ether_fcc_info_s
 {
        int ether_index;
@@ -131,6 +143,9 @@ static int fec_send(struct eth_device* dev, volatile void *packet, int length);
 static int fec_recv(struct eth_device* dev);
 static int fec_init(struct eth_device* dev, bd_t * bd);
 static void fec_halt(struct eth_device* dev);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static void __mii_init(void);
+#endif
 
 int fec_initialize(bd_t *bis)
 {
@@ -169,6 +184,11 @@ int fec_initialize(bd_t *bis)
                dev->recv = fec_recv;
 
                eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+               miiphy_register(dev->name,
+                       fec8xx_miiphy_read, fec8xx_miiphy_write);
+#endif
        }
        return 1;
 }
@@ -177,7 +197,7 @@ static int fec_send(struct eth_device* dev, volatile void *packet, int length)
 {
        int j, rc;
        struct ether_fcc_info_s *efis = dev->priv;
-       volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
+       volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 
        /* section 16.9.23.3
         * Wait for ready
@@ -228,7 +248,7 @@ static int fec_recv (struct eth_device *dev)
 {
        struct ether_fcc_info_s *efis = dev->priv;
        volatile fec_t *fecp =
-               (volatile fec_t *) (CFG_IMMR + efis->fecp_offset);
+               (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
        int length;
 
        for (;;) {
@@ -251,7 +271,7 @@ static int fec_recv (struct eth_device *dev)
 
                        length -= 4;
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if defined(CONFIG_CMD_CDP)
                        if ((rx[0] & 1) != 0
                            && memcmp ((uchar *) rx, NetBcastAddr, 6) != 0
                            && memcmp ((uchar *) rx, NetCDPAddr, 6) != 0)
@@ -319,7 +339,7 @@ static inline void fec_10Mbps(struct eth_device *dev)
        if ((unsigned int)fecidx >= 2)
                hang();
 
-       ((volatile immap_t *)CFG_IMMR)->im_cpm.cp_cptr |=  mask;
+       ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr |=  mask;
 }
 
 static inline void fec_100Mbps(struct eth_device *dev)
@@ -331,7 +351,7 @@ static inline void fec_100Mbps(struct eth_device *dev)
        if ((unsigned int)fecidx >= 2)
                hang();
 
-       ((volatile immap_t *)CFG_IMMR)->im_cpm.cp_cptr &= ~mask;
+       ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr &= ~mask;
 }
 
 #endif
@@ -339,7 +359,7 @@ static inline void fec_100Mbps(struct eth_device *dev)
 static inline void fec_full_duplex(struct eth_device *dev)
 {
        struct ether_fcc_info_s *efis = dev->priv;
-       volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
+       volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 
        fecp->fec_r_cntrl &= ~FEC_RCNTRL_DRT;
        fecp->fec_x_cntrl |=  FEC_TCNTRL_FDEN;  /* FD enable */
@@ -348,7 +368,7 @@ static inline void fec_full_duplex(struct eth_device *dev)
 static inline void fec_half_duplex(struct eth_device *dev)
 {
        struct ether_fcc_info_s *efis = dev->priv;
-       volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
+       volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 
        fecp->fec_r_cntrl |=  FEC_RCNTRL_DRT;
        fecp->fec_x_cntrl &= ~FEC_TCNTRL_FDEN;  /* FD disable */
@@ -356,9 +376,8 @@ static inline void fec_half_duplex(struct eth_device *dev)
 
 static void fec_pin_init(int fecidx)
 {
-       DECLARE_GLOBAL_DATA_PTR;
        bd_t           *bd = gd->bd;
-       volatile immap_t *immr = (immap_t *) CFG_IMMR;
+       volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
        volatile fec_t *fecp;
 
        /*
@@ -380,15 +399,17 @@ static void fec_pin_init(int fecidx)
         * * to 2.5 MHz.
         * * This MDC frequency is equal to system clock / (2 * MII_SPEED).
         * * Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
+        *
+        * All MII configuration is done via FEC1 registers:
         */
-       fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
+       immr->im_cpm.cp_fec1.fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
 
-#if defined(CONFIG_NETTA) || defined(CONFIG_NETPHONE)
+#if defined(CONFIG_NETTA) || defined(CONFIG_NETPHONE) || defined(CONFIG_NETTA2)
        /* our PHYs are the limit at 2.5 MHz */
        fecp->fec_mii_speed <<= 1;
 #endif
 
-#if defined(CONFIG_DUET) && defined(WANT_MII)
+#if defined(CONFIG_MPC885_FAMILY) && defined(WANT_MII)
        /* use MDC for MII */
        immr->im_ioport.iop_pdpar |=  0x0080;
        immr->im_ioport.iop_pddir &= ~0x0080;
@@ -397,7 +418,7 @@ static void fec_pin_init(int fecidx)
        if (fecidx == 0) {
 #if defined(CONFIG_ETHER_ON_FEC1)
 
-#if defined(CONFIG_DUET)       /* MPC87x/88x have got 2 FECs and different pinout */
+#if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
 
 #if !defined(CONFIG_RMII)
 
@@ -453,7 +474,7 @@ static void fec_pin_init(int fecidx)
                 * Configure port A for MII.
                 */
 
-#if defined(CONFIG_ICU862) && defined(CFG_DISCOVER_PHY)
+#if defined(CONFIG_ICU862) && defined(CONFIG_SYS_DISCOVER_PHY)
 
                /*
                 * On the ICU862 board the MII-MDC pin is routed to PD8 pin
@@ -489,11 +510,9 @@ static void fec_pin_init(int fecidx)
 
 #if defined(CONFIG_ETHER_ON_FEC2)
 
-#if defined(CONFIG_DUET)       /* MPC87x/88x have got 2 FECs and different pinout */
+#if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
 
 #if !defined(CONFIG_RMII)
-
-#warning this configuration is not tested; please report if it works
                immr->im_cpm.cp_pepar     |=  0x0003fffc;
                immr->im_cpm.cp_pedir     |=  0x0003fffc;
                immr->im_cpm.cp_peso      &= ~0x000087fc;
@@ -516,24 +535,48 @@ static void fec_pin_init(int fecidx)
                immr->im_cpm.cp_cptr      &= ~0x00000028;
 #endif /* CONFIG_RMII */
 
-#endif /* CONFIG_DUET */
+#endif /* CONFIG_MPC885_FAMILY */
 
 #endif /* CONFIG_ETHER_ON_FEC2 */
 
        }
 }
 
+static int fec_reset(volatile fec_t *fecp)
+{
+       int i;
+
+       /* Whack a reset.
+        * A delay is required between a reset of the FEC block and
+        * initialization of other FEC registers because the reset takes
+        * some time to complete. If you don't delay, subsequent writes
+        * to FEC registers might get killed by the reset routine which is
+        * still in progress.
+        */
+
+       fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+       for (i = 0;
+            (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+            ++i) {
+               udelay (1);
+       }
+       if (i == FEC_RESET_DELAY)
+               return -1;
+
+       return 0;
+}
+
 static int fec_init (struct eth_device *dev, bd_t * bd)
 {
        struct ether_fcc_info_s *efis = dev->priv;
-       volatile immap_t *immr = (immap_t *) CFG_IMMR;
+       volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
        volatile fec_t *fecp =
-               (volatile fec_t *) (CFG_IMMR + efis->fecp_offset);
+               (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
        int i;
 
        if (efis->ether_index == 0) {
 #if defined(CONFIG_FADS)       /* FADS family uses FPGA (BCSR) to control PHYs */
-#if defined(CONFIG_DUET_ADS)
+#if defined(CONFIG_MPC885ADS)
                *(vu_char *) BCSR5 &= ~(BCSR5_MII1_EN | BCSR5_MII1_RST);
 #else
                /* configure FADS for fast (FEC) ethernet, half-duplex */
@@ -553,27 +596,21 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
                        *bcsr4 |= BCSR4_FETHRST;
                        udelay (10);
                }
-#endif /* CONFIG_DUET_ADS */
+#endif /* CONFIG_MPC885ADS */
 #endif /* CONFIG_FADS */
        }
 
-       /* Whack a reset.
-        * A delay is required between a reset of the FEC block and
-        * initialization of other FEC registers because the reset takes
-        * some time to complete. If you don't delay, subsequent writes
-        * to FEC registers might get killed by the reset routine which is
-        * still in progress.
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+       /* the MII interface is connected to FEC1
+        * so for the miiphy_xxx function to work we must
+        * call mii_init since fec_halt messes the thing up
         */
-       fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
-       for (i = 0;
-            (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
-            ++i) {
-               udelay (1);
-       }
-       if (i == FEC_RESET_DELAY) {
+       if (efis->ether_index != 0)
+               __mii_init();
+#endif
+
+       if (fec_reset(fecp) < 0)
                printf ("FEC_RESET_DELAY timeout\n");
-               return 0;
-       }
 
        /* We use strictly polling mode only
         */
@@ -587,12 +624,12 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
 
        /* Set station address
         */
-#define ea eth_get_dev()->enetaddr
+#define ea dev->enetaddr
        fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
        fecp->fec_addr_high = (ea[4] << 8) | (ea[5]);
 #undef ea
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if defined(CONFIG_CMD_CDP)
        /*
         * Turn on multicast address hash table
         */
@@ -620,7 +657,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
        txIdx = 0;
 
        if (!rtx) {
-#ifdef CFG_ALLOC_DPRAM
+#ifdef CONFIG_SYS_ALLOC_DPRAM
                rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
                                 dpram_alloc_align (sizeof (RTXBD), 8));
 #else
@@ -684,34 +721,28 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
 
        if (efis->phy_addr == -1) {
-#ifdef CFG_DISCOVER_PHY
+#ifdef CONFIG_SYS_DISCOVER_PHY
                /*
                 * wait for the PHY to wake up after reset
                 */
                efis->actual_phy_addr = mii_discover_phy (dev);
-#else
-               efis->actual_phy_addr = -1;
-#endif
+
                if (efis->actual_phy_addr == -1) {
                        printf ("Unable to discover phy!\n");
-                       return 0;
+                       return -1;
                }
+#else
+               efis->actual_phy_addr = -1;
+#endif
        } else {
                efis->actual_phy_addr = efis->phy_addr;
        }
-#if defined(CONFIG_MII) && defined(CONFIG_RMII)
-
-       /* the MII interface is connected to FEC1
-        * so for the miiphy_xxx function to work we must
-        * call mii_init since fec_halt messes the thing up
-        */
-       if (efis->ether_index != 0)
-               mii_init();
 
+#if defined(CONFIG_MII) && defined(CONFIG_RMII)
        /*
         * adapt the RMII speed to the speed of the phy
         */
-       if (miiphy_speed (efis->actual_phy_addr) == _100BASET) {
+       if (miiphy_speed (dev->name, efis->actual_phy_addr) == _100BASET) {
                fec_100Mbps (dev);
        } else {
                fec_10Mbps (dev);
@@ -722,7 +753,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
        /*
         * adapt to the half/full speed settings
         */
-       if (miiphy_duplex (efis->actual_phy_addr) == FULL) {
+       if (miiphy_duplex (dev->name, efis->actual_phy_addr) == FULL) {
                fec_full_duplex (dev);
        } else {
                fec_half_duplex (dev);
@@ -734,14 +765,14 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
 
        efis->initialized = 1;
 
-       return 1;
+       return 0;
 }
 
 
 static void fec_halt(struct eth_device* dev)
 {
        struct ether_fcc_info_s *efis = dev->priv;
-       volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset);
+       volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
        int i;
 
        /* avoid halt if initialized; mii gets stuck otherwise */
@@ -770,7 +801,7 @@ static void fec_halt(struct eth_device* dev)
        efis->initialized = 0;
 }
 
-#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 
 /* Make MII read/write commands for the FEC.
 */
@@ -805,6 +836,7 @@ static void fec_halt(struct eth_device* dev)
 #define PHY_ID_LSI80225                0x0016f870      /* LSI 80225 */
 #define PHY_ID_LSI80225B       0x0016f880      /* LSI 80225/B */
 #define PHY_ID_DM9161          0x0181B880      /* Davicom DM9161 */
+#define PHY_ID_KSM8995M                0x00221450      /* MICREL KS8995MA */
 
 /* send command to phy using mii, wait for result */
 static uint
@@ -814,7 +846,7 @@ mii_send(uint mii_cmd)
        volatile fec_t  *ep;
        int cnt;
 
-       ep = &(((immap_t *)CFG_IMMR)->im_cpm.cp_fec);
+       ep = &(((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_fec);
 
        ep->fec_mii_data = mii_cmd;     /* command to phy */
 
@@ -834,9 +866,9 @@ mii_send(uint mii_cmd)
 #endif
        return (mii_reply & 0xffff);            /* data read from phy */
 }
-#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
+#endif
 
-#if defined(CFG_DISCOVER_PHY)
+#if defined(CONFIG_SYS_DISCOVER_PHY)
 static int mii_discover_phy(struct eth_device *dev)
 {
 #define MAX_PHY_PASSES 11
@@ -856,15 +888,14 @@ static int mii_discover_phy(struct eth_device *dev)
                        udelay(10000);  /* wait 10ms */
                }
                for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
-                       phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1));
+                       phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR2));
 #ifdef ET_DEBUG
                        printf("PHY type 0x%x pass %d type ", phytype, pass);
 #endif
                        if (phytype != 0xffff) {
                                phyaddr = phyno;
-                               phytype <<= 16;
                                phytype |= mii_send(mk_mii_read(phyno,
-                                                               PHY_PHYIDR2));
+                                                               PHY_PHYIDR1)) << 16;
 
 #ifdef ET_DEBUG
                                printf("PHY @ 0x%x pass %d type ",phyno,pass);
@@ -890,6 +921,9 @@ static int mii_discover_phy(struct eth_device *dev)
                                case PHY_ID_DM9161:
                                        printf("Davicom DM9161\n");
                                        break;
+                               case PHY_ID_KSM8995M:
+                                       printf("MICREL KS8995M\n");
+                                       break;
                                default:
                                        printf("0x%08x\n", phytype);
                                        break;
@@ -903,41 +937,22 @@ static int mii_discover_phy(struct eth_device *dev)
        }
        return phyaddr;
 }
-#endif /* CFG_DISCOVER_PHY */
+#endif /* CONFIG_SYS_DISCOVER_PHY */
 
-#if (defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
 
 /****************************************************************************
- * mii_init -- Initialize the MII for MII command without ethernet
+ * mii_init -- Initialize the MII via FEC 1 for MII command without ethernet
  * This function is a subset of eth_init
  ****************************************************************************
  */
-void mii_init (void)
+static void __mii_init(void)
 {
-       volatile immap_t *immr = (immap_t *) CFG_IMMR;
+       volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
        volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
-       int i, j;
-
-       for (j = 0; j < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); j++) {
 
-       /* Whack a reset.
-        * A delay is required between a reset of the FEC block and
-        * initialization of other FEC registers because the reset takes
-        * some time to complete. If you don't delay, subsequent writes
-        * to FEC registers might get killed by the reset routine which is
-        * still in progress.
-        */
-
-       fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
-       for (i = 0;
-            (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
-            ++i) {
-               udelay (1);
-       }
-       if (i == FEC_RESET_DELAY) {
+       if (fec_reset(fecp) < 0)
                printf ("FEC_RESET_DELAY timeout\n");
-               return;
-       }
 
        /* We use strictly polling mode only
         */
@@ -947,14 +962,21 @@ void mii_init (void)
         */
        fecp->fec_ievent = 0xffc0;
 
-               /* Setup the pin configuration of the FEC(s)
-       */
-               fec_pin_init(ether_fcc_info[i].ether_index);
-
        /* Now enable the transmit and receive processing
         */
        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
-       }
+}
+
+void mii_init (void)
+{
+       int i;
+
+       __mii_init();
+
+       /* Setup the pin configuration of the FEC(s)
+       */
+       for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+               fec_pin_init(ether_fcc_info[i].ether_index);
 }
 
 /*****************************************************************************
@@ -968,7 +990,8 @@ void mii_init (void)
  *       Otherwise they hang in mii_send() !!! Sorry!
  *****************************************************************************/
 
-int miiphy_read(unsigned char addr, unsigned char  reg, unsigned short *value)
+int fec8xx_miiphy_read(char *devname, unsigned char addr,
+               unsigned char  reg, unsigned short *value)
 {
        short rdreg;    /* register working value */
 
@@ -984,7 +1007,8 @@ int miiphy_read(unsigned char addr, unsigned char  reg, unsigned short *value)
        return 0;
 }
 
-int miiphy_write(unsigned char  addr, unsigned char  reg, unsigned short value)
+int fec8xx_miiphy_write(char *devname, unsigned char  addr,
+               unsigned char  reg, unsigned short value)
 {
        short rdreg;    /* register working value */
 #ifdef MII_DEBUG
@@ -997,6 +1021,6 @@ int miiphy_write(unsigned char  addr, unsigned char  reg, unsigned short value)
 #endif
        return 0;
 }
-#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)*/
+#endif
 
-#endif /* CFG_CMD_NET, FEC_ENET */
+#endif