Fix Bamboo DDR SDRAM initialization (problem with onboard SDRAM)
authorStefan Roese <sr@denx.de>
Tue, 15 Nov 2005 15:04:58 +0000 (16:04 +0100)
committerStefan Roese <sr@denx.de>
Tue, 15 Nov 2005 15:04:58 +0000 (16:04 +0100)
Patch by Stefan Roese, 15 Nov 2005

board/amcc/bamboo/bamboo.c
cpu/ppc4xx/spd_sdram.c
include/configs/bamboo.h

index d02add5723e6f5e6d0bbca40faf9cdd6da3f0323..53bf735008aa0ed9364db37a375bc2355ff1ba39 100644 (file)
@@ -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;
index 7c9ac25e218d7fd63b1ec0c6bf245438fd3c6637..1bdfc1610c1858fb19ea3d80b2c6581ac5512aa3 100644 (file)
@@ -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);
 }
 
index 95f9b5c62e0c9b271c65885c24e9469cf964ec80..e681f6c9339a71a7e9c052fbc81d7e4193f40c0e 100644 (file)
  * 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