From 89da44ce3fe1638312d71cb3add8c6a6d2c7c1f3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 16 Sep 2009 23:21:59 +0400 Subject: mpc83xx: mpc8360emds: Use RGMII-ID mode, add workarounds for rev. 2.1 CPUs 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 Signed-off-by: Kim Phillips --- board/freescale/mpc8360emds/mpc8360emds.c | 56 +++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) (limited to 'board/freescale') diff --git a/board/freescale/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c index 769eb2f..54f2989 100644 --- a/board/freescale/mpc8360emds/mpc8360emds.c +++ b/board/freescale/mpc8360emds/mpc8360emds.c @@ -21,12 +21,14 @@ #endif #include #include +#include #if defined(CONFIG_OF_LIBFDT) #include #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; -- cgit v1.1