All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/1 v3] ppc4xx: Autocalibration can set RDCC to over aggressive value.
@ 2009-02-09 21:18 Adam Graham
  2009-02-12  5:32 ` Stefan Roese
  0 siblings, 1 reply; 2+ messages in thread
From: Adam Graham @ 2009-02-09 21:18 UTC (permalink / raw)
  To: u-boot

The criteria of the AMCC SDRAM Controller DDR autocalibration
U-Boot code is to pick the largest passing write/read/compare
window that also has the smallest SDRAM_RDCC.[RDSS] Read Sample
Cycle Select value.

On some Kilauea boards the DDR autocalibration algorithm can
find a large passing write/read/compare window with a small
SDRAM_RDCC.[RDSS] aggressive value of Read Sample Cycle Select
value "T1 Sample".

This SDRAM_RDCC.[RDSS] Read Sample Cycle Select value of
"T1 Sample" proves to be to aggressive when later on U-Boot
relocates into DDR memory and executes.

The memory traces on the Kilauea board are short so on some
Kilauea boards the SDRAM_RDCC.[RDSS] Read Sample Cycle Select
value of "T1 Sample" shows up as a potentially valid value for
the DDR autocalibratiion algorithm.

The fix is to define a weak default function which provides
the minimum SDRAM_RDCC.[RDSS] Read Sample Cycle Select value
to accept for DDR autocalibration.  The default will be the
"T2 Sample" value.  A board developer who has a well defined
board and chooses to be more aggressive can always provide
their own board specific string function with the more
aggressive "T1 Sample" value or stick with the default
minimum SDRAM_RDCC.[RDSS] value of "T2".

Also put in a autocalibration loop fix for case where current
write/read/compare passing window size is the same as a prior
window size, then in this case choose the write/read/compare
result that has the associated smallest RDCC T-Sample value.

Signed-off-by: Adam Graham <agraham@amcc.com>
---
  v2:
   - Shortened the maximum patch comment line lengths
   - Correct coding indentions by using TABS
   - Correct coding style by removing deep nested if statements

  v3:
   - Remove debug changes from v2 patch which had nothing to do with
     the fix for this patch

 cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c |   74 +++++++++++++++++++++--------------
 include/asm-ppc/ppc4xx-sdram.h      |    2 +
 include/configs/kilauea.h           |    7 ---
 3 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
index 1e3e20d..91bf582 100644
--- a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
+++ b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
@@ -61,6 +61,8 @@
 #define NUMLOOPS		1	/* configure as you deem approporiate */
 #define NUMMEMWORDS		16
 
+#define SDRAM_RDCC_RDSS_VAL(n)	SDRAM_RDCC_RDSS_DECODE(ddr_rdss_opt(n))
+
 /* Private Structure Definitions */
 
 struct autocal_regs {
@@ -147,6 +149,13 @@ ulong __ddr_scan_option(ulong default_val)
 }
 ulong ddr_scan_option(ulong) __attribute__((weak, alias("__ddr_scan_option")));
 
+u32 __ddr_rdss_opt(u32 default_val)
+{
+	return default_val;
+}
+u32 ddr_rdss_opt(ulong) __attribute__((weak, alias("__ddr_rdss_opt")));
+
+
 static u32 *get_membase(int bxcr_num)
 {
 	ulong bxcf;
@@ -341,6 +350,7 @@ static int short_mem_test(u32 *base_address)
 			ppcDcbf((ulong)&(base_address[j]));
 		}
 		sync();
+		iobarrier_rw();
 		for (l = 0; l < NUMLOOPS; l++) {
 			for (j = 0; j < NUMMEMWORDS; j++) {
 				if (base_address[j] != test[i][j]) {
@@ -355,6 +365,7 @@ static int short_mem_test(u32 *base_address)
 				ppcDcbf((u32)&(base_address[j]));
 			} /* for (j = 0; j < NUMMEMWORDS; j++) */
 			sync();
+			iobarrier_rw();
 		} /* for (l=0; l<NUMLOOPS; l++) */
 	}
 
@@ -447,7 +458,8 @@ static u32 DQS_calibration_methodA(struct ddrautocal *cal)
 	 * Program RDCC register
 	 * Read sample cycle auto-update enable
 	 */
-	mtsdram(SDRAM_RDCC, SDRAM_RDCC_RDSS_T1 | SDRAM_RDCC_RSAE_ENABLE);
+	mtsdram(SDRAM_RDCC,
+		ddr_rdss_opt(SDRAM_RDCC_RDSS_T2) | SDRAM_RDCC_RSAE_ENABLE);
 
 #ifdef DEBUG
 	mfsdram(SDRAM_RDCC, temp);
@@ -633,7 +645,8 @@ static u32 program_DQS_calibration_methodB(struct ddrautocal *ddrcal)
 	 * Program RDCC register
 	 * Read sample cycle auto-update enable
 	 */
-	mtsdram(SDRAM_RDCC, SDRAM_RDCC_RDSS_T2 | SDRAM_RDCC_RSAE_ENABLE);
+	mtsdram(SDRAM_RDCC,
+		ddr_rdss_opt(SDRAM_RDCC_RDSS_T2) | SDRAM_RDCC_RSAE_ENABLE);
 
 #ifdef DEBUG
 	mfsdram(SDRAM_RDCC, temp);
@@ -1091,32 +1104,36 @@ u32 DQS_autocalibration(void)
 		 * if no passing window was found, or is the
 		 * size of the RFFD passing window.
 		 */
-		if (result != 0) {
-			tcal.autocal.flags = 1;
-			debug("*** (%d)(%d) result passed window size: 0x%08x, "
-			      "rqfd = 0x%08x, rffd = 0x%08x, rdcc = 0x%08x\n",
-				wdtr, clkp, result, ddrcal.rqfd,
-				ddrcal.rffd, ddrcal.rdcc);
-			/*
-			 * Save the SDRAM_WRDTR and SDRAM_CLKTR
-			 * settings for the largest returned
-			 * RFFD passing window size.
-			 */
-			if (result > best_result) {
+		/*
+		 * want the lowest Read Sample Cycle Select
+		 */
+		val = SDRAM_RDCC_RDSS_DECODE(val);
+		debug("*** (%d) (%d) current_rdcc, best_rdcc\n",
+			val, best_rdcc);
+
+		if ((result != 0) &&
+		    (val >= SDRAM_RDCC_RDSS_VAL(SDRAM_RDCC_RDSS_T2))) {
+			if (((result == best_result) && (val < best_rdcc)) ||
+			    ((result > best_result) && (val <= best_rdcc))) {
+				tcal.autocal.flags = 1;
+				debug("*** (%d)(%d) result passed window "
+					"size: 0x%08x, rqfd = 0x%08x, "
+					"rffd = 0x%08x, rdcc = 0x%08x\n",
+					wdtr, clkp, result, ddrcal.rqfd,
+					ddrcal.rffd, ddrcal.rdcc);
+
 				/*
-				 * want the lowest Read Sample Cycle Select
+				 * Save the SDRAM_WRDTR and SDRAM_CLKTR
+				 * settings for the largest returned
+				 * RFFD passing window size.
 				 */
-				val = (val & SDRAM_RDCC_RDSS_MASK) >> 30;
-				debug("*** (%d) (%d) current_rdcc, best_rdcc\n",
-							val, best_rdcc);
-				if (val <= best_rdcc) {
-					best_rdcc = val;
-					tcal.clocks.wrdtr = wdtr;
-					tcal.clocks.clktr = clkp;
-					tcal.clocks.rdcc = (val << 30);
-					tcal.autocal.rqfd = ddrcal.rqfd;
-					tcal.autocal.rffd = ddrcal.rffd;
-					best_result = result;
+				best_rdcc = val;
+				tcal.clocks.wrdtr = wdtr;
+				tcal.clocks.clktr = clkp;
+				tcal.clocks.rdcc = SDRAM_RDCC_RDSS_ENCODE(val);
+				tcal.autocal.rqfd = ddrcal.rqfd;
+				tcal.autocal.rffd = ddrcal.rffd;
+				best_result = result;
 
 					if (verbose_lvl > 2) {
 						printf("** (%d)(%d)  "
@@ -1152,9 +1169,8 @@ u32 DQS_autocalibration(void)
 						       "loop FCSR: 0x%08x\n",
 							wdtr, clkp, val);
 					}
-				} /* if (val <= best_rdcc) */
-			} /* if (result >= best_result) */
-		} /* if (result != 0) */
+			}
+		} /* if ((result != 0) && (val >= (ddr_rdss_opt()))) */
 		scan_list++;
 	} /* while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) */
 
diff --git a/include/asm-ppc/ppc4xx-sdram.h b/include/asm-ppc/ppc4xx-sdram.h
index 98faced..992a3d2 100644
--- a/include/asm-ppc/ppc4xx-sdram.h
+++ b/include/asm-ppc/ppc4xx-sdram.h
@@ -566,6 +566,8 @@
 #define SDRAM_RDCC_RSAE_MASK		0x00000001
 #define SDRAM_RDCC_RSAE_DISABLE		0x00000001
 #define SDRAM_RDCC_RSAE_ENABLE		0x00000000
+#define SDRAM_RDCC_RDSS_ENCODE(n)	((((u32)(n))&0x03)<<30)
+#define SDRAM_RDCC_RDSS_DECODE(n)	((((u32)(n))>>30)&0x03)
 
 /*
  * SDRAM Read Feedback Delay Control Register
diff --git a/include/configs/kilauea.h b/include/configs/kilauea.h
index 4d3ccf5..26cb854 100644
--- a/include/configs/kilauea.h
+++ b/include/configs/kilauea.h
@@ -234,16 +234,9 @@
  *
  * DDR Autocalibration Method_B is the default.
  */
-#if 0
-/*
- * Needs FIX!!!
- * Disable autocalibration for now, because of the unresolved problem
- * with kilauea board using 200MHz PLB/DDR2 frequency
- */
 #define	CONFIG_PPC4xx_DDR_AUTOCALIBRATION	/* IBM DDR autocalibration */
 #define	DEBUG_PPC4xx_DDR_AUTOCALIBRATION	/* dynamic DDR autocal debug */
 #undef	CONFIG_PPC4xx_DDR_METHOD_A
-#endif
 
 #define	CONFIG_SYS_SDRAM0_MB0CF_BASE	((  0 << 20) + CONFIG_SYS_SDRAM_BASE)
 
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [U-Boot] [PATCH 1/1 v3] ppc4xx: Autocalibration can set RDCC to over aggressive value.
  2009-02-09 21:18 [U-Boot] [PATCH 1/1 v3] ppc4xx: Autocalibration can set RDCC to over aggressive value Adam Graham
@ 2009-02-12  5:32 ` Stefan Roese
  0 siblings, 0 replies; 2+ messages in thread
From: Stefan Roese @ 2009-02-12  5:32 UTC (permalink / raw)
  To: u-boot

On Monday 09 February 2009, Adam Graham wrote:
> The criteria of the AMCC SDRAM Controller DDR autocalibration
> U-Boot code is to pick the largest passing write/read/compare
> window that also has the smallest SDRAM_RDCC.[RDSS] Read Sample
> Cycle Select value.

...

Applied to ppc4xx/master. Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-02-12  5:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-09 21:18 [U-Boot] [PATCH 1/1 v3] ppc4xx: Autocalibration can set RDCC to over aggressive value Adam Graham
2009-02-12  5:32 ` Stefan Roese

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.