فهرست منبع

Fix Bamboo DDR SDRAM initialization (problem with onboard SDRAM)
Patch by Stefan Roese, 15 Nov 2005

Stefan Roese 19 سال پیش
والد
کامیت
fd49bf0214
3فایلهای تغییر یافته به همراه140 افزوده شده و 71 حذف شده
  1. 38 19
      board/amcc/bamboo/bamboo.c
  2. 99 50
      cpu/ppc4xx/spd_sdram.c
  3. 3 2
      include/configs/bamboo.h

+ 38 - 19
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;

+ 99 - 50
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);
 }
 

+ 3 - 2
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