From 8ac41e3e37c3080c6b1d9461d654161cfe2aa492 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 11 Mar 2008 15:05:26 +0100 Subject: [PATCH] ppc4xx: Add basic support for AMCC 460EX/460GT (1/5) This patch adds basic support for the AMCC 460EX/460GT PPC's. Signed-off-by: Stefan Roese --- cpu/ppc4xx/44x_spd_ddr2.c | 41 +++++- cpu/ppc4xx/4xx_enet.c | 369 +++++++++++++++++++++++++++++++++++++--------- cpu/ppc4xx/4xx_pci.c | 9 +- cpu/ppc4xx/4xx_pcie.c | 203 ++++++++++++++++++++++++- cpu/ppc4xx/4xx_uart.c | 24 ++- 5 files changed, 553 insertions(+), 93 deletions(-) diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 3bafea3..9e722b9 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -42,7 +42,8 @@ #include #if defined(CONFIG_SPD_EEPROM) && \ - (defined(CONFIG_440SP) || defined(CONFIG_440SPE)) + (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT)) /*-----------------------------------------------------------------------------+ * Defines @@ -579,6 +580,13 @@ long int initdram(int board_type) ppc440sp_sdram_register_dump(); + /* + * Clear potential errors resulting from auto-calibration. + * If not done, then we could get an interrupt later on when + * exceptions are enabled. + */ + set_mcsr(get_mcsr()); + return dram_size; } @@ -2125,6 +2133,7 @@ static void program_memory_queue(unsigned long *dimm_populated, unsigned long baseadd_size; unsigned long i; unsigned long bank_0_populated = 0; + unsigned long total_size = 0; /*------------------------------------------------------------------ * Reset the rank_base_address. @@ -2147,28 +2156,38 @@ static void program_memory_queue(unsigned long *dimm_populated, * Set the sizes *-----------------------------------------------------------------*/ baseadd_size = 0; - rank_size_bytes = 4 * 1024 * 1024 * rank_size_id; switch (rank_size_id) { + case 0x01: + baseadd_size |= SDRAM_RXBAS_SDSZ_1024; + total_size = 1024; + break; case 0x02: - baseadd_size |= SDRAM_RXBAS_SDSZ_8; + baseadd_size |= SDRAM_RXBAS_SDSZ_2048; + total_size = 2048; break; case 0x04: - baseadd_size |= SDRAM_RXBAS_SDSZ_16; + baseadd_size |= SDRAM_RXBAS_SDSZ_4096; + total_size = 4096; break; case 0x08: baseadd_size |= SDRAM_RXBAS_SDSZ_32; + total_size = 32; break; case 0x10: baseadd_size |= SDRAM_RXBAS_SDSZ_64; + total_size = 64; break; case 0x20: baseadd_size |= SDRAM_RXBAS_SDSZ_128; + total_size = 128; break; case 0x40: baseadd_size |= SDRAM_RXBAS_SDSZ_256; + total_size = 256; break; case 0x80: baseadd_size |= SDRAM_RXBAS_SDSZ_512; + total_size = 512; break; default: printf("DDR-SDRAM: DIMM %d memory queue configuration.\n", @@ -2178,6 +2197,7 @@ static void program_memory_queue(unsigned long *dimm_populated, printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); } + rank_size_bytes = total_size << 20; if ((dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_num == 1)) bank_0_populated = 1; @@ -2190,6 +2210,19 @@ static void program_memory_queue(unsigned long *dimm_populated, } } } + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) + /* + * Enable high bandwidth access on 460EX/GT. + * This should/could probably be done on other + * PPC's too, like 440SPe. + * This is currently not used, but with this setup + * it is possible to use it later on in e.g. the Linux + * EMAC driver for performance gain. + */ + mtdcr(SDRAM_PLBADDULL, 0x00000000); /* MQ0_BAUL */ + mtdcr(SDRAM_PLBADDUHB, 0x00000008); /* MQ0_BAUH */ +#endif } /*-----------------------------------------------------------------------------+ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index 599f5ce..d990250 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -137,17 +137,32 @@ #define BI_PHYMODE_RTBI 4 #define BI_PHYMODE_TBI 5 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) #define BI_PHYMODE_SMII 6 #define BI_PHYMODE_MII 7 +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define BI_PHYMODE_RMII 8 +#endif #endif #if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) #define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1)) #endif +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define SDR0_ETH_CFG_CLK_SEL_V(n) (0x01 << (8 + n)) +#endif + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define MAL_RX_CHAN_MUL 8 /* 460EX/GT uses MAL channel 8 for EMAC1 */ +#else +#define MAL_RX_CHAN_MUL 1 +#endif + /*-----------------------------------------------------------------------------+ * Global variables. TX and RX descriptors and buffers. *-----------------------------------------------------------------------------*/ @@ -214,6 +229,44 @@ extern int emac4xx_miiphy_write (char *devname, unsigned char addr, int board_emac_count(void); +static void emac_loopback_enable(EMAC_4XX_HW_PST hw_p) +{ +#if defined(CONFIG_440SPE) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_405EX) + u32 val; + + mfsdr(sdr_mfr, val); + val |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); + mtsdr(sdr_mfr, val); +#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) + u32 val; + + mfsdr(SDR0_ETH_CFG, val); + val |= SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum); + mtsdr(SDR0_ETH_CFG, val); +#endif +} + +static void emac_loopback_disable(EMAC_4XX_HW_PST hw_p) +{ +#if defined(CONFIG_440SPE) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_405EX) + u32 val; + + mfsdr(sdr_mfr, val); + val &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); + mtsdr(sdr_mfr, val); +#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) + u32 val; + + mfsdr(SDR0_ETH_CFG, val); + val &= ~SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum); + mtsdr(SDR0_ETH_CFG, val); +#endif +} + /*-----------------------------------------------------------------------------+ | ppc_4xx_eth_halt | Disable MAL channel, and EMACn @@ -222,11 +275,6 @@ static void ppc_4xx_eth_halt (struct eth_device *dev) { EMAC_4XX_HW_PST hw_p = dev->priv; uint32_t failsafe = 10000; -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) - unsigned long mfr; -#endif out_be32((void *)EMAC_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */ @@ -247,27 +295,14 @@ static void ppc_4xx_eth_halt (struct eth_device *dev) break; } - /* EMAC RESET */ -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) /* provide clocks for EMAC internal loopback */ - mfsdr (sdr_mfr, mfr); - mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); - mtsdr(sdr_mfr, mfr); -#endif + emac_loopback_enable(hw_p); + /* EMAC RESET */ out_be32((void *)EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST); -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) /* remove clocks for EMAC internal loopback */ - mfsdr (sdr_mfr, mfr); - mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); - mtsdr(sdr_mfr, mfr); -#endif - + emac_loopback_disable(hw_p); #ifndef CONFIG_NETCONSOLE hw_p->print_speed = 1; /* print speed message again next time */ @@ -452,6 +487,187 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) } #endif /* CONFIG_405EX */ +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) +{ + u32 eth_cfg; + u32 zmiifer; /* ZMII0_FER reg. */ + u32 rmiifer; /* RGMII0_FER reg. Bridge 0 */ + u32 rmiifer1; /* RGMII0_FER reg. Bridge 1 */ + + zmiifer = 0; + rmiifer = 0; + rmiifer1 = 0; + + /* TODO: + * NOTE: 460GT has 2 RGMII bridge cores: + * emac0 ------ RGMII0_BASE + * | + * emac1 -----+ + * + * emac2 ------ RGMII1_BASE + * | + * emac3 -----+ + * + * 460EX has 1 RGMII bridge core: + * and RGMII1_BASE is disabled + * emac0 ------ RGMII0_BASE + * | + * emac1 -----+ + */ + + /* + * Right now only 2*RGMII is supported. Please extend when needed. + * sr - 2008-02-19 + */ + switch (9) { + case 1: + /* 1 MII - 460EX */ + /* GMC0 EMAC4_0, ZMII Bridge */ + zmiifer |= ZMII_FER_MII << ZMII_FER_V(0); + bis->bi_phymode[0] = BI_PHYMODE_MII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 2: + /* 2 MII - 460GT */ + /* GMC0 EMAC4_0, GMC1 EMAC4_2, ZMII Bridge */ + zmiifer |= ZMII_FER_MII << ZMII_FER_V(0); + zmiifer |= ZMII_FER_MII << ZMII_FER_V(2); + bis->bi_phymode[0] = BI_PHYMODE_MII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + bis->bi_phymode[2] = BI_PHYMODE_MII; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 3: + /* 2 RMII - 460EX */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */ + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1); + bis->bi_phymode[0] = BI_PHYMODE_RMII; + bis->bi_phymode[1] = BI_PHYMODE_RMII; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 4: + /* 4 RMII - 460GT */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC1 EMAC4_2, GMC1, EMAC4_3 */ + /* ZMII Bridge */ + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1); + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(2); + zmiifer |= ZMII_FER_RMII << ZMII_FER_V(3); + bis->bi_phymode[0] = BI_PHYMODE_RMII; + bis->bi_phymode[1] = BI_PHYMODE_RMII; + bis->bi_phymode[2] = BI_PHYMODE_RMII; + bis->bi_phymode[3] = BI_PHYMODE_RMII; + break; + case 5: + /* 2 SMII - 460EX */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */ + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); + bis->bi_phymode[0] = BI_PHYMODE_SMII; + bis->bi_phymode[1] = BI_PHYMODE_SMII; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 6: + /* 4 SMII - 460GT */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC0 EMAC4_3, GMC0 EMAC4_3 */ + /* ZMII Bridge */ + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2); + zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3); + bis->bi_phymode[0] = BI_PHYMODE_SMII; + bis->bi_phymode[1] = BI_PHYMODE_SMII; + bis->bi_phymode[2] = BI_PHYMODE_SMII; + bis->bi_phymode[3] = BI_PHYMODE_SMII; + break; + case 7: + /* This is the default mode that we want for board bringup - Maple */ + /* 1 GMII - 460EX */ + /* GMC0 EMAC4_0, RGMII Bridge 0 */ + rmiifer |= RGMII_FER_MDIO(0); + + if (devnum == 0) { + rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC0 */ + bis->bi_phymode[0] = BI_PHYMODE_GMII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + } else { + rmiifer |= RGMII_FER_GMII << RGMII_FER_V(3); /* CH1CFG - EMAC1 */ + bis->bi_phymode[0] = BI_PHYMODE_NONE; + bis->bi_phymode[1] = BI_PHYMODE_GMII; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + } + break; + case 8: + /* 2 GMII - 460GT */ + /* GMC0 EMAC4_0, RGMII Bridge 0 */ + /* GMC1 EMAC4_2, RGMII Bridge 1 */ + rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC0 */ + rmiifer1 |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC2 */ + rmiifer |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC0 */ + rmiifer1 |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC2 */ + + bis->bi_phymode[0] = BI_PHYMODE_GMII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + bis->bi_phymode[2] = BI_PHYMODE_GMII; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 9: + /* 2 RGMII - 460EX */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */ + rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); + rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3); + rmiifer |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC0 */ + + bis->bi_phymode[0] = BI_PHYMODE_RGMII; + bis->bi_phymode[1] = BI_PHYMODE_RGMII; + bis->bi_phymode[2] = BI_PHYMODE_NONE; + bis->bi_phymode[3] = BI_PHYMODE_NONE; + break; + case 10: + /* 4 RGMII - 460GT */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */ + /* GMC1 EMAC4_2, GMC1 EMAC4_3, RGMII Bridge 1 */ + rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); + rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3); + rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(2); + rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(3); + bis->bi_phymode[0] = BI_PHYMODE_RGMII; + bis->bi_phymode[1] = BI_PHYMODE_RGMII; + bis->bi_phymode[2] = BI_PHYMODE_RGMII; + bis->bi_phymode[3] = BI_PHYMODE_RGMII; + break; + default: + break; + } + + /* Set EMAC for MDIO */ + mfsdr(SDR0_ETH_CFG, eth_cfg); + eth_cfg |= SDR0_ETH_CFG_MDIO_SEL_EMAC0; + mtsdr(SDR0_ETH_CFG, eth_cfg); + + out_be32((void *)RGMII_FER, rmiifer); +#if defined(CONFIG_460GT) + out_be32((void *)RGMII_FER + RGMII1_BASE_OFFSET, rmiifer1); +#endif + + /* bypass the TAHOE0/TAHOE1 cores for U-Boot */ + mfsdr(SDR0_ETH_CFG, eth_cfg); + eth_cfg |= (SDR0_ETH_CFG_TAHOE0_BYPASS | SDR0_ETH_CFG_TAHOE1_BYPASS); + mtsdr(SDR0_ETH_CFG, eth_cfg); + + return 0; +} +#endif /* CONFIG_460EX || CONFIG_460GT */ + static inline void *malloc_aligned(u32 size, u32 align) { return (void *)(((u32)malloc(size + align) + align - 1) & @@ -472,19 +688,16 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) #if defined(CONFIG_440GX) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) sys_info_t sysinfo; #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) int ethgroup = -1; #endif #endif -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_405EX) - unsigned long mfr; -#endif u32 bd_cached; u32 bd_uncached = 0; #ifdef CONFIG_4xx_DCACHE @@ -503,6 +716,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) #if defined(CONFIG_440GX) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) /* Need to get the OPB frequency so we can access the PHY */ get_sys_info (&sysinfo); @@ -556,21 +770,12 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) out_be32((void *)ZMII_FER, 0); udelay (100); -#if defined(CONFIG_440EP) || defined(CONFIG_440GR) +#if defined(CONFIG_440GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) out_be32((void *)ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum)); -#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX) +#elif defined(CONFIG_440GX) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis); -#elif defined(CONFIG_440GP) - /* set RMII mode */ - out_be32((void *)ZMII_FER, ZMII_RMII | ZMII_MDI0); -#else - if ((devnum == 0) || (devnum == 1)) { - out_be32((void *)ZMII_FER, (ZMII_FER_SMII | ZMII_FER_MDI) << ZMII_FER_V (devnum)); - } else { /* ((devnum == 2) || (devnum == 3)) */ - out_be32((void *)ZMII_FER, ZMII_FER_MDI << ZMII_FER_V (devnum)); - out_be32((void *)RGMII_FER, ((RGMII_FER_RGMII << RGMII_FER_V (2)) | - (RGMII_FER_RGMII << RGMII_FER_V (3)))); - } #endif out_be32((void *)ZMII_SSR, ZMII_SSR_SP << ZMII_SSR_V(devnum)); @@ -579,20 +784,17 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis); #endif - __asm__ volatile ("eieio"); + sync(); - /* reset emac so we have access to the phy */ -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) /* provide clocks for EMAC internal loopback */ - mfsdr (sdr_mfr, mfr); - mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum); - mtsdr(sdr_mfr, mfr); -#endif + emac_loopback_enable(hw_p); + /* EMAC RESET */ out_be32((void *)EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST); + /* remove clocks for EMAC internal loopback */ + emac_loopback_disable(hw_p); + failsafe = 1000; while ((in_be32((void *)EMAC_M0 + hw_p->hw_addr) & (EMAC_M0_SRST)) && failsafe) { udelay (1000); @@ -601,18 +803,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) if (failsafe <= 0) printf("\nProblem resetting EMAC!\n"); -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) - /* remove clocks for EMAC internal loopback */ - mfsdr (sdr_mfr, mfr); - mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum); - mtsdr(sdr_mfr, mfr); -#endif - #if defined(CONFIG_440GX) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) /* Whack the M1 register */ mode_reg = 0x0; @@ -674,6 +868,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) #if defined(CONFIG_440GX) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) #if defined(CONFIG_CIS8201_PHY) @@ -772,8 +967,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) hw_p->devnum); } -#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ - !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) +#if defined(CONFIG_440) && \ + !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ + !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \ + !defined(CONFIG_460EX) && !defined(CONFIG_460GT) #if defined(CONFIG_440EP) || defined(CONFIG_440GR) mfsdr(sdr_mfr, reg); if (speed == 100) { @@ -807,6 +1004,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) #endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */ #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) if (speed == 1000) reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum)); @@ -819,12 +1017,17 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) return -1; } out_be32((void *)RGMII_SSR, reg); +#if defined(CONFIG_460GT) + if ((devnum == 2) || (devnum == 3)) + out_be32((void *)RGMII_SSR + RGMII1_BASE_OFFSET, reg); +#endif #endif /* set the Mal configuration reg */ #if defined(CONFIG_440GX) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000); @@ -926,9 +1129,16 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) mtdcr (maltxbattr, 0x0); mtdcr (malrxbattr, 0x0); #endif + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) + mtdcr (malrxctp8r, hw_p->rx); + /* set RX buffer size */ + mtdcr (malrcbs8, ENET_MAX_MTU_ALIGNED / 16); +#else mtdcr (malrxctp1r, hw_p->rx_phys); /* set RX buffer size */ mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16); +#endif break; #if defined (CONFIG_440GX) case 2: @@ -1087,7 +1297,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, hw_p->tx[hw_p->tx_slot].data_len = (short) len; hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_READY; - __asm__ volatile ("eieio"); + sync(); out_be32((void *)EMAC_TXM0 + hw_p->hw_addr, in_be32((void *)EMAC_TXM0 + hw_p->hw_addr) | EMAC_TXM0_GNP0); @@ -1127,15 +1337,31 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, */ #define UIC0MSR uic1msr #define UIC0SR uic1sr +#define UIC1MSR uic1msr +#define UIC1SR uic1sr +#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) +/* + * Hack: On 460EX/GT all enet irq sources are located on UIC2 + * Needs some cleanup. --ag + */ +#define UIC0MSR uic2msr +#define UIC0SR uic2sr +#define UIC1MSR uic2msr +#define UIC1SR uic2sr #else #define UIC0MSR uic0msr #define UIC0SR uic0sr +#define UIC1MSR uic1msr +#define UIC1SR uic1sr #endif #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_405EX) #define UICMSR_ETHX uic0msr #define UICSR_ETHX uic0sr +#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define UICMSR_ETHX uic2msr +#define UICSR_ETHX uic2sr #else #define UICMSR_ETHX uic1msr #define UICSR_ETHX uic1sr @@ -1173,7 +1399,7 @@ int enetInt (struct eth_device *dev) serviced = 0; my_uic0msr = mfdcr (UIC0MSR); - my_uic1msr = mfdcr (uic1msr); + my_uic1msr = mfdcr (UIC1MSR); #if defined(CONFIG_440GX) my_uic2msr = mfdcr (uic2msr); #endif @@ -1219,7 +1445,7 @@ int enetInt (struct eth_device *dev) if ((hw_p->emac_ier & emac_isr) || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ + mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */ return (rc); /* we had errors so get out */ } @@ -1238,7 +1464,7 @@ int enetInt (struct eth_device *dev) if ((hw_p->emac_ier & emac_isr) || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ + mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */ return (rc); /* we had errors so get out */ } @@ -1256,7 +1482,7 @@ int enetInt (struct eth_device *dev) if ((hw_p->emac_ier & emac_isr) || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ + mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ mtdcr (uic2sr, UIC_ETH2); return (rc); /* we had errors so get out */ } @@ -1274,7 +1500,7 @@ int enetInt (struct eth_device *dev) if ((hw_p->emac_ier & emac_isr) || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ + mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ mtdcr (uic2sr, UIC_ETH3); return (rc); /* we had errors so get out */ } @@ -1292,7 +1518,9 @@ int enetInt (struct eth_device *dev) /* check for EOB on valid channels */ if (my_uic0msr & UIC_MRE) { mal_rx_eob = mfdcr (malrxeobisr); - if ((mal_rx_eob & (0x80000000 >> hw_p->devnum)) != 0) { /* call emac routine for channel x */ + if ((mal_rx_eob & + (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) + != 0) { /* call emac routine for channel x */ /* clear EOB mtdcr(malrxeobisr, mal_rx_eob); */ enet_rcv (dev, emac_isr); @@ -1303,7 +1531,7 @@ int enetInt (struct eth_device *dev) } mtdcr (UIC0SR, UIC_MRE); /* Clear */ - mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ + mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ switch (hw_p->devnum) { case 0: mtdcr (UICSR_ETHX, UIC_ETH0); @@ -1468,7 +1696,7 @@ static void enet_rcv (struct eth_device *dev, unsigned long malisr) int loop_count = 0; rx_eob_isr = mfdcr (malrxeobisr); - if ((0x80000000 >> hw_p->devnum) & rx_eob_isr) { + if ((0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL)) & rx_eob_isr) { /* clear EOB */ mtdcr (malrxeobisr, rx_eob_isr); @@ -1482,7 +1710,7 @@ static void enet_rcv (struct eth_device *dev, unsigned long malisr) loop_count++; handled++; - data_len = (unsigned long) hw_p->rx[i].data_len; /* Get len */ + data_len = (unsigned long) hw_p->rx[i].data_len & 0x0fff; /* Get len */ if (data_len) { if (data_len > ENET_MAX_MTU) /* Check len */ data_len = 0; @@ -1568,7 +1796,7 @@ static int ppc_4xx_eth_rx (struct eth_device *dev) msr = mfmsr (); mtmsr (msr & ~(MSR_EE)); - length = hw_p->rx[user_index].data_len; + length = hw_p->rx[user_index].data_len & 0x0fff; /* Pass the packet up to the protocol layers. */ /* NetReceive(NetRxPackets[rxIdx], length - 4); */ @@ -1718,6 +1946,7 @@ int ppc_4xx_eth_initialize (bd_t * bis) /* set the MAL IER ??? names may change with new spec ??? */ #if defined(CONFIG_440SPE) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) mal_ier = MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE | diff --git a/cpu/ppc4xx/4xx_pci.c b/cpu/ppc4xx/4xx_pci.c index a5b9690..941d4dc 100644 --- a/cpu/ppc4xx/4xx_pci.c +++ b/cpu/ppc4xx/4xx_pci.c @@ -531,7 +531,8 @@ int pci_440_init (struct pci_controller *hose) out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */ #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) out32r( PCIX0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */ out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */ #elif defined(PCIX0_BRDGOPT1) @@ -549,7 +550,8 @@ int pci_440_init (struct pci_controller *hose) out32r( PCIX0_POM0SA, 0 ); /* disable */ out32r( PCIX0_POM1SA, 0 ); /* disable */ out32r( PCIX0_POM2SA, 0 ); /* disable */ -#if defined(CONFIG_440SPE) +#if defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) out32r( PCIX0_POM0LAL, 0x10000000 ); out32r( PCIX0_POM0LAH, 0x0000000c ); #else @@ -586,7 +588,8 @@ void pci_init_board(void) int busno; busno = pci_440_init (&ppc440_hose); -#if defined(CONFIG_440SPE) +#if defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) pcie_setup_hoses(busno + 1); #endif } diff --git a/cpu/ppc4xx/4xx_pcie.c b/cpu/ppc4xx/4xx_pcie.c index 3af9862..f9a1988 100644 --- a/cpu/ppc4xx/4xx_pcie.c +++ b/cpu/ppc4xx/4xx_pcie.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2006 - 2007 + * (C) Copyright 2006 - 2008 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * Copyright (c) 2005 Cisco Systems. All rights reserved. @@ -31,7 +31,8 @@ #include #include -#if (defined(CONFIG_440SPE) || defined(CONFIG_405EX)) && \ +#if (defined(CONFIG_440SPE) || defined(CONFIG_405EX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT)) && \ defined(CONFIG_PCI) #include @@ -306,9 +307,8 @@ static int check_error(void) int err = 0; /* SDR0_PEGPLLLCT1 reset */ - if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) { + if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0); - } valPE0 = SDR_READ(PESDR0_RCSSET); valPE1 = SDR_READ(PESDR1_RCSSET); @@ -400,7 +400,108 @@ int ppc4xx_init_pcie(void) } return 0; } -#else +#endif + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +static void ppc4xx_setup_utl(u32 port) +{ + volatile void *utl_base = NULL; + + /* + * Map UTL registers at 0x0801_n000 (4K 0xfff mask) PEGPLn_REGMSK + */ + switch (port) { + case 0: + mtdcr(DCRN_PEGPL_REGBAH(PCIE0), U64_TO_U32_HIGH(CFG_PCIE0_UTLBASE)); + mtdcr(DCRN_PEGPL_REGBAL(PCIE0), U64_TO_U32_LOW(CFG_PCIE0_UTLBASE)); + mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); /* BAM 11100000=4KB */ + mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0); + break; + + case 1: + mtdcr(DCRN_PEGPL_REGBAH(PCIE1), U64_TO_U32_HIGH(CFG_PCIE0_UTLBASE)); + mtdcr(DCRN_PEGPL_REGBAL(PCIE1), U64_TO_U32_LOW(CFG_PCIE0_UTLBASE) + + 0x1000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); /* BAM 11100000=4KB */ + mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0); + break; + } + utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port); + + /* + * Set buffer allocations and then assert VRB and TXE. + */ + out_be32(utl_base + PEUTL_PBCTL, 0x0800000c); /* PLBME, CRRE */ + out_be32(utl_base + PEUTL_OUTTR, 0x08000000); + out_be32(utl_base + PEUTL_INTR, 0x02000000); + out_be32(utl_base + PEUTL_OPDBSZ, 0x04000000); /* OPD = 512 Bytes */ + out_be32(utl_base + PEUTL_PBBSZ, 0x00000000); /* Max 512 Bytes */ + out_be32(utl_base + PEUTL_IPHBSZ, 0x02000000); + out_be32(utl_base + PEUTL_IPDBSZ, 0x04000000); /* IPD = 512 Bytes */ + out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); + out_be32(utl_base + PEUTL_PCTL, 0x80800066); /* VRB,TXE,timeout=default */ +} + +/* + * TODO: double check PCI express SDR based on the latest user manual + * Some registers specified here no longer exist.. has to be + * updated based on the final EAS spec. + */ +static int check_error(void) +{ + u32 valPE0, valPE1; + int err = 0; + + valPE0 = SDR_READ(SDRN_PESDR_RCSSET(0)); + valPE1 = SDR_READ(SDRN_PESDR_RCSSET(1)); + + /* SDR0_PExRCSSET rstgu */ + if (!(valPE0 & PESDRx_RCSSET_RSTGU) || !(valPE1 & PESDRx_RCSSET_RSTGU)) { + printf("PCIE: SDR0_PExRCSSET rstgu error\n"); + err = -1; + } + + /* SDR0_PExRCSSET rstdl */ + if (!(valPE0 & PESDRx_RCSSET_RSTDL) || !(valPE1 & PESDRx_RCSSET_RSTDL)) { + printf("PCIE: SDR0_PExRCSSET rstdl error\n"); + err = -1; + } + + /* SDR0_PExRCSSET rstpyn */ + if ((valPE0 & PESDRx_RCSSET_RSTPYN) || (valPE1 & PESDRx_RCSSET_RSTPYN)) { + printf("PCIE: SDR0_PExRCSSET rstpyn error\n"); + err = -1; + } + + /* SDR0_PExRCSSET hldplb */ + if ((valPE0 & PESDRx_RCSSET_HLDPLB) || (valPE1 & PESDRx_RCSSET_HLDPLB)) { + printf("PCIE: SDR0_PExRCSSET hldplb error\n"); + err = -1; + } + + /* SDR0_PExRCSSET rdy */ + if ((valPE0 & PESDRx_RCSSET_RDY) || (valPE1 & PESDRx_RCSSET_RDY)) { + printf("PCIE: SDR0_PExRCSSET rdy error\n"); + err = -1; + } + + return err; +} + +/* + * Initialize PCI Express core as described in User Manual + * TODO: double check PE SDR PLL Register with the updated user manual. + */ +int ppc4xx_init_pcie(void) +{ + if (check_error()) + return -1; + + return 0; +} +#endif /* CONFIG_460EX */ + +#if defined(CONFIG_405EX) static void ppc4xx_setup_utl(u32 port) { u32 utl_base; @@ -450,7 +551,7 @@ int ppc4xx_init_pcie(void) */ return 0; } -#endif +#endif /* CONFIG_405EX */ /* * Board-specific pcie initialization @@ -511,6 +612,82 @@ int __ppc4xx_init_pcie_port_hw(int port, int rootport) } #endif /* CONFIG_440SPE */ +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +int __ppc4xx_init_pcie_port_hw(int port, int rootport) +{ + u32 val = 1 << 24; + u32 utlset1; + + if (rootport) { + val = PTYPE_ROOT_PORT << 20; + utlset1 = 0x21222222; + } else { + val = PTYPE_LEGACY_ENDPOINT << 20; + utlset1 = 0x20222222; + } + + if (port == 0) { + val |= LNKW_X1 << 12; + } else { + val |= LNKW_X4 << 12; + utlset1 |= 0x00101101; + } + + SDR_WRITE(SDRN_PESDR_DLPSET(port), val); + SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1); + SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01210000); + + switch (port) { + case 0: + SDR_WRITE(PESDR0_L0CDRCTL, 0x00003230); + SDR_WRITE(PESDR0_L0DRV, 0x00000136); + SDR_WRITE(PESDR0_L0CLK, 0x00000006); + + SDR_WRITE(PESDR0_PHY_CTL_RST,0x10000000); + break; + + case 1: + SDR_WRITE(PESDR1_L0CDRCTL, 0x00003230); + SDR_WRITE(PESDR1_L1CDRCTL, 0x00003230); + SDR_WRITE(PESDR1_L2CDRCTL, 0x00003230); + SDR_WRITE(PESDR1_L3CDRCTL, 0x00003230); + SDR_WRITE(PESDR1_L0DRV, 0x00000136); + SDR_WRITE(PESDR1_L1DRV, 0x00000136); + SDR_WRITE(PESDR1_L2DRV, 0x00000136); + SDR_WRITE(PESDR1_L3DRV, 0x00000136); + SDR_WRITE(PESDR1_L0CLK, 0x00000006); + SDR_WRITE(PESDR1_L1CLK, 0x00000006); + SDR_WRITE(PESDR1_L2CLK, 0x00000006); + SDR_WRITE(PESDR1_L3CLK, 0x00000006); + + SDR_WRITE(PESDR1_PHY_CTL_RST,0x10000000); + break; + } + + SDR_WRITE(SDRN_PESDR_RCSSET(port), SDR_READ(SDRN_PESDR_RCSSET(port)) | + (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); + + /* Poll for PHY reset */ + switch (port) { + case 0: + while (!(SDR_READ(PESDR0_RSTSTA) & 0x1)) + udelay(10); + break; + case 1: + while (!(SDR_READ(PESDR1_RSTSTA) & 0x1)) + udelay(10); + break; + } + + SDR_WRITE(SDRN_PESDR_RCSSET(port), + (SDR_READ(SDRN_PESDR_RCSSET(port)) & + ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | + PESDRx_RCSSET_RSTPYN); + + return 0; +} +#endif /* CONFIG_440SPE */ + #if defined(CONFIG_405EX) int __ppc4xx_init_pcie_port_hw(int port, int rootport) { @@ -564,12 +741,12 @@ __attribute__((weak, alias("__ppc4xx_init_pcie_port_hw"))); * range (hangs the core upon config transaction attempts when set * otherwise) while revA uses c_nnnn_nnnn. * - * For revA: + * For 440SPe revA: * PCIE0: 0xc_4000_0000 * PCIE1: 0xc_8000_0000 * PCIE2: 0xc_c000_0000 * - * For revB: + * For 440SPe revB: * PCIE0: 0xd_0000_0000 * PCIE1: 0xd_2000_0000 * PCIE2: 0xd_4000_0000 @@ -577,6 +754,10 @@ __attribute__((weak, alias("__ppc4xx_init_pcie_port_hw"))); * For 405EX: * PCIE0: 0xa000_0000 * PCIE1: 0xc000_0000 + * + * For 460EX/GT: + * PCIE0: 0xd_0000_0000 + * PCIE1: 0xd_2000_0000 */ static inline u64 ppc4xx_get_cfgaddr(int port) { @@ -609,6 +790,12 @@ static inline u64 ppc4xx_get_cfgaddr(int port) } } #endif +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) + if (port == 0) + return 0x0000000d00000000ULL; + else + return 0x0000000d20000000ULL; +#endif } /* diff --git a/cpu/ppc4xx/4xx_uart.c b/cpu/ppc4xx/4xx_uart.c index 3d1124e..ffbc222 100644 --- a/cpu/ppc4xx/4xx_uart.c +++ b/cpu/ppc4xx/4xx_uart.c @@ -64,16 +64,22 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_440) #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000300 -#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000400 + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define UART0_BASE (CFG_PERIPHERAL_BASE + 0x00000300) +#define UART1_BASE (CFG_PERIPHERAL_BASE + 0x00000400) #else -#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000200 -#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000300 +#define UART0_BASE (CFG_PERIPHERAL_BASE + 0x00000200) +#define UART1_BASE (CFG_PERIPHERAL_BASE + 0x00000300) #endif #if defined(CONFIG_440SP) || defined(CONFIG_440SPE) -#define UART2_BASE CFG_PERIPHERAL_BASE + 0x00000600 +#define UART2_BASE (CFG_PERIPHERAL_BASE + 0x00000600) +#endif + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define UART2_BASE (CFG_PERIPHERAL_BASE + 0x00000500) +#define UART3_BASE (CFG_PERIPHERAL_BASE + 0x00000600) #endif #if defined(CONFIG_440GP) @@ -94,11 +100,13 @@ DECLARE_GLOBAL_DATA_PTR; #define UART1_SDR sdr_uart1 #if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \ defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPe) + defined(CONFIG_440SP) || defined(CONFIG_440SPe) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) #define UART2_SDR sdr_uart2 #endif #if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \ - defined(CONFIG_440GR) || defined(CONFIG_440GRx) + defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) #define UART3_SDR sdr_uart3 #endif #define MFREG(a, d) mfsdr(a, d)