Subject: [PATCH 1/1] Check for memory rank missed oversample during DDR autocalibration.
From: Adam Graham <[email-masked]>
To: Stefan Roese <[email-masked]>
Cc: Adam Graham <[email-masked]>, Victor Gallardo <[email-masked]>
Date: Tue, 14 Oct 2008 19:24:13 -0700

Signed-off-by: Adam Graham <[email-masked]>
---
 cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
index 47ab39b..c63315b 100644
--- a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
+++ b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
@@ -174,6 +174,22 @@ static inline void ecc_clear_status_reg(void)
 #endif
 }
 
+#define SDRAM_FCSR_RxMOS	0x00008000	/* rank missed oversample */
+#define SDRAM_FCSR_CMOS_MASK	0x00000030	/* hit/missed oversample */
+#define SDRAM_FCSR_CMOS_MISSED	0x00000010	/* hit/missed oversample */
+
+static inline int check_fcsr_oversample_miss(int membank)
+{
+	u32 fcsr;
+
+	mfsdram(SDRAM_FCSR, fcsr);
+	if (fcsr & (SDRAM_FCSR_RxMOS >> membank))
+		if (fcsr & SDRAM_FCSR_CMOS_MISSED)
+			return 0;		/* don't count this pass */
+
+	return 1;
+}
+
 /*
  * Reset and relock memory DLL after SDRAM_CLKTR change
  */
@@ -783,10 +799,20 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal)
 			in_window = 1;
 			curr_win_min = curr_win_max = rffd;
 			mfsdram(SDRAM_RDCC, rdcc);	/* record this value */
+
+			if (!(check_fcsr_oversample_miss(bxcr_num)))
+				pass = 0;
 		} else if (!pass && in_window) {	/* end passing window */
 			in_window = 0;
+			break;				/* exit end of window */
 		} else if (pass && in_window) {	/* within the passing window */
 			curr_win_max = rffd;
+
+			if (!(check_fcsr_oversample_miss(bxcr_num))) {
+				pass = 0;
+				in_window = 0;
+				break;			/* exit end of window */
+			}
 		}
 
 		if (in_window) {
@@ -849,6 +875,7 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal)
 			curr_win_min = curr_win_max = rqfd;
 		} else if (!pass && in_window) {
 			in_window = 0;
+			break;				/* exit end of window */
 		} else if (pass && in_window) {
 			curr_win_max = rqfd;
 		}
-- 
1.5.5