From fd49bf02149a29f0ef8a3eb56b6002c3e5761c8e Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 15 Nov 2005 16:04:58 +0100 Subject: Fix Bamboo DDR SDRAM initialization (problem with onboard SDRAM) Patch by Stefan Roese, 15 Nov 2005 --- board/amcc/bamboo/bamboo.c | 57 +++++++++++------ cpu/ppc4xx/spd_sdram.c | 149 ++++++++++++++++++++++++++++++--------------- include/configs/bamboo.h | 5 +- 3 files changed, 140 insertions(+), 71 deletions(-) diff --git a/board/amcc/bamboo/bamboo.c b/board/amcc/bamboo/bamboo.c index d02add5723..53bf735008 100644 --- a/board/amcc/bamboo/bamboo.c +++ b/board/amcc/bamboo/bamboo.c @@ -31,6 +31,8 @@ void ext_bus_cntlr_init(void); void configure_ppc440ep_pins(void); int is_nand_selected(void); +unsigned char cfg_simulate_spd_eeprom[128]; + gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX]; #if 0 { /* GPIO Alternate1 Alternate2 Alternate3 */ @@ -380,7 +382,7 @@ int checkboard(void) /************************************************************************* * - * fixed_sdram_init -- Bamboo has one bank onboard sdram (plus DIMM) + * init_spd_array -- Bamboo has one bank onboard sdram (plus DIMM) * * Fixed memory is composed of : * MT46V16M16TG-75 from Micron (x 2), 256Mb, 16 M x16, DDR266, @@ -397,24 +399,40 @@ int checkboard(void) * PLB @ 133 MHz * ************************************************************************/ -void fixed_sdram_init(void) +static void init_spd_array(void) { - /* - * clear this first, if the DDR is enabled by a debugger - * then you can not make changes. - */ - mtsdram(mem_cfg0, 0x00000000); /* Disable EEC */ + cfg_simulate_spd_eeprom[8] = 0x04; /* 2.5 Volt */ + cfg_simulate_spd_eeprom[2] = 0x07; /* DDR ram */ - /*-------------------------------------------------------------------- - * Setup for board-specific specific mem - *------------------------------------------------------------------*/ - /* - * Following for CAS Latency = 2.5 @ 133 MHz PLB - */ - mtsdram(mem_b0cr, 0x00082001); - mtsdram(mem_b1cr, 0x00000000); - mtsdram(mem_b2cr, 0x00000000); - mtsdram(mem_b3cr, 0x00000000); +#ifdef CONFIG_DDR_ECC + cfg_simulate_spd_eeprom[11] = 0x02; /* ECC ON : 02 OFF : 00 */ + cfg_simulate_spd_eeprom[31] = 0x08; /* bankSizeID: 32MB */ + cfg_simulate_spd_eeprom[3] = 0x0C; /* num Row Addr: 12 */ +#else + cfg_simulate_spd_eeprom[11] = 0x00; /* ECC ON : 02 OFF : 00 */ + cfg_simulate_spd_eeprom[31] = 0x10; /* bankSizeID: 64MB */ + cfg_simulate_spd_eeprom[3] = 0x0D; /* num Row Addr: 13 */ +#endif + + cfg_simulate_spd_eeprom[4] = 0x09; /* numColAddr: 9 */ + cfg_simulate_spd_eeprom[5] = 0x01; /* numBanks: 1 */ + cfg_simulate_spd_eeprom[0] = 0x80; /* number of SPD bytes used: 128 */ + cfg_simulate_spd_eeprom[1] = 0x08; /* total number bytes in SPD device = 256 */ + cfg_simulate_spd_eeprom[21] = 0x00; /* not registered: 0 registered : 0x02*/ + cfg_simulate_spd_eeprom[6] = 0x20; /* Module data width: 32 bits */ + cfg_simulate_spd_eeprom[7] = 0x00; /* Module data width continued: +0 */ + cfg_simulate_spd_eeprom[15] = 0x01; /* wcsbc = 1 */ + cfg_simulate_spd_eeprom[27] = 0x50; /* tRpNs = 20 ns */ + cfg_simulate_spd_eeprom[29] = 0x50; /* tRcdNs = 20 ns */ + + cfg_simulate_spd_eeprom[30] = 45; /* tRasNs */ + + cfg_simulate_spd_eeprom[18] = 0x0C; /* casBit (2,2.5) */ + + cfg_simulate_spd_eeprom[9] = 0x75; /* SDRAM Cycle Time (cas latency 2.5) = 7.5 ns */ + cfg_simulate_spd_eeprom[23] = 0xA0; /* SDRAM Cycle Time (cas latency 2) = 10 ns */ + cfg_simulate_spd_eeprom[25] = 0x00; /* SDRAM Cycle Time (cas latency 1.5) = N.A */ + cfg_simulate_spd_eeprom[12] = 0x82; /* refresh Rate Type: Normal (15.625us) + Self refresh */ } long int initdram (int board_type) @@ -422,9 +440,10 @@ long int initdram (int board_type) long dram_size = 0; /* - * First init bank0 (onboard sdram) and then configure the DIMM-slots + * First write simulated values in eeprom array for onboard bank 0 */ - fixed_sdram_init(); + init_spd_array(); + dram_size = spd_sdram (0); return dram_size; diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index 7c9ac25e21..1bdfc1610c 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -650,6 +650,17 @@ const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { 0xAA55AA55, 0xAA55AA55} }; +/* bank_parms is used to sort the bank sizes by descending order */ +struct bank_param { + unsigned long cr; + unsigned long bank_size_bytes; +}; + +typedef struct bank_param BANKPARMS; + +#ifdef CFG_SIMULATE_SPD_EEPROM +extern unsigned char cfg_simulate_spd_eeprom[128]; +#endif unsigned char spd_read(uchar chip, uint addr); @@ -806,9 +817,19 @@ long int spd_sdram(void) { return total_size; } -unsigned char spd_read(uchar chip, uint addr) { +unsigned char spd_read(uchar chip, uint addr) +{ unsigned char data[2]; +#ifdef CFG_SIMULATE_SPD_EEPROM + if (chip == CFG_SIMULATE_SPD_EEPROM) { + /* + * Onboard spd eeprom requested -> simulate values + */ + return cfg_simulate_spd_eeprom[addr]; + } +#endif /* CFG_SIMULATE_SPD_EEPROM */ + if (i2c_probe(chip) == 0) { if (i2c_read(chip, addr, 1, data, 1) == 0) { return data[0]; @@ -849,12 +870,10 @@ void get_spd_info(unsigned long* dimm_populated, } } -#ifndef CONFIG_BAMBOO /* bamboo has onboard DDR _and_ DDR DIMM's */ if (dimm_found == FALSE) { printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); hang(); } -#endif /* CONFIG_BAMBOO */ } void check_mem_type(unsigned long* dimm_populated, @@ -1593,35 +1612,56 @@ unsigned long program_bxcr(unsigned long* dimm_populated, { unsigned long dimm_num; unsigned long bank_base_addr; - unsigned long bank_size_bytes; unsigned long cr; unsigned long i; + unsigned long j; unsigned long temp; unsigned char num_row_addr; unsigned char num_col_addr; unsigned char num_banks; unsigned char bank_size_id; - -#ifndef CONFIG_BAMBOO - unsigned long bxcr_num; + unsigned long ctrl_bank_num[MAXBANKS]; + unsigned long bx_cr_num; + unsigned long largest_size_index; + unsigned long largest_size; + unsigned long current_size_index; + BANKPARMS bank_parms[MAXBXCR]; + unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */ + unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/ /* * Set the BxCR regs. First, wipe out the bank config registers. */ - for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { - mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); + for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) { + mtdcr(memcfga, mem_b0cr + (bx_cr_num << 2)); mtdcr(memcfgd, 0x00000000); + bank_parms[bx_cr_num].bank_size_bytes = 0; } + +#ifdef CONFIG_BAMBOO + /* + * This next section is hardware dependent and must be programmed + * to match the hardware. For bammboo, the following holds... + * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 + * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1 + * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1 + * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3 + * ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM + */ + ctrl_bank_num[0] = 0; + ctrl_bank_num[1] = 1; + ctrl_bank_num[2] = 3; +#else + ctrl_bank_num[0] = 0; + ctrl_bank_num[1] = 1; + ctrl_bank_num[2] = 2; + ctrl_bank_num[3] = 3; #endif /* * reset the bank_base address */ -#ifndef CONFIG_BAMBOO bank_base_addr = CFG_SDRAM_BASE; -#else - bank_base_addr = CFG_SDRAM_ONBOARD_SIZE; -#endif for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { @@ -1634,7 +1674,6 @@ unsigned long program_bxcr(unsigned long* dimm_populated, * Set the SDRAM0_BxCR regs */ cr = 0; - bank_size_bytes = 4 * 1024 * 1024 * bank_size_id; switch (bank_size_id) { case 0x02: cr |= SDRAM_BXCR_SDSZ_8; @@ -1693,46 +1732,56 @@ unsigned long program_bxcr(unsigned long* dimm_populated, */ cr |= SDRAM_BXCR_SDBE; - /*------------------------------------------------------------------ - | This next section is hardware dependent and must be programmed - | to match the hardware. - +-----------------------------------------------------------------*/ - if (dimm_num == 0) { - for (i = 0; i < num_banks; i++) { -#ifndef CONFIG_BAMBOO - mtdcr(memcfga, mem_b0cr + (i << 2)); -#else - mtdcr(memcfga, mem_b1cr + (i << 2)); -#endif - temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | - SDRAM_BXCR_SDSZ_MASK | - SDRAM_BXCR_SDAM_MASK | - SDRAM_BXCR_SDBE); - cr |= temp; - cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; - mtdcr(memcfgd, cr); - bank_base_addr += bank_size_bytes; - } - } else { - for (i = 0; i < num_banks; i++) { -#ifndef CONFIG_BAMBOO - mtdcr(memcfga, mem_b2cr + (i << 2)); -#else - mtdcr(memcfga, mem_b3cr + (i << 2)); -#endif - temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | - SDRAM_BXCR_SDSZ_MASK | - SDRAM_BXCR_SDAM_MASK | - SDRAM_BXCR_SDBE); - cr |= temp; - cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; - mtdcr(memcfgd, cr); - bank_base_addr += bank_size_bytes; - } + for (i = 0; i < num_banks; i++) { + bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes = + (4 * 1024 * 1024) * bank_size_id; + bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr; } } } + /* Initialize sort tables */ + for (i = 0; i < MAXBXCR; i++) { + sorted_bank_num[i] = i; + sorted_bank_size[i] = bank_parms[i].bank_size_bytes; + } + + for (i = 0; i < MAXBXCR-1; i++) { + largest_size = sorted_bank_size[i]; + largest_size_index = 255; + + /* Find the largest remaining value */ + for (j = i + 1; j < MAXBXCR; j++) { + if (sorted_bank_size[j] > largest_size) { + /* Save largest remaining value and its index */ + largest_size = sorted_bank_size[j]; + largest_size_index = j; + } + } + + if (largest_size_index != 255) { + /* Swap the current and largest values */ + current_size_index = sorted_bank_num[largest_size_index]; + sorted_bank_size[largest_size_index] = sorted_bank_size[i]; + sorted_bank_size[i] = largest_size; + sorted_bank_num[largest_size_index] = sorted_bank_num[i]; + sorted_bank_num[i] = current_size_index; + } + } + + /* Set the SDRAM0_BxCR regs thanks to sort tables */ + for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) { + if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) { + mtdcr(memcfga, mem_b0cr + (sorted_bank_num[bx_cr_num] << 2)); + temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK | + SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE); + temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) | + bank_parms[sorted_bank_num[bx_cr_num]].cr; + mtdcr(memcfgd, temp); + bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes; + } + } + return(bank_base_addr); } diff --git a/include/configs/bamboo.h b/include/configs/bamboo.h index 95f9b5c62e..e681f6c933 100644 --- a/include/configs/bamboo.h +++ b/include/configs/bamboo.h @@ -205,8 +205,9 @@ * DDR SDRAM *----------------------------------------------------------------------------- */ #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for setup */ -#define SPD_EEPROM_ADDRESS {0x50,0x51} /* SPD i2c spd addresses */ -#define CFG_SDRAM_ONBOARD_SIZE (64 << 20) /* Bamboo has onboard and DIMM-slots!*/ +#undef CONFIG_DDR_ECC /* don't use ECC */ +#define CFG_SIMULATE_SPD_EEPROM 0xff /* simulate spd eeprom on this address */ +#define SPD_EEPROM_ADDRESS {CFG_SIMULATE_SPD_EEPROM, 0x50, 0x51} /*----------------------------------------------------------------------- * I2C -- cgit v1.2.1