mpc83xx: mpc8360emds: Use RGMII-ID mode, add workarounds for rev. 2.1 CPUs
authorAnton Vorontsov <avorontsov@ru.mvista.com>
Wed, 16 Sep 2009 19:21:59 +0000 (23:21 +0400)
committerKim Phillips <kim.phillips@freescale.com>
Fri, 25 Sep 2009 23:25:51 +0000 (18:25 -0500)
This patch fixes various ethernet issues with gigabit links handling
in U-Boot. The workarounds originally implemented by Kim Phillips for
Linux kernel.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
board/freescale/mpc8360emds/mpc8360emds.c
include/configs/MPC8360EMDS.h

index 769eb2f..54f2989 100644 (file)
 #endif
 #include <spd_sdram.h>
 #include <asm/mmu.h>
+#include <asm/io.h>
 #if defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #endif
 #if defined(CONFIG_PQ_MDS_PIB)
 #include "../common/pq-mds-pib.h"
 #endif
+#include "../../../drivers/qe/uec.h"
 
 const qe_iop_conf_t qe_iop_conf_tab[] = {
        /* GETH1 */
@@ -89,11 +91,19 @@ const qe_iop_conf_t qe_iop_conf_tab[] = {
        {0,  0, 0, 0, QE_IOP_TAB_END}, /* END of table */
 };
 
-int board_early_init_f(void)
+/* Handle "mpc8360ea rev.2.1 erratum 2: RGMII Timing"? */
+static int board_handle_erratum2(void)
 {
+       const immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 
-       u8 *bcsr = (u8 *)CONFIG_SYS_BCSR;
+       return REVID_MAJOR(immr->sysconf.spridr) == 2 &&
+              REVID_MINOR(immr->sysconf.spridr) == 1;
+}
+
+int board_early_init_f(void)
+{
        const immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+       u8 *bcsr = (u8 *)CONFIG_SYS_BCSR;
 
        /* Enable flash write */
        bcsr[0xa] &= ~0x04;
@@ -105,6 +115,21 @@ int board_early_init_f(void)
        /* Enable second UART */
        bcsr[0x9] &= ~0x01;
 
+       if (board_handle_erratum2()) {
+               void *immap = (immap_t *)(CONFIG_SYS_IMMR + 0x14a8);
+
+               /*
+                * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
+                * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
+                */
+               setbits_be32(immap, 0x0c003000);
+
+               /*
+                * IMMR + 0x14AC[20:27] = 10101010
+                * (data delay for both UCC's)
+                */
+               clrsetbits_be32(immap + 4, 0xff0, 0xaa0);
+       }
        return 0;
 }
 
@@ -116,6 +141,28 @@ int board_early_init_r(void)
        return 0;
 }
 
+#ifdef CONFIG_UEC_ETH
+static uec_info_t uec_info[] = {
+#ifdef CONFIG_UEC_ETH1
+       STD_UEC_INFO(1),
+#endif
+#ifdef CONFIG_UEC_ETH2
+       STD_UEC_INFO(2),
+#endif
+};
+
+int board_eth_init(bd_t *bd)
+{
+       if (board_handle_erratum2()) {
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(uec_info); i++)
+                       uec_info[i].enet_interface = ENET_1000_RGMII_RXID;
+       }
+       return uec_eth_init(bd, uec_info, ARRAY_SIZE(uec_info));
+}
+#endif /* CONFIG_UEC_ETH */
+
 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 extern void ddr_enable_ecc(unsigned int dram_size);
 #endif
@@ -312,8 +359,6 @@ static int sdram_init(unsigned int base) { return 0; }
 #if defined(CONFIG_OF_BOARD_SETUP)
 void ft_board_setup(void *blob, bd_t *bd)
 {
-       const immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-
        ft_cpu_setup(blob, bd);
 #ifdef CONFIG_PCI
        ft_pci_setup(blob, bd);
@@ -323,8 +368,7 @@ void ft_board_setup(void *blob, bd_t *bd)
         * if on mpc8360ea rev. 2.1,
         * change both ucc phy-connection-types from rgmii-id to rgmii-rxid
         */
-       if ((REVID_MAJOR(immr->sysconf.spridr) == 2) &&
-           (REVID_MINOR(immr->sysconf.spridr) == 1)) {
+       if (board_handle_erratum2()) {
                int nodeoffset;
                const char *prop;
                int path;
index b072e84..fec7cc5 100644 (file)
 #define CONFIG_SYS_UEC1_TX_CLK         QE_CLK9
 #define CONFIG_SYS_UEC1_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR       0
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_GMII
+#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
 #endif
 
 #define CONFIG_UEC_ETH2                /* GETH2 */
 #define CONFIG_SYS_UEC2_TX_CLK         QE_CLK4
 #define CONFIG_SYS_UEC2_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR       1
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_GMII
+#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
 #endif
 
 /*