summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2005-11-15 16:04:58 +0100
committerStefan Roese <sr@denx.de>2005-11-15 16:04:58 +0100
commitfd49bf02149a29f0ef8a3eb56b6002c3e5761c8e (patch)
tree7bf1586bbfd935cbc823fe7773a6717dc730e1bf
parentea339205a94706d8b9170bbd89e8c1373df9a92f (diff)
downloadu-boot-imx-fd49bf02149a29f0ef8a3eb56b6002c3e5761c8e.zip
u-boot-imx-fd49bf02149a29f0ef8a3eb56b6002c3e5761c8e.tar.gz
u-boot-imx-fd49bf02149a29f0ef8a3eb56b6002c3e5761c8e.tar.bz2
Fix Bamboo DDR SDRAM initialization (problem with onboard SDRAM)
Patch by Stefan Roese, 15 Nov 2005
-rw-r--r--board/amcc/bamboo/bamboo.c57
-rw-r--r--cpu/ppc4xx/spd_sdram.c149
-rw-r--r--include/configs/bamboo.h5
3 files changed, 140 insertions, 71 deletions
diff --git a/board/amcc/bamboo/bamboo.c b/board/amcc/bamboo/bamboo.c
index d02add5..53bf735 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 7c9ac25..1bdfc16 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 95f9b5c..e681f6c 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