[U-Boot] [PATCH] ppc4xx: Optimization for DDR2 initialization for IBM DDR2 memory controller

Prodyut Hazarika phazarika at amcc.com
Thu Aug 28 00:28:44 CEST 2008


>From 5dd36e0d171286f59e4ca4e9eb2a040143b4ec33 Mon Sep 17 00:00:00 2001
From: Prodyut Hazarika <phazarika at amcc.com>
Date: Wed, 27 Aug 2008 14:51:08 -0700
Subject: [PATCH] Optimization for DDR2 initialization for IBM DDR2 memory controller
 Optimized values suggested by Hardware Team at AMCC
 Removed Magic numbers from Initialization preload registers
 Tested with Kilauea, Glacier, Canyonlands and Katmai boards
 About 5-7% improvement seen for LMBench memtests
 Signed-off-by: Prodyut Hazarika <phazarika at amcc.com>

---
 cpu/ppc4xx/44x_spd_ddr2.c |   59 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 001f2c1..c24cfec 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -118,6 +118,7 @@ static inline void ppc4xx_ibm_ddr2_register_dump(void);
 
 #define ODS_FULL	0x00000000
 #define ODS_REDUCED	0x00000002
+#define OCD_CALIB_DEF	0x00000380
 
 /* defines for ODT (On Die Termination) of the 440SP(e) DDR2 controller */
 #define ODT_EB0R	(0x80000000 >> 8)
@@ -570,15 +571,24 @@ phys_size_t initdram(int board_type)
 	mtsdram(SDRAM_MCOPT2,
 		(val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK |
 			 SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) |
-		(SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE));
+		SDRAM_MCOPT2_IPTR_EXECUTE);
 
 	/*------------------------------------------------------------------
-	 * Wait for SDRAM_CFG0_DC_EN to complete.
+	 * Wait for IPTR_EXECUTE init sequence to complete.
 	 *-----------------------------------------------------------------*/
 	do {
 		mfsdram(SDRAM_MCSTAT, val);
 	} while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP);
 
+	/* enable the controller only after init sequence completes */
+	mfsdram(SDRAM_MCOPT2, val);
+	mtsdram(SDRAM_MCOPT2, (val | SDRAM_MCOPT2_DCEN_ENABLE));
+
+	/* Make sure delay-line calibration is done before proceeding */
+	do {
+		mfsdram(SDRAM_DLCR, val);
+	} while (!(val & SDRAM_DLCR_DLCS_COMPLETE));
+
 	/* get installed memory size */
 	dram_size = sdram_memsize();
 
@@ -1343,22 +1353,36 @@ static void program_initplr(unsigned long *dimm_populated,
 		emr = CMD_EMR | SELECT_EMR | odt | ods;
 		emr2 = CMD_EMR | SELECT_EMR2;
 		emr3 = CMD_EMR | SELECT_EMR3;
-		mtsdram(SDRAM_INITPLR0,  0xB5000000 | CMD_NOP);		/* NOP */
+		mtsdram(SDRAM_INITPLR0, SDRAM_INITPLR_ENABLE | CMD_NOP |	/* NOP */
+					SDRAM_INITPLR_IMWT_ENCODE(106));	/* Wait 106 MemClk cycles */
 		udelay(1000);
-		mtsdram(SDRAM_INITPLR1,  0x82000400 | CMD_PRECHARGE);	/* precharge 8 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR2,  0x80800000 | emr2);		/* EMR2 */
-		mtsdram(SDRAM_INITPLR3,  0x80800000 | emr3);		/* EMR3 */
-		mtsdram(SDRAM_INITPLR4,  0x80800000 | emr);		/* EMR DLL ENABLE */
-		mtsdram(SDRAM_INITPLR5,  0x80800000 | mr | DLL_RESET);	/* MR w/ DLL reset */
+		mtsdram(SDRAM_INITPLR1, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE |	/* precharge 4 MemClk cycles */
+					SDRAM_INITPLR_IMWT_ENCODE(4));
+		mtsdram(SDRAM_INITPLR2, SDRAM_INITPLR_ENABLE | emr2 |	/* EMR2 */
+					SDRAM_INITPLR_IMWT_ENCODE(2));	/* Wait tMRD (2 MemClk cycles) */
+		mtsdram(SDRAM_INITPLR3, SDRAM_INITPLR_ENABLE | emr3 |	/* EMR3 */
+					SDRAM_INITPLR_IMWT_ENCODE(2));	/* Wait tMRD (2 MemClk cycles) */
+		mtsdram(SDRAM_INITPLR4, SDRAM_INITPLR_ENABLE | emr |	/* EMR DLL ENABLE */
+					SDRAM_INITPLR_IMWT_ENCODE(2));	/* Wait tMRD (2 MemClk cycles) */
+		mtsdram(SDRAM_INITPLR5, SDRAM_INITPLR_ENABLE | mr | DLL_RESET |	/* MR w/ DLL reset */
+					SDRAM_INITPLR_IMWT_ENCODE(200));	/* 200 cycle wait for DLL reset */
 		udelay(1000);
-		mtsdram(SDRAM_INITPLR6,  0x82000400 | CMD_PRECHARGE);	/* precharge 8 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR7,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR8,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR9,  0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR10, 0x8a000000 | CMD_REFRESH);	/* Refresh  50 DDR clock cycle */
-		mtsdram(SDRAM_INITPLR11, 0x80000000 | mr);		/* MR w/o DLL reset */
-		mtsdram(SDRAM_INITPLR12, 0x80800380 | emr);		/* EMR OCD Default */
-		mtsdram(SDRAM_INITPLR13, 0x80800000 | emr);		/* EMR OCD Exit */
+		mtsdram(SDRAM_INITPLR6, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE |
+					SDRAM_INITPLR_IMWT_ENCODE(4));		/* precharge 4 MemClk cycles */
+		mtsdram(SDRAM_INITPLR7, SDRAM_INITPLR_ENABLE | CMD_REFRESH |
+					SDRAM_INITPLR_IMWT_ENCODE(25));		/* Refresh 25 MemClk cycles */
+		mtsdram(SDRAM_INITPLR8, SDRAM_INITPLR_ENABLE | CMD_REFRESH |
+					SDRAM_INITPLR_IMWT_ENCODE(25));		/* Refresh 25 MemClk cycles */
+		mtsdram(SDRAM_INITPLR9, SDRAM_INITPLR_ENABLE | CMD_REFRESH |
+					SDRAM_INITPLR_IMWT_ENCODE(25));		/* Refresh 25 MemClk cycles */
+		mtsdram(SDRAM_INITPLR10, SDRAM_INITPLR_ENABLE | CMD_REFRESH |
+					 SDRAM_INITPLR_IMWT_ENCODE(25));	/* Refresh 25 MemClk cycles */
+		mtsdram(SDRAM_INITPLR11, SDRAM_INITPLR_ENABLE | mr |		/* MR w/o DLL reset */
+					 SDRAM_INITPLR_IMWT_ENCODE(2));		/* Wait tMRD (2 MemClk cycles) */
+		mtsdram(SDRAM_INITPLR12, SDRAM_INITPLR_ENABLE | OCD_CALIB_DEF |	/* EMR OCD Default */
+					 SDRAM_INITPLR_IMWT_ENCODE(2) | emr);	/* Wait tMRD (2 MemClk cycles) */
+		mtsdram(SDRAM_INITPLR13, SDRAM_INITPLR_ENABLE | emr |		/* EMR OCD Exit */
+					 SDRAM_INITPLR_IMWT_ENCODE(2));
 	} else {
 		printf("ERROR: ucode error as unknown DDR type in program_initplr");
 		spd_ddr_init_hang ();
@@ -2466,12 +2490,13 @@ static void program_DQS_calibration(unsigned long *dimm_populated,
 	 * Program RFDC register
 	 * Set Feedback Fractional Oversample
 	 * Auto-detect read sample cycle enable
+	 * Set RFOS to 1/4 of memclk cycle (0x3f)
 	 *-----------------------------------------------------------------*/
 	mfsdram(SDRAM_RFDC, val);
 	mtsdram(SDRAM_RFDC,
 		(val & ~(SDRAM_RFDC_ARSE_MASK | SDRAM_RFDC_RFOS_MASK |
 			 SDRAM_RFDC_RFFD_MASK))
-		| (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0) |
+		| (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0x3f) |
 		   SDRAM_RFDC_RFFD_ENCODE(0)));
 
 	DQS_calibration_process();
-- 
1.5.5





More information about the U-Boot mailing list