From 59217bae40e90982ab5400d849c08af683ace036 Mon Sep 17 00:00:00 2001 From: Adam Graham Date: Wed, 8 Oct 2008 10:13:14 -0700 Subject: ppc4xx: Add static support for 44x IBM SDRAM Controller This patch add the capability to configure a PPC440 based IBM SDRAM Controller with static, compiled-in, values. PPC440 memory subsystem includes a Memory Queue core. Signed-off-by: Adam Graham Signed-off-by: Victor Gallardo Signed-off-by: Stefan Roese --- cpu/ppc4xx/44x_spd_ddr2.c | 71 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 4544b78ac1e..b40e4b15150 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -60,6 +60,26 @@ "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ } while (0) +#if defined(CONFIG_440) +/* + * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 + * memory region. Right now the cache should still be disabled in U-Boot + * because of the EMAC driver, that need its buffer descriptor to be located + * in non cached memory. + * + * If at some time this restriction doesn't apply anymore, just define + * CONFIG_4xx_DCACHE in the board config file and this code should setup + * everything correctly. + */ +#ifdef CONFIG_4xx_DCACHE +/* enable caching on SDRAM */ +#define MY_TLB_WORD2_I_ENABLE 0 +#else +/* disable caching on SDRAM */ +#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE +#endif /* CONFIG_4xx_DCACHE */ +#endif /* CONFIG_440 */ + #if defined(CONFIG_SPD_EEPROM) /*-----------------------------------------------------------------------------+ @@ -130,22 +150,6 @@ #define NUMMEMWORDS 8 #define NUMLOOPS 64 /* memory test loops */ -/* - * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory - * region. Right now the cache should still be disabled in U-Boot because of the - * EMAC driver, that need it's buffer descriptor to be located in non cached - * memory. - * - * If at some time this restriction doesn't apply anymore, just define - * CONFIG_4xx_DCACHE in the board config file and this code should setup - * everything correctly. - */ -#ifdef CONFIG_4xx_DCACHE -#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */ -#else -#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */ -#endif - /* * Newer PPC's like 440SPe, 460EX/GT can be equipped with more than 2GB of SDRAM. * To support such configurations, we "only" map the first 2GB via the TLB's. We @@ -2958,9 +2962,10 @@ static void test(void) /*----------------------------------------------------------------------------- * Function: initdram - * Description: Configures the PPC405EX(r) DDR1/DDR2 SDRAM memory - * banks. The configuration is performed using static, compile- + * Description: Configures the PPC4xx IBM DDR1/DDR2 SDRAM memory controller. + * The configuration is performed using static, compile- * time parameters. + * Configures the PPC405EX(r) and PPC460EX/GT *---------------------------------------------------------------------------*/ phys_size_t initdram(int board_type) { @@ -2976,6 +2981,18 @@ phys_size_t initdram(int board_type) #if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) unsigned long val; +#if defined(CONFIG_440) + mtdcr(SDRAM_R0BAS, CONFIG_SYS_SDRAM_R0BAS); + mtdcr(SDRAM_R1BAS, CONFIG_SYS_SDRAM_R1BAS); + mtdcr(SDRAM_R2BAS, CONFIG_SYS_SDRAM_R2BAS); + mtdcr(SDRAM_R3BAS, CONFIG_SYS_SDRAM_R3BAS); + mtdcr(SDRAM_PLBADDULL, CONFIG_SYS_SDRAM_PLBADDULL); /* MQ0_BAUL */ + mtdcr(SDRAM_PLBADDUHB, CONFIG_SYS_SDRAM_PLBADDUHB); /* MQ0_BAUH */ + mtdcr(SDRAM_CONF1LL, CONFIG_SYS_SDRAM_CONF1LL); + mtdcr(SDRAM_CONF1HB, CONFIG_SYS_SDRAM_CONF1HB); + mtdcr(SDRAM_CONFPATHB, CONFIG_SYS_SDRAM_CONFPATHB); +#endif + /* Set Memory Bank Configuration Registers */ mtsdram(SDRAM_MB0CF, CONFIG_SYS_SDRAM0_MB0CF); @@ -3069,6 +3086,14 @@ phys_size_t initdram(int board_type) mfsdram(SDRAM_MCOPT2, val); mtsdram(SDRAM_MCOPT2, val | SDRAM_MCOPT2_DCEN_ENABLE); +#if defined(CONFIG_440) + /* + * Program TLB entries with caches enabled, for best performace + * while auto-calibrating and ECC generation + */ + program_tlb(0, 0, (CONFIG_SYS_MBYTES_SDRAM << 20), 0); +#endif + #if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) /*------------------------------------------------------------------ @@ -3082,6 +3107,16 @@ phys_size_t initdram(int board_type) ecc_init(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20); #endif /* defined(CONFIG_DDR_ECC) */ +#if defined(CONFIG_440) + /* + * Now after initialization (auto-calibration and ECC generation) + * remove the TLB entries with caches enabled and program again with + * desired cache functionality + */ + remove_tlb(0, (CONFIG_SYS_MBYTES_SDRAM << 20)); + program_tlb(0, 0, (CONFIG_SYS_MBYTES_SDRAM << 20), MY_TLB_WORD2_I_ENABLE); +#endif + ppc4xx_ibm_ddr2_register_dump(); #if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) -- cgit v1.2.3 From c9c11d751e4242cf29c3c3c290d971f6d0cb1d15 Mon Sep 17 00:00:00 2001 From: Adam Graham Date: Wed, 8 Oct 2008 10:13:19 -0700 Subject: ppc4xx: Add routine to retrieve CPU number Provide a weak defined routine to retrieve the CPU number for reference boards that have multiple CPU's. Default behavior is the existing single CPU print output. Reference boards with multiple CPU's need to provide a board specific routine. See board/amcc/arches/arches.c for an example. Signed-off-by: Adam Graham Signed-off-by: Victor Gallardo Signed-off-by: Stefan Roese --- cpu/ppc4xx/cpu.c | 19 ++++++++++++++++++- include/ppc4xx.h | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 66a77370c8f..a676b30efe7 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -41,6 +41,18 @@ DECLARE_GLOBAL_DATA_PTR; void board_reset(void); +/* + * To provide an interface to detect CPU number for boards that support + * more then one CPU, we implement the "weak" default functions here. + * + * Returns CPU number + */ +int __get_cpu_num(void) +{ + return NA_OR_UNKNOWN_CPU; +} +int get_cpu_num(void) __attribute__((weak, alias("__get_cpu_num"))); + #if defined(CONFIG_405GP) || \ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) @@ -274,8 +286,13 @@ int checkcpu (void) #if !defined(CONFIG_IOP480) char addstr[64] = ""; sys_info_t sys_info; + int cpu_num; - puts ("CPU: "); + cpu_num = get_cpu_num(); + if (cpu_num >= 0) + printf("CPU%d: ", cpu_num); + else + puts("CPU: "); get_sys_info(&sys_info); diff --git a/include/ppc4xx.h b/include/ppc4xx.h index ce4b29a1939..f1478854d11 100644 --- a/include/ppc4xx.h +++ b/include/ppc4xx.h @@ -218,4 +218,7 @@ static inline void set_mcsr(u32 val) #endif /* __ASSEMBLY__ */ +/* for multi-cpu support */ +#define NA_OR_UNKNOWN_CPU -1 + #endif /* __PPC4XX_H__ */ -- cgit v1.2.3 From 43cbce69d48d052574d71f50724be546d90a46a4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 13 Oct 2008 10:45:14 +0200 Subject: ppc4xx: Correctly setup ranges property in ebc node Previously only the NOR flash mapping was written into the ranges property of the ebc node. This patch now writes all enabled chip select areas into the ranges property. Signed-off-by: Stefan Roese --- cpu/ppc4xx/fdt.c | 45 +++++++++++++++++++++++++++----------------- include/asm-ppc/ppc4xx-ebc.h | 31 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 17 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/fdt.c b/cpu/ppc4xx/fdt.c index a97484fa74e..c55e1cfbb72 100644 --- a/cpu/ppc4xx/fdt.c +++ b/cpu/ppc4xx/fdt.c @@ -37,29 +37,40 @@ DECLARE_GLOBAL_DATA_PTR; void __ft_board_setup(void *blob, bd_t *bd) { - u32 val[4]; int rc; + int i; + u32 bxcr; + u32 ranges[EBC_NUM_BANKS * 4]; + u32 *p = ranges; + char *ebc_path = "/plb/opb/ebc"; ft_cpu_setup(blob, bd); - /* Fixup NOR mapping */ - val[0] = 0; /* chip select number */ - val[1] = 0; /* always 0 */ - val[2] = gd->bd->bi_flashstart; - val[3] = gd->bd->bi_flashsize; - if (fdt_path_offset(blob, "/plb/opb/ebc") >= 0) { - rc = fdt_find_and_setprop(blob, "/plb/opb/ebc", "ranges", - val, sizeof(val), 1); - } else { - /* - * Some 405 PPC's have EBC as direct PLB child in the dts - */ - rc = fdt_find_and_setprop(blob, "/plb/ebc", "ranges", - val, sizeof(val), 1); + /* + * Read 4xx EBC bus bridge registers to get mappings of the + * peripheral banks into the OPB/PLB address space + */ + for (i = 0; i < EBC_NUM_BANKS; i++) { + mtdcr(ebccfga, EBC_BXCR(i)); + bxcr = mfdcr(ebccfgd); + + if ((bxcr & EBC_BXCR_BU_MASK) != EBC_BXCR_BU_NONE) { + *p++ = i; + *p++ = 0; + *p++ = bxcr & EBC_BXCR_BAS_MASK; + *p++ = EBC_BXCR_BANK_SIZE(bxcr); + } } - if (rc) - printf("Unable to update property NOR mapping, err=%s\n", + + /* Some 405 PPC's have EBC as direct PLB child in the dts */ + if (fdt_path_offset(blob, "/plb/opb/ebc") < 0) + strcpy(ebc_path, "/plb/ebc"); + rc = fdt_find_and_setprop(blob, ebc_path, "ranges", ranges, + (p - ranges) * sizeof(u32), 1); + if (rc) { + printf("Unable to update property EBC mappings, err=%s\n", fdt_strerror(rc)); + } } void ft_board_setup(void *blob, bd_t *bd) __attribute__((weak, alias("__ft_board_setup"))); diff --git a/include/asm-ppc/ppc4xx-ebc.h b/include/asm-ppc/ppc4xx-ebc.h index d180e045fc5..9680f70d6b0 100644 --- a/include/asm-ppc/ppc4xx-ebc.h +++ b/include/asm-ppc/ppc4xx-ebc.h @@ -35,7 +35,38 @@ #define CONFIG_EBC_PPC4xx_IBM_VER1 #endif +/* + * Define the max number of EBC banks (chip selects) + */ +#if defined(CONFIG_405CR) || defined(CONFIG_405GP) || \ + defined(CONFIG_405EZ) || \ + defined(CONFIG_440GP) || defined(CONFIG_440GX) +#define EBC_NUM_BANKS 8 +#endif + +#if defined(CONFIG_405EP) +#define EBC_NUM_BANKS 5 +#endif + +#if defined(CONFIG_405EX) || \ + defined(CONFIG_460SX) +#define EBC_NUM_BANKS 4 +#endif + +#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define EBC_NUM_BANKS 6 +#endif + +#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) +#define EBC_NUM_BANKS 3 +#endif + /* Bank Configuration Register */ +#define EBC_BXCR(n) (n) +#define EBC_BXCR_BANK_SIZE(n) (0x100000 << (((n) & EBC_BXCR_BS_MASK) >> 17)) + #define EBC_BXCR_BAS_MASK PPC_REG_VAL(11, 0xFFF) #define EBC_BXCR_BAS_ENCODE(n) (((static_cast(u32, n)) & EBC_BXCR_BAS_MASK)) #define EBC_BXCR_BS_MASK PPC_REG_VAL(14, 0x7) -- cgit v1.2.3