diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu_init.c | 12 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/fdt.c | 24 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c | 66 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/p1022_serdes.c | 38 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/cpu.c | 6 | ||||
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c | 12 | ||||
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/cmd_ecctest.c | 284 | ||||
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/ecc.c | 21 | ||||
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/traps.c | 16 | ||||
-rw-r--r-- | arch/powerpc/include/asm/config.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/fsl_pci.h | 84 | ||||
-rw-r--r-- | arch/powerpc/include/asm/fsl_serdes.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/immap_85xx.h | 20 | ||||
-rw-r--r-- | arch/powerpc/include/asm/immap_86xx.h | 17 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc4xx-sdram.h | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 6 |
19 files changed, 560 insertions, 68 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 4ee0e9a..fe851f1 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -58,7 +58,9 @@ COBJS-$(CONFIG_P1021) += ddr-gen3.o COBJS-$(CONFIG_P1022) += ddr-gen3.o COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o +COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o +COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_CPM2) += ether_fcc.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index fe2b52d..f15d43c 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -179,7 +179,7 @@ int checkcpu (void) #ifdef CONFIG_SYS_DPAA_FMAN for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) { - printf(" FMAN%d: %s MHz\n", i, + printf(" FMAN%d: %s MHz\n", i + 1, strmhz(buf1, sysinfo.freqFMan[i])); } #endif diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index d491e2a..5d5b4c2 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -39,10 +39,6 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_MPC8536 -extern void fsl_serdes_init(void); -#endif - #ifdef CONFIG_QE extern qe_iop_conf_t qe_iop_conf_tab[]; extern void qe_config_iopin(u8 port, u8 pin, int dir, @@ -185,9 +181,6 @@ void cpu_init_f (void) /* Config QE ioports */ config_qe_ioports(); #endif -#if defined(CONFIG_MPC8536) - fsl_serdes_init(); -#endif #if defined(CONFIG_FSL_DMA) dma_init(); #endif @@ -332,6 +325,11 @@ int cpu_init_r(void) qe_reset(); #endif +#if defined(CONFIG_SYS_HAS_SERDES) + /* needs to be in ram since code uses global static vars */ + fsl_serdes_init(); +#endif + #if defined(CONFIG_MP) setup_mp(); #endif diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 2628cc5..932466e 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -298,17 +298,17 @@ void fdt_add_enet_stashing(void *fdt) } #if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME) -static void ft_fixup_clks(void *blob, const char *alias, unsigned long freq) +static void ft_fixup_clks(void *blob, const char *compat, u32 offset, + unsigned long freq) { - const char *path = fdt_get_alias(blob, alias); - - int off = fdt_path_offset(blob, path); + phys_addr_t phys = offset + CONFIG_SYS_CCSRBAR_PHYS; + int off = fdt_node_offset_by_compat_reg(blob, compat, phys); if (off >= 0) { off = fdt_setprop_cell(blob, off, "clock-frequency", freq); if (off > 0) printf("WARNING enable to set clock-frequency " - "for %s: %s\n", alias, fdt_strerror(off)); + "for %s: %s\n", compat, fdt_strerror(off)); } } @@ -317,14 +317,17 @@ static void ft_fixup_dpaa_clks(void *blob) sys_info_t sysinfo; get_sys_info(&sysinfo); - ft_fixup_clks(blob, "fman0", sysinfo.freqFMan[0]); + ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM1_OFFSET, + sysinfo.freqFMan[0]); #if (CONFIG_SYS_NUM_FMAN == 2) - ft_fixup_clks(blob, "fman1", sysinfo.freqFMan[1]); + ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM2_OFFSET, + sysinfo.freqFMan[1]); #endif #ifdef CONFIG_SYS_DPAA_PME - ft_fixup_clks(blob, "pme", sysinfo.freqPME); + do_fixup_by_compat_u32(blob, "fsl,pme", + "clock-frequency", sysinfo.freqPME, 1); #endif } #else @@ -400,6 +403,11 @@ void ft_cpu_setup(void *blob, bd_t *bd) "clock-frequency", bd->bi_brgfreq, 1); #endif +#ifdef CONFIG_FSL_CORENET + do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0", + "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); +#endif + fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); #ifdef CONFIG_MP diff --git a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c index 7e72f5f..6dadeb8 100644 --- a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c @@ -66,10 +66,11 @@ #define FSL_SRDSCR3_LANEE_SGMII 0x00000000 #define FSL_SRDSCR3_LANEE_SATA 0x00150005 - #define SRDS1_MAX_LANES 8 #define SRDS2_MAX_LANES 2 +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { [0x2] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, NONE, NONE}, [0x3] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1}, @@ -86,39 +87,12 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { int is_serdes_configured(enum srds_prtcl device) { - int i; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 pordevsr = in_be32(&gur->pordevsr); - u32 srds1_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> - MPC85xx_PORDEVSR_IO_SEL_SHIFT; + int ret = (1 << device) & serdes1_prtcl_map; - u32 srds2_cfg = (pordevsr & MPC85xx_PORDEVSR_SRDS2_IO_SEL) >> - GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT; - - debug("%s: dev = %d\n", __FUNCTION__, device); - debug("PORDEVSR[IO_SEL] = %x\n", srds1_cfg); - debug("PORDEVSR[SRDS2_IO_SEL] = %x\n", srds2_cfg); - - if (srds1_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) { - printf("Invalid PORDEVSR[IO_SEL] = %d\n", srds1_cfg); - return 0; - } - - if (srds2_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { - printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_cfg); - return 0; - } - - for (i = 0; i < SRDS1_MAX_LANES; i++) { - if (serdes1_cfg_tbl[srds1_cfg][i] == device) - return 1; - } - for (i = 0; i < SRDS2_MAX_LANES; i++) { - if (serdes2_cfg_tbl[srds2_cfg][i] == device) - return 1; - } + if (ret) + return ret; - return 0; + return (1 << device) & serdes2_prtcl_map; } void fsl_serdes_init(void) @@ -126,13 +100,20 @@ void fsl_serdes_init(void) void *guts = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); void *sd = (void *)CONFIG_SYS_MPC85xx_SERDES2_ADDR; u32 pordevsr = in_be32(guts + GUTS_PORDEVSR_OFFS); - u32 srds2_io_sel; + u32 srds1_io_sel, srds2_io_sel; u32 tmp; + int lane; + + srds1_io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> + MPC85xx_PORDEVSR_IO_SEL_SHIFT; /* parse the SRDS2_IO_SEL of PORDEVSR */ srds2_io_sel = (pordevsr & GUTS_PORDEVSR_SERDES2_IO_SEL) >> GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT; + debug("PORDEVSR[SRDS1_IO_SEL] = %x\n", srds1_io_sel); + debug("PORDEVSR[SRDS2_IO_SEL] = %x\n", srds2_io_sel); + switch (srds2_io_sel) { case 1: /* Lane A - SATA1, Lane E - SATA2 */ /* CR 0 */ @@ -246,4 +227,23 @@ void fsl_serdes_init(void) default: break; } + + if (srds1_io_sel > ARRAY_SIZE(serdes1_cfg_tbl)) { + printf("Invalid PORDEVSR[SRDS1_IO_SEL] = %d\n", srds1_io_sel); + return; + } + for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds1_io_sel][lane]; + serdes1_prtcl_map |= (1 << lane_prtcl); + } + + if (srds2_io_sel > ARRAY_SIZE(serdes2_cfg_tbl)) { + printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel); + return; + } + + for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds2_io_sel][lane]; + serdes2_prtcl_map |= (1 << lane_prtcl); + } } diff --git a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c index 6b0fbf2..e4c9c22 100644 --- a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c @@ -17,6 +17,8 @@ #define SRDS1_MAX_LANES 4 #define SRDS2_MAX_LANES 2 +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + static const u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { [0x00] = {NONE, NONE, NONE, NONE}, [0x01] = {NONE, NONE, NONE, NONE}, @@ -73,26 +75,40 @@ static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { int is_serdes_configured(enum srds_prtcl device) { + int ret = (1 << device) & serdes1_prtcl_map; + + if (ret) + return ret; + + return (1 << device) & serdes2_prtcl_map; +} + +void fsl_serdes_init(void) +{ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; u32 pordevsr = in_be32(&gur->pordevsr); u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> MPC85xx_PORDEVSR_IO_SEL_SHIFT; - unsigned int i; + int lane; - debug("%s: dev = %d\n", __FUNCTION__, device); - debug("PORDEVSR[IO_SEL] = 0x%x\n", srds_cfg); + debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg); if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) { - printf("Invalid PORDEVSR[IO_SEL] = %d\n", srds_cfg); - return 0; + printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); + return; + } + for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane]; + serdes1_prtcl_map |= (1 << lane_prtcl); } - for (i = 0; i < SRDS1_MAX_LANES; i++) { - if (serdes1_cfg_tbl[srds_cfg][i] == device) - return 1; - if (serdes2_cfg_tbl[srds_cfg][i] == device) - return 1; + if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { + printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); + return; } - return 0; + for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane]; + serdes2_prtcl_map |= (1 << lane_prtcl); + } } diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 22f3423..dc3da16 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -80,10 +80,16 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2010, P2010_E, 1), CPU_TYPE_ENTRY(P2020, P2020, 2), CPU_TYPE_ENTRY(P2020, P2020_E, 2), + CPU_TYPE_ENTRY(P3041, P3041, 4), + CPU_TYPE_ENTRY(P3041, P3041_E, 4), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4040, P4040_E, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), CPU_TYPE_ENTRY(P4080, P4080_E, 8), + CPU_TYPE_ENTRY(P5010, P5010, 1), + CPU_TYPE_ENTRY(P5010, P5010_E, 1), + CPU_TYPE_ENTRY(P5020, P5020, 2), + CPU_TYPE_ENTRY(P5020, P5020_E, 2), #elif defined(CONFIG_MPC86xx) CPU_TYPE_ENTRY(8610, 8610, 1), CPU_TYPE_ENTRY(8641, 8641, 2), diff --git a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c index 0f69ef9..2fee995 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c @@ -767,6 +767,13 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal) debug("\n\n"); +#if defined(CONFIG_DDR_RFDC_FIXED) + mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED); + size = 512; + rffd_average = CONFIG_DDR_RFDC_FIXED & SDRAM_RFDC_RFFD_MASK; + mfsdram(SDRAM_RDCC, rdcc); /* record this value */ + cal->rdcc = rdcc; +#else /* CONFIG_DDR_RFDC_FIXED */ in_window = 0; rdcc = 0; @@ -830,6 +837,7 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal) rffd_average = SDRAM_RFDC_RFFD_MAX; mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average)); +#endif /* CONFIG_DDR_RFDC_FIXED */ rffd = rffd_average; in_window = 0; @@ -1211,10 +1219,14 @@ u32 DQS_autocalibration(void) debug("*** best_result: read value SDRAM_RQDC 0x%08x\n", rqdc_reg); +#if defined(CONFIG_DDR_RFDC_FIXED) + mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED); +#else /* CONFIG_DDR_RFDC_FIXED */ mfsdram(SDRAM_RFDC, rfdc_reg); rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK); mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(tcal.autocal.rffd)); +#endif /* CONFIG_DDR_RFDC_FIXED */ mfsdram(SDRAM_RFDC, rfdc_reg); debug("*** best_result: read value SDRAM_RFDC 0x%08x\n", diff --git a/arch/powerpc/cpu/ppc4xx/Makefile b/arch/powerpc/cpu/ppc4xx/Makefile index 88d53fb..c9c1a33 100644 --- a/arch/powerpc/cpu/ppc4xx/Makefile +++ b/arch/powerpc/cpu/ppc4xx/Makefile @@ -51,6 +51,9 @@ COBJS += cpu_init.o COBJS += denali_data_eye.o COBJS += denali_spd_ddr2.o COBJS += ecc.o +ifdef CONFIG_CMD_ECCTEST +COBJS += cmd_ecctest.o +endif COBJS += fdt.o COBJS += interrupts.o COBJS += iop480_uart.o diff --git a/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c b/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c new file mode 100644 index 0000000..b4eac40 --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c @@ -0,0 +1,284 @@ +/* + * (C) Copyright 2010 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/cache.h> + +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \ + defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) +#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) + +#if defined(CONFIG_405EX) +/* + * Currently only 405EX uses 16bit data bus width as an alternative + * option to 32bit data width (SDRAM0_MCOPT1_WDTH) + */ +#define SDRAM_DATA_ALT_WIDTH 2 +#else +#define SDRAM_DATA_ALT_WIDTH 8 +#endif + +#if defined(CONFIG_SYS_OCM_BASE) +#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_OCM_BASE +#endif + +#if defined(CONFIG_SYS_ISRAM_BASE) +#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_ISRAM_BASE +#endif + +#if !defined(CONFIG_FUNC_ISRAM_ADDR) +#error "No internal SRAM/OCM provided!" +#endif + +#define force_inline inline __attribute__ ((always_inline)) + +static inline void machine_check_disable(void) +{ + mtmsr(mfmsr() & ~MSR_ME); +} + +static inline void machine_check_enable(void) +{ + mtmsr(mfmsr() | MSR_ME); +} + +/* + * These helper functions need to be inlined, since they + * are called from the functions running from internal SRAM. + * SDRAM operation is forbidden at that time, so calling + * functions in SDRAM has to be avoided. + */ +static force_inline void wait_ddr_idle(void) +{ + u32 val; + + do { + mfsdram(SDRAM_MCSTAT, val); + } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT); +} + +static force_inline void recalibrate_ddr(void) +{ + u32 val; + + /* + * Rewrite RQDC & RFDC to calibrate again. If this is not + * done, the SDRAM controller is working correctly after + * changing the MCOPT1_MCHK bits. + */ + mfsdram(SDRAM_RQDC, val); + mtsdram(SDRAM_RQDC, val); + mfsdram(SDRAM_RFDC, val); + mtsdram(SDRAM_RFDC, val); +} + +static force_inline void set_mcopt1_mchk(u32 bits) +{ + u32 val; + + wait_ddr_idle(); + mfsdram(SDRAM_MCOPT1, val); + mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | bits); + recalibrate_ddr(); +} + +/* + * The next 2 functions are copied to internal SRAM/OCM and run + * there. No function calls allowed here. No SDRAM acitivity should + * be done here. + */ +static void inject_ecc_error(void *ptr, int par) +{ + u32 val; + + /* + * Taken from PPC460EX/EXr/GT users manual (Rev 1.21) + * 22.2.17.13 ECC Diagnostics + * + * Items 1 ... 5 are already done by now, running from RAM + * with ECC enabled + */ + + out_be32(ptr, 0x00000000); + val = in_be32(ptr); + + /* 6. Set memory controller to no error checking */ + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_NON); + + /* 7. Modify one or two bits for error simulation */ + if (par == 1) + out_be32(ptr, in_be32(ptr) ^ 0x00000001); + else + out_be32(ptr, in_be32(ptr) ^ 0x00000003); + + /* 8. Wait for SDRAM idle */ + val = in_be32(ptr); + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); + + /* Wait for SDRAM idle */ + wait_ddr_idle(); + + /* Continue with 9. in calling function... */ +} + +static void rewrite_ecc_parity(void *ptr, int par) +{ + u32 current_address = (u32)ptr; + u32 end_address; + u32 address_increment; + u32 mcopt1; + u32 val; + + /* + * Fill ECC parity byte again. Otherwise further accesses to + * the failure address will result in exceptions. + */ + + /* Wait for SDRAM idle */ + val = in_be32(0x00000000); + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_GEN); + + /* ECC bit set method for non-cached memory */ + mfsdram(SDRAM_MCOPT1, mcopt1); + if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) + address_increment = 4; + else + address_increment = SDRAM_DATA_ALT_WIDTH; + end_address = current_address + CONFIG_SYS_CACHELINE_SIZE; + + while (current_address < end_address) { + *((unsigned long *)current_address) = 0; + current_address += address_increment; + } + + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); + + /* Wait for SDRAM idle */ + wait_ddr_idle(); +} + +static int do_ecctest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 old_val; + u32 val; + u32 *ptr; + void (*sram_func)(u32 *, int); + int error; + + if (argc < 3) { + cmd_usage(cmdtp); + return 1; + } + + ptr = (u32 *)simple_strtoul(argv[1], NULL, 16); + error = simple_strtoul(argv[2], NULL, 16); + if ((error < 1) || (error > 2)) { + cmd_usage(cmdtp); + return 1; + } + + printf("Using address %p for %d bit ECC error injection\n", + ptr, error); + + /* + * Save value to restore it later on + */ + old_val = in_be32(ptr); + + /* + * Copy ECC injection function into internal SRAM/OCM + */ + sram_func = (void *)CONFIG_FUNC_ISRAM_ADDR; + memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, inject_ecc_error, 0x10000); + + /* + * Disable interrupts and exceptions before calling this + * function in internal SRAM/OCM + */ + disable_interrupts(); + machine_check_disable(); + eieio(); + + /* + * Jump to ECC simulation function in internal SRAM/OCM + */ + (*sram_func)(ptr, error); + + /* 10. Read the corresponding address */ + val = in_be32(ptr); + + /* + * Read and print ECC status register/info: + * The faulting address is only known upon uncorrectable ECC + * errors. + */ + mfsdram(SDRAM_ECCES, val); + if (val & SDRAM_ECCES_CE) + printf("ECC: Correctable error\n"); + if (val & SDRAM_ECCES_UE) { + printf("ECC: Uncorrectable error at 0x%02x%08x\n", + mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL)); + } + + /* + * Clear pending interrupts/exceptions + */ + mtsdram(SDRAM_ECCES, 0xffffffff); + mtdcr(SDRAM_ERRSTATLL, 0xff000000); + set_mcsr(get_mcsr()); + + /* Now enable interrupts and exceptions again */ + eieio(); + machine_check_enable(); + enable_interrupts(); + + /* + * The ECC parity byte need to be re-written for the + * corresponding address. Otherwise future accesses to it + * will result in exceptions. + * + * Jump to ECC parity generation function + */ + memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, rewrite_ecc_parity, 0x10000); + (*sram_func)(ptr, 0); + + /* + * Restore value in corresponding address + */ + out_be32(ptr, old_val); + + return 0; +} + +U_BOOT_CMD( + ecctest, 3, 0, do_ecctest, + "Test ECC by single and double error bit injection", + "address 1/2" +); + +#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */ +#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */ diff --git a/arch/powerpc/cpu/ppc4xx/ecc.c b/arch/powerpc/cpu/ppc4xx/ecc.c index f105605..49f28d9 100644 --- a/arch/powerpc/cpu/ppc4xx/ecc.c +++ b/arch/powerpc/cpu/ppc4xx/ecc.c @@ -130,7 +130,26 @@ static void program_ecc_addr(unsigned long start_address, /* clear ECC error repoting registers */ mtsdram(SDRAM_ECCES, 0xffffffff); - mtdcr(0x4c, 0xffffffff); +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) + /* + * IBM DDR(1) core (440GX): + * Clear Mx bits in SDRAM0_BESR0/1 + */ + mtsdram(SDRAM0_BESR0, 0xffffffff); + mtsdram(SDRAM0_BESR1, 0xffffffff); +#elif defined(CONFIG_440) + /* + * 440/460 DDR2 core: + * Clear EMID (Error PLB Master ID) in MQ0_ESL + */ + mtdcr(SDRAM_ERRSTATLL, 0xfff00000); +#else + /* + * 405EX(r) DDR2 core: + * Clear M0ID (Error PLB Master ID) in SDRAM_BESR + */ + mtsdram(SDRAM_BESR, 0xf0000000); +#endif mtsdram(SDRAM_MCOPT1, (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP); diff --git a/arch/powerpc/cpu/ppc4xx/traps.c b/arch/powerpc/cpu/ppc4xx/traps.c index 1616772..b5562ad 100644 --- a/arch/powerpc/cpu/ppc4xx/traps.c +++ b/arch/powerpc/cpu/ppc4xx/traps.c @@ -209,6 +209,22 @@ MachineCheckException(struct pt_regs *regs) /* Clear MCSR */ mtspr(SPRN_MCSR, val); } + +#if defined(CONFIG_DDR_ECC) && defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) + /* + * Read and print ECC status register/info: + * The faulting address is only known upon uncorrectable ECC + * errors. + */ + mfsdram(SDRAM_ECCES, val); + if (val & SDRAM_ECCES_CE) + printf("ECC: Correctable error\n"); + if (val & SDRAM_ECCES_UE) { + printf("ECC: Uncorrectable error at 0x%02x%08x\n", + mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL)); + } +#endif /* CONFIG_DDR_ECC ... */ + #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) mfsdram(DDR0_00, val) ; printf("DDR0: DDR0_00 %lx\n", val); diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d88c282..f70699d 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -44,8 +44,12 @@ defined(CONFIG_P1021) || defined(CONFIG_P1022) || \ defined(CONFIG_P2020) || defined(CONFIG_MPC8641) #define CONFIG_MAX_CPUS 2 +#elif defined(CONFIG_PPC_P3041) +#define CONFIG_MAX_CPUS 4 #elif defined(CONFIG_PPC_P4080) #define CONFIG_MAX_CPUS 8 +#elif defined(CONFIG_PPC_P5020) +#define CONFIG_MAX_CPUS 2 #else #define CONFIG_MAX_CPUS 1 #endif diff --git a/arch/powerpc/include/asm/fsl_pci.h b/arch/powerpc/include/asm/fsl_pci.h index bb87543..dc5c579 100644 --- a/arch/powerpc/include/asm/fsl_pci.h +++ b/arch/powerpc/include/asm/fsl_pci.h @@ -1,5 +1,5 @@ /* - * Copyright 2007,2009 Freescale Semiconductor, Inc. + * Copyright 2007,2009-2010 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ int fsl_setup_hose(struct pci_controller *hose, unsigned long addr); int fsl_is_pci_agent(struct pci_controller *hose); void fsl_pci_init(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data); void fsl_pci_config_unlock(struct pci_controller *hose); -void ft_fsl_pci_setup(void *blob, const char *pci_alias, - struct pci_controller *hose); +void ft_fsl_pci_setup(void *blob, const char *pci_compat, + struct pci_controller *hose, unsigned long ctrl_addr); /* * Common PCI/PCIE Register structure for mpc85xx and mpc86xx @@ -202,4 +202,82 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info, x.pci_num = num; \ } +#define __FT_FSL_PCI_SETUP(blob, compat, num) \ + ft_fsl_pci_setup(blob, compat, &pci##num##_hose, \ + CONFIG_SYS_PCI##num##_ADDR) + +#define __FT_FSL_PCI_DEL(blob, compat, num) \ + ft_fsl_pci_setup(blob, compat, NULL, CONFIG_SYS_PCI##num##_ADDR) + +#define __FT_FSL_PCIE_SETUP(blob, compat, num) \ + ft_fsl_pci_setup(blob, compat, &pcie##num##_hose, \ + CONFIG_SYS_PCIE##num##_ADDR) + +#define __FT_FSL_PCIE_DEL(blob, compat, num) \ + ft_fsl_pci_setup(blob, compat, NULL, CONFIG_SYS_PCIE##num##_ADDR) + +#ifdef CONFIG_PCI1 +#define FT_FSL_PCI1_SETUP __FT_FSL_PCI_SETUP(blob, FSL_PCI_COMPAT, 1) +#else +#define FT_FSL_PCI1_SETUP __FT_FSL_PCI_DEL(blob, FSL_PCI_COMPAT, 1) +#endif + +#ifdef CONFIG_PCI2 +#define FT_FSL_PCI2_SETUP __FT_FSL_PCI_SETUP(blob, FSL_PCI_COMPAT, 2) +#else +#define FT_FSL_PCI2_SETUP __FT_FSL_PCI_DEL(blob, FSL_PCI_COMPAT, 2) +#endif + +#ifdef CONFIG_PCIE1 +#define FT_FSL_PCIE1_SETUP __FT_FSL_PCIE_SETUP(blob, FSL_PCIE_COMPAT, 1) +#else +#define FT_FSL_PCIE1_SETUP __FT_FSL_PCIE_DEL(blob, FSL_PCIE_COMPAT, 1) +#endif + +#ifdef CONFIG_PCIE2 +#define FT_FSL_PCIE2_SETUP __FT_FSL_PCIE_SETUP(blob, FSL_PCIE_COMPAT, 2) +#else +#define FT_FSL_PCIE2_SETUP __FT_FSL_PCIE_DEL(blob, FSL_PCIE_COMPAT, 2) +#endif + +#ifdef CONFIG_PCIE3 +#define FT_FSL_PCIE3_SETUP __FT_FSL_PCIE_SETUP(blob, FSL_PCIE_COMPAT, 3) +#else +#define FT_FSL_PCIE3_SETUP __FT_FSL_PCIE_DEL(blob, FSL_PCIE_COMPAT, 3) +#endif + +#ifdef CONFIG_PCIE4 +#define FT_FSL_PCIE4_SETUP __FT_FSL_PCIE_SETUP(blob, FSL_PCIE_COMPAT, 4) +#else +#define FT_FSL_PCIE4_SETUP __FT_FSL_PCIE_DEL(blob, FSL_PCIE_COMPAT, 4) +#endif + +#if defined(CONFIG_FSL_CORENET) +#define FSL_PCIE_COMPAT "fsl,p4080-pcie" +#define FT_FSL_PCI_SETUP \ + FT_FSL_PCIE1_SETUP; \ + FT_FSL_PCIE2_SETUP; \ + FT_FSL_PCIE3_SETUP; \ + FT_FSL_PCIE4_SETUP; +#elif defined(CONFIG_MPC85xx) +#define FSL_PCI_COMPAT "fsl,mpc8540-pci" +#define FSL_PCIE_COMPAT "fsl,mpc8548-pcie" +#define FT_FSL_PCI_SETUP \ + FT_FSL_PCI1_SETUP; \ + FT_FSL_PCI2_SETUP; \ + FT_FSL_PCIE1_SETUP; \ + FT_FSL_PCIE2_SETUP; \ + FT_FSL_PCIE3_SETUP; +#elif defined(CONFIG_MPC86xx) +#define FSL_PCI_COMPAT "fsl,mpc8610-pci" +#define FSL_PCIE_COMPAT "fsl,mpc8641-pcie" +#define FT_FSL_PCI_SETUP \ + FT_FSL_PCI1_SETUP; \ + FT_FSL_PCIE1_SETUP; \ + FT_FSL_PCIE2_SETUP; +#else +#error FT_FSL_PCI_SETUP not defined +#endif + + #endif diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index d4839f4..c7877b9 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -44,5 +44,6 @@ enum srds_prtcl { }; int is_serdes_configured(enum srds_prtcl device); +void fsl_serdes_init(void); #endif /* __FSL_SERDES_H */ diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 4e665d3..b1d219b 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2060,8 +2060,17 @@ typedef struct ccsr_sec { #define CONFIG_SYS_MPC85xx_LBC_OFFSET 0x5000 #define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x6000 #define CONFIG_SYS_MPC85xx_ESPI_OFFSET 0x7000 +#define CONFIG_SYS_MPC85xx_PCI1_OFFSET 0x8000 #define CONFIG_SYS_MPC85xx_PCIX_OFFSET 0x8000 +#define CONFIG_SYS_MPC85xx_PCI2_OFFSET 0x9000 #define CONFIG_SYS_MPC85xx_PCIX2_OFFSET 0x9000 +#define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0xa000 +#define CONFIG_SYS_MPC85xx_PCIE2_OFFSET 0x9000 +#if defined(CONFIG_MPC8572) || defined(CONFIG_P2020) +#define CONFIG_SYS_MPC85xx_PCIE3_OFFSET 0x8000 +#else +#define CONFIG_SYS_MPC85xx_PCIE3_OFFSET 0xb000 +#endif #define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0xF000 #define CONFIG_SYS_MPC85xx_SATA1_OFFSET 0x18000 #define CONFIG_SYS_MPC85xx_SATA2_OFFSET 0x19000 @@ -2138,6 +2147,17 @@ typedef struct ccsr_sec { #define CONFIG_SYS_FSL_SEC_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_SEC_OFFSET) +#define CONFIG_SYS_PCI1_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCI1_OFFSET) +#define CONFIG_SYS_PCI2_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCI2_OFFSET) +#define CONFIG_SYS_PCIE1_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE1_OFFSET) +#define CONFIG_SYS_PCIE2_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE2_OFFSET) +#define CONFIG_SYS_PCIE3_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE3_OFFSET) + #define TSEC_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_TSEC1_OFFSET) #define MDIO_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MDIO1_OFFSET) diff --git a/arch/powerpc/include/asm/immap_86xx.h b/arch/powerpc/include/asm/immap_86xx.h index b9e02db..4bebb68 100644 --- a/arch/powerpc/include/asm/immap_86xx.h +++ b/arch/powerpc/include/asm/immap_86xx.h @@ -1257,6 +1257,23 @@ extern immap_t *immr; #define CONFIG_SYS_MPC86xx_DMA_OFFSET (0x21000) #define CONFIG_SYS_MPC86xx_DMA_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DMA_OFFSET) +#define CONFIG_SYS_MPC86xx_PCI1_OFFSET 0x8000 +#ifdef CONFIG_MPC8610 +#define CONFIG_SYS_MPC86xx_PCIE1_OFFSET 0xa000 +#else +#define CONFIG_SYS_MPC86xx_PCIE1_OFFSET 0x8000 +#endif +#define CONFIG_SYS_MPC86xx_PCIE2_OFFSET 0x9000 + +#define CONFIG_SYS_PCI1_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_PCI1_OFFSET) +#define CONFIG_SYS_PCI2_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_PCI2_OFFSET) +#define CONFIG_SYS_PCIE1_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_PCIE1_OFFSET) +#define CONFIG_SYS_PCIE2_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_PCIE2_OFFSET) + #define CONFIG_SYS_TSEC1_OFFSET 0x24000 #define CONFIG_SYS_MDIO1_OFFSET 0x24000 #define CONFIG_SYS_LBC_ADDR (&((immap_t *)CONFIG_SYS_IMMR)->im_lbc) diff --git a/arch/powerpc/include/asm/ppc4xx-sdram.h b/arch/powerpc/include/asm/ppc4xx-sdram.h index d9506e2..4ec1ef8 100644 --- a/arch/powerpc/include/asm/ppc4xx-sdram.h +++ b/arch/powerpc/include/asm/ppc4xx-sdram.h @@ -63,6 +63,8 @@ #define SDRAM_CFG0 0x20 /* memory controller options 0 */ #define SDRAM_CFG1 0x21 /* memory controller options 1 */ +#define SDRAM0_BESR0 0x0000 /* bus error status reg 0 */ +#define SDRAM0_BESR1 0x0008 /* bus error status reg 1 */ #define SDRAM0_BEAR 0x0010 /* bus error address reg */ #define SDRAM0_SLIO 0x0018 /* ddr sdram slave interface options */ #define SDRAM0_CFG0 0x0020 /* ddr sdram options 0 */ @@ -363,6 +365,7 @@ /* * Memory controller registers */ +#ifdef CONFIG_405EX #define SDRAM_BESR 0x00 /* PLB bus error status (read/clear) */ #define SDRAM_BESRT 0x01 /* PLB bus error status (test/set) */ #define SDRAM_BEARL 0x02 /* PLB bus error address low */ @@ -371,11 +374,10 @@ #define SDRAM_WMIRQT 0x07 /* PLB write master interrupt (test/set) */ #define SDRAM_PLBOPT 0x08 /* PLB slave options */ #define SDRAM_PUABA 0x09 /* PLB upper address base */ -#ifndef CONFIG_405EX -#define SDRAM_MCSTAT 0x14 /* memory controller status */ -#else #define SDRAM_MCSTAT 0x1F /* memory controller status */ -#endif +#else /* CONFIG_405EX */ +#define SDRAM_MCSTAT 0x14 /* memory controller status */ +#endif /* CONFIG_405EX */ #define SDRAM_MCOPT1 0x20 /* memory controller options 1 */ #define SDRAM_MCOPT2 0x21 /* memory controller options 2 */ #define SDRAM_MODT0 0x22 /* on die termination for bank 0 */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 844552c..89f283a 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1052,10 +1052,16 @@ #define SVR_P2010_E 0x80EB00 #define SVR_P2020 0x80E200 #define SVR_P2020_E 0x80EA00 +#define SVR_P3041 0x821103 +#define SVR_P3041_E 0x821903 #define SVR_P4040 0x820100 #define SVR_P4040_E 0x820900 #define SVR_P4080 0x820000 #define SVR_P4080_E 0x820800 +#define SVR_P5010 0x822100 +#define SVR_P5010_E 0x822900 +#define SVR_P5020 0x822000 +#define SVR_P5020_E 0x822800 #define SVR_8610 0x80A000 #define SVR_8641 0x809000 |