]> git.sur5r.net Git - u-boot/blobdiff - cpu/mpc5xxx/fec.c
* Add support for HMI1001 board
[u-boot] / cpu / mpc5xxx / fec.c
index 50499e214e5dc160ef696e328426164d3a1c0017..d29310787dc83c007db981e595bd00bdaf1bbb3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2003
+ * (C) Copyright 2003-2005
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * This file is based on mpc4200fec.c,
@@ -115,7 +115,7 @@ static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec)
 }
 
 /********************************************************************/
-static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, FEC_RBD * pRbd)
+static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd)
 {
        /*
         * Reset buffer descriptor as empty
@@ -141,7 +141,7 @@ static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, FEC_RBD * pRbd)
 /********************************************************************/
 static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec)
 {
-       FEC_TBD *pUsedTbd;
+       volatile FEC_TBD *pUsedTbd;
 
 #if (DEBUG & 0x1)
        printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
@@ -238,7 +238,6 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
        DECLARE_GLOBAL_DATA_PTR;
        mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
        struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
-       const uint8 phyAddr = CONFIG_PHY_ADDR;  /* Only one PHY */
 
 #if (DEBUG & 0x1)
        printf ("mpc5xxx_fec_init... Begin\n");
@@ -250,17 +249,6 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
        mpc5xxx_fec_rbd_init(fec);
        mpc5xxx_fec_tbd_init(fec);
 
-       /*
-        * Initialize GPIO pins
-        */
-       if (fec->xcv_type == SEVENWIRE) {
-               /*  10MBit with 7-wire operation */
-               *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
-       } else {
-               /* 100MBit with MD operation */
-               *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
-       }
-
        /*
         * Clear FEC-Lite interrupt event register(IEVENT)
         */
@@ -286,16 +274,8 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
                fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
        }
 
-       if (fec->xcv_type == SEVENWIRE) {
-               /*
-                * Set FEC-Lite transmit control register(X_CNTRL):
-                */
-               /*fec->eth->x_cntrl = 0x00000002; */  /* half-duplex, heartbeat */
-               fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
-       } else {
-               /*fec->eth->x_cntrl = 0x00000006; */  /* full-duplex, heartbeat */
-               fec->eth->x_cntrl = 0x00000004; /* full-duplex, heartbeat disabled */
-
+       fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
+       if (fec->xcv_type != SEVENWIRE) {
                /*
                 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
                 * and do not drop the Preamble.
@@ -374,10 +354,78 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
        /*
         * Initialize SmartDMA parameters stored in SRAM
         */
-       *(int *)FEC_TBD_BASE = (int)fec->tbdBase;
-       *(int *)FEC_RBD_BASE = (int)fec->rbdBase;
-       *(int *)FEC_TBD_NEXT = (int)fec->tbdBase;
-       *(int *)FEC_RBD_NEXT = (int)fec->rbdBase;
+       *(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase;
+       *(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase;
+       *(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase;
+       *(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase;
+
+       /*
+        * Enable FEC-Lite controller
+        */
+       fec->eth->ecntrl |= 0x00000006;
+
+#if (DEBUG & 0x2)
+       if (fec->xcv_type != SEVENWIRE)
+               mpc5xxx_fec_phydump ();
+#endif
+
+       /*
+        * Enable SmartDMA receive task
+        */
+       SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
+
+#if (DEBUG & 0x1)
+       printf("mpc5xxx_fec_init... Done \n");
+#endif
+
+       return 1;
+}
+
+/********************************************************************/
+static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+       const uint8 phyAddr = CONFIG_PHY_ADDR;  /* Only one PHY */
+
+#if (DEBUG & 0x1)
+       printf ("mpc5xxx_fec_init_phy... Begin\n");
+#endif
+
+       /*
+        * Initialize GPIO pins
+        */
+       if (fec->xcv_type == SEVENWIRE) {
+               /*  10MBit with 7-wire operation */
+#if defined(CONFIG_TOTAL5200)
+               /* 7-wire and USB2 on Ethernet */
+               *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00030000;
+#else  /* !CONFIG_TOTAL5200 */
+               /* 7-wire only */
+               *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
+#endif /* CONFIG_TOTAL5200 */
+       } else {
+               /* 100MBit with MD operation */
+               *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
+       }
+
+       /*
+        * Clear FEC-Lite interrupt event register(IEVENT)
+        */
+       fec->eth->ievent = 0xffffffff;
+
+       /*
+        * Set interrupt mask register
+        */
+       fec->eth->imask = 0x00000000;
+
+       if (fec->xcv_type != SEVENWIRE) {
+               /*
+                * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+                * and do not drop the Preamble.
+                */
+               fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
+       }
 
        if (fec->xcv_type != SEVENWIRE) {
                /*
@@ -485,7 +533,7 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
 #endif
                                        return -1;
                                }
-                       } while ((phyStatus & 0x0020) != 0x0020);
+                       } while (!(phyStatus & 0x0004));
 
 #if (DEBUG & 0x2)
                        printf("PHY auto neg complete! \n");
@@ -494,23 +542,14 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
 
        }
 
-       /*
-        * Enable FEC-Lite controller
-        */
-       fec->eth->ecntrl |= 0x00000006;
-
 #if (DEBUG & 0x2)
        if (fec->xcv_type != SEVENWIRE)
                mpc5xxx_fec_phydump ();
 #endif
 
-       /*
-        * Enable SmartDMA receive task
-        */
-       SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
 
 #if (DEBUG & 0x1)
-       printf("mpc5xxx_fec_init... Done \n");
+       printf("mpc5xxx_fec_init_phy... Done \n");
 #endif
 
        return 1;
@@ -649,7 +688,7 @@ static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
         * 6-byte Ethernet addresses.
         */
        mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
-       FEC_TBD *pTbd;
+       volatile FEC_TBD *pTbd;
 
 #if (DEBUG & 0x20)
        printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
@@ -740,7 +779,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev)
         * This command pulls one frame from the card
         */
        mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
-       FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
+       volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
        unsigned long ievent;
        int frame_length, len = 0;
        NBUF *frame;
@@ -830,14 +869,17 @@ int mpc5xxx_fec_initialize(bd_t * bis)
        fec->eth = (ethernet_regs *)MPC5XXX_FEC;
        fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
        fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
-#if defined(CONFIG_ICECUBE) ||
-    defined(CONFIG_PM520)   ||
-    defined(CONFIG_TOP5200)
+#if defined(CONFIG_CANMB)   || defined(CONFIG_HMI1001) || \
+    defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0) || \
+    defined(CONFIG_PM520)   || defined(CONFIG_TOP5200) || \
+    defined(CONFIG_TQM5200)
 # ifndef CONFIG_FEC_10MBIT
        fec->xcv_type = MII100;
 # else
        fec->xcv_type = MII10;
 # endif
+#elif defined(CONFIG_TOTAL5200)
+       fec->xcv_type = SEVENWIRE;
 #else
 #error fec->xcv_type not initialized.
 #endif
@@ -867,6 +909,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
                mpc5xxx_fec_set_hwaddr(fec, env_enetaddr);
        }
 
+       mpc5xxx_fec_init_phy(dev, bis);
        return 1;
 }