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 4544b78..b40e4b1 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) /*-----------------------------------------------------------------------------+ @@ -131,22 +151,6 @@ #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 * need some free virtual address space for the remaining peripherals like, SoC @@ -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.1 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 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 66a7737..a676b30 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); -- cgit v1.1 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 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/fdt.c b/cpu/ppc4xx/fdt.c index a97484f..c55e1cf 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"))); -- cgit v1.1