Add support for AMCC Bamboo PPC440EP eval board
[platform/kernel/u-boot.git] / cpu / ppc4xx / 405gp_enet.c
index da45558..b60d122 100644 (file)
@@ -166,7 +166,6 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
                failsafe--;
                if (failsafe == 0)
                        break;
-
        }
 
        /* EMAC RESET */
@@ -223,13 +222,19 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 #endif
 
        /* MAL RESET */
-        mtdcr (malmcr, MAL_CR_MMSR);
-        /* wait for reset */
-        while (mfdcr (malmcr) & MAL_CR_MMSR) {
-        };
-#if defined(CONFIG_440)
-        /* set RMII mode */
-        out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+       mtdcr (malmcr, MAL_CR_MMSR);
+       /* wait for reset */
+       while (mfdcr (malmcr) & MAL_CR_MMSR) {
+       };
+
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       out32 (ZMII_FER, 0);
+       udelay(100);
+       /* set RII mode */
+       out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+#elif defined(CONFIG_440)
+       /* set RMII mode */
+       out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
 #endif /* CONFIG_440 */
 
        /* MAL Channel RESET */
@@ -319,14 +324,11 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
                        (int) speed, (duplex == HALF) ? "HALF" : "FULL");
        }
 
-#if defined(CONFIG_440)
-       /* Errata 1.12: MAL_1 -- Disable MAL bursting */
-       if( get_pvr() == PVR_440GP_RB)
-               mtdcr (malmcr, MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
-       else
-#else
        mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
-#endif
+       /* Errata 1.12: MAL_1 -- Disable MAL bursting */
+       if (get_pvr() == PVR_440GP_RB) {
+               mtdcr (malmcr, mfdcr(malmcr) & ~MAL_CR_PLBB);
+       }
 
        /* Free "old" buffers */
        if (hw_p->alloc_tx_buf)
@@ -413,7 +415,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
        reg |= dev->enetaddr[5];
 
        out32 (EMAC_IAL + hw_p->hw_addr, reg);
+
        switch (devnum) {
+#if defined(CONFIG_NET_MULTI)
        case 1:
                /* setup MAL tx & rx channel pointers */
                /* For 405EP, the EMAC1 tx channel 0 is MAL tx channel 2 */
@@ -422,6 +426,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
                /* set RX buffer size */
                mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16);
                break;
+#endif
        case 0:
        default:
                /* setup MAL tx & rx channel pointers */
@@ -459,6 +464,18 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
                out32(ZMII_SSR, in32(ZMII_SSR) | 0x10000000);
        else
                out32(ZMII_SSR, in32(ZMII_SSR) & ~0x10000000);
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       mfsdr(sdr_mfr, reg);
+       /* set speed */
+       if (speed == _100BASET) {
+               out32(ZMII_SSR, in32(ZMII_SSR) | 0x10000000);
+               reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_100M;
+       } else {
+               reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M;
+               out32(ZMII_SSR, in32(ZMII_SSR) & ~0x10000000);
+       }
+       mtsdr(sdr_mfr, reg);
+#endif
 #endif
 
        /* Enable broadcast and indvidual address */
@@ -479,7 +496,6 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
        out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);
 #endif
 
-
        /* Frame gap set */
        out32 (EMAC_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008);
 
@@ -496,11 +512,6 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
                /*
                 * Connect interrupt service routines
                 */
-#if !defined(CONFIG_405EP)
-               /* 405EP has one EWU interrupt */
-               irq_install_handler (VECNUM_EWU0 + (hw_p->devnum * 2),
-                                    (interrupt_handler_t *) enetInt, dev);
-#endif
                irq_install_handler (VECNUM_ETH0 + (hw_p->devnum * 2),
                                     (interrupt_handler_t *) enetInt, dev);
        }
@@ -942,6 +953,7 @@ int ppc_4xx_eth_initialize (bd_t * bis)
                                "Cannot allocate eth_device %d\n", eth_num);
                        return (-1);
                }
+               memset(dev, 0, sizeof(*dev));
                /* Allocate our private use data */
                hw = (EMAC_405_HW_PST) malloc (sizeof (*hw));
                if (hw == NULL) {
@@ -951,6 +963,7 @@ int ppc_4xx_eth_initialize (bd_t * bis)
                        free (dev);
                        return (-1);
                }
+               memset(hw, 0, sizeof(*hw));
 
                switch (eth_num) {
                case 0:
@@ -989,12 +1002,6 @@ int ppc_4xx_eth_initialize (bd_t * bis)
                        mtdcr (malrxdeir, 0xffffffff);  /* clear pending interrupts */
                        mtdcr (malier, mal_ier);
 
-#if defined(CONFIG_405EP)
-                       /* 405EP has one EWU interrupt */
-                       irq_install_handler (VECNUM_EWU0,
-                                            (interrupt_handler_t *) enetInt,
-                                            dev);
-#endif
                        /* install MAL interrupt handler */
                        irq_install_handler (VECNUM_MS,
                                             (interrupt_handler_t *) enetInt,