From 5d812b8b4ad9667c77a5bf92b4ba81699abc9fc3 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 9 Jul 2008 17:33:57 +0200 Subject: [PATCH] ppc4xx: Enable support for > 2GB SDRAM on AMCC Katmai 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 devices, FLASH etc. Note that ECC is currently not supported on configurations with more than 2GB SDRAM. This is because we only map the first 2GB on such systems, and therefore the ECC parity byte of the remaining area can't be written. Signed-off-by: Stefan Roese --- cpu/ppc4xx/44x_spd_ddr2.c | 56 +++++++++++++++++++++++++++------- include/asm-ppc/ppc4xx-sdram.h | 4 +-- include/configs/katmai.h | 7 +++++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index c28fc463b5..9a5340c351 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -137,6 +137,20 @@ #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 + * devices, FLASH etc. + * + * Note that ECC is currently not supported on configurations with more than 2GB + * SDRAM. This is because we only map the first 2GB on such systems, and therefore + * the ECC parity byte of the remaining area can't be written. + */ +#ifndef CONFIG_MAX_MEM_MAPPED +#define CONFIG_MAX_MEM_MAPPED ((phys_size_t)2 << 30) +#endif + /* * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed */ @@ -181,7 +195,7 @@ typedef enum ddr_cas_id { /*-----------------------------------------------------------------------------+ * Prototypes *-----------------------------------------------------------------------------*/ -static unsigned long sdram_memsize(void); +static phys_size_t sdram_memsize(void); static void get_spd_info(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks); @@ -306,9 +320,9 @@ static unsigned char spd_read(uchar chip, uint addr) /*-----------------------------------------------------------------------------+ * sdram_memsize *-----------------------------------------------------------------------------*/ -static unsigned long sdram_memsize(void) +static phys_size_t sdram_memsize(void) { - unsigned long mem_size; + phys_size_t mem_size; unsigned long mcopt2; unsigned long mcstat; unsigned long mb0cf; @@ -364,6 +378,8 @@ static unsigned long sdram_memsize(void) mem_size+=4096; break; default: + printf("WARNING: Unsupported bank size (SDSZ=0x%x)!\n" + , sdsz); mem_size=0; break; } @@ -371,8 +387,7 @@ static unsigned long sdram_memsize(void) } } - mem_size *= 1024 * 1024; - return(mem_size); + return mem_size << 20; } /*-----------------------------------------------------------------------------+ @@ -400,7 +415,7 @@ phys_size_t initdram(int board_type) unsigned long val; ddr_cas_id_t selected_cas = DDR_CAS_5; /* preset to silence compiler */ int write_recovery; - unsigned long dram_size = 0; + phys_size_t dram_size = 0; num_dimm_banks = sizeof(iic0_dimm_addr); @@ -558,6 +573,12 @@ phys_size_t initdram(int board_type) /* get installed memory size */ dram_size = sdram_memsize(); + /* + * Limit size to 2GB + */ + if (dram_size > CONFIG_MAX_MEM_MAPPED) + dram_size = CONFIG_MAX_MEM_MAPPED; + /* and program tlb entries for this size (dynamic) */ /* @@ -595,7 +616,7 @@ phys_size_t initdram(int board_type) */ set_mcsr(get_mcsr()); - return dram_size; + return sdram_memsize(); } static void get_spd_info(unsigned long *dimm_populated, @@ -2133,15 +2154,15 @@ static void program_memory_queue(unsigned long *dimm_populated, unsigned long num_dimm_banks) { unsigned long dimm_num; - unsigned long rank_base_addr; + phys_size_t rank_base_addr; unsigned long rank_reg; - unsigned long rank_size_bytes; + phys_size_t rank_size_bytes; unsigned long rank_size_id; unsigned long num_ranks; unsigned long baseadd_size; unsigned long i; unsigned long bank_0_populated = 0; - unsigned long total_size = 0; + phys_size_t total_size = 0; /*------------------------------------------------------------------ * Reset the rank_base_address. @@ -2289,6 +2310,11 @@ static void program_ecc(unsigned long *dimm_populated, if (ecc == 0) return; + if (sdram_memsize() > CONFIG_MAX_MEM_MAPPED) { + printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n"); + return; + } + mfsdram(SDRAM_MCOPT1, mcopt1); mfsdram(SDRAM_MCOPT2, mcopt2); @@ -2441,6 +2467,7 @@ static int short_mem_test(void) u32 bxcf; int i; int j; + phys_size_t base_addr; u32 test[NUMMEMTESTS][NUMMEMWORDS] = { {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}, @@ -2467,10 +2494,17 @@ static int short_mem_test(void) if ((bxcf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { /* Bank is enabled */ + /* + * Only run test on accessable memory (below 2GB) + */ + base_addr = SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)); + if (base_addr >= CONFIG_MAX_MEM_MAPPED) + continue; + /*------------------------------------------------------------------ * Run the short memory test. *-----------------------------------------------------------------*/ - membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num))); + membase = (u32 *)(u32)base_addr; for (i = 0; i < NUMMEMTESTS; i++) { for (j = 0; j < NUMMEMWORDS; j++) { diff --git a/include/asm-ppc/ppc4xx-sdram.h b/include/asm-ppc/ppc4xx-sdram.h index 83931f17f5..e151f0c113 100644 --- a/include/asm-ppc/ppc4xx-sdram.h +++ b/include/asm-ppc/ppc4xx-sdram.h @@ -284,8 +284,8 @@ #if defined(CONFIG_440SPE) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT) #define SDRAM_RXBAS_SDBA_MASK 0xFFE00000 /* Base address */ -#define SDRAM_RXBAS_SDBA_ENCODE(n) ((((u32)(n))&0xFFE00000)>>2) -#define SDRAM_RXBAS_SDBA_DECODE(n) ((((u32)(n))&0xFFE00000)<<2) +#define SDRAM_RXBAS_SDBA_ENCODE(n) ((u32)(((phys_size_t)(n) >> 2) & 0xFFE00000)) +#define SDRAM_RXBAS_SDBA_DECODE(n) ((((phys_size_t)(n)) & 0xFFE00000) << 2) #endif /* CONFIG_440SPE */ #if defined(CONFIG_440SP) #define SDRAM_RXBAS_SDBA_MASK 0xFF800000 /* Base address */ diff --git a/include/configs/katmai.h b/include/configs/katmai.h index d3789bd67a..f07e470683 100644 --- a/include/configs/katmai.h +++ b/include/configs/katmai.h @@ -40,6 +40,13 @@ #define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */ #define CFG_4xx_RESET_TYPE 0x2 /* use chip reset on this board */ +/* + * Enable this board for more than 2GB of SDRAM + */ +#define CONFIG_PHYS_64BIT +#define CONFIG_VERY_BIG_RAM +#define CONFIG_MAX_MEM_MAPPED ((phys_size_t)2 << 30) + /* * Include common defines/options for all AMCC eval boards */ -- 2.39.5