|
@@ -3,7 +3,7 @@
|
|
* This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
|
|
* This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
|
|
* DDR2 controller (non Denali Core). Those are 440SP/SPe.
|
|
* DDR2 controller (non Denali Core). Those are 440SP/SPe.
|
|
*
|
|
*
|
|
- * (C) Copyright 2007
|
|
|
|
|
|
+ * (C) Copyright 2007-2008
|
|
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
|
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
|
*
|
|
*
|
|
* COPYRIGHT AMCC CORPORATION 2004
|
|
* COPYRIGHT AMCC CORPORATION 2004
|
|
@@ -2409,17 +2409,10 @@ static void program_DQS_calibration(unsigned long *dimm_populated,
|
|
* Read sample cycle auto-update enable
|
|
* Read sample cycle auto-update enable
|
|
*-----------------------------------------------------------------*/
|
|
*-----------------------------------------------------------------*/
|
|
|
|
|
|
- /*
|
|
|
|
- * Modified for the Katmai platform: with some DIMMs, the DDR2
|
|
|
|
- * controller automatically selects the T2 read cycle, but this
|
|
|
|
- * proves unreliable. Go ahead and force the DDR2 controller
|
|
|
|
- * to use the T4 sample and disable the automatic update of the
|
|
|
|
- * RDSS field.
|
|
|
|
- */
|
|
|
|
mfsdram(SDRAM_RDCC, val);
|
|
mfsdram(SDRAM_RDCC, val);
|
|
mtsdram(SDRAM_RDCC,
|
|
mtsdram(SDRAM_RDCC,
|
|
(val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK))
|
|
(val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK))
|
|
- | (SDRAM_RDCC_RDSS_T4 | SDRAM_RDCC_RSAE_DISABLE));
|
|
|
|
|
|
+ | SDRAM_RDCC_RSAE_ENABLE);
|
|
|
|
|
|
/*------------------------------------------------------------------
|
|
/*------------------------------------------------------------------
|
|
* Program RQDC register
|
|
* Program RQDC register
|
|
@@ -2512,10 +2505,7 @@ static void DQS_calibration_process(void)
|
|
{
|
|
{
|
|
unsigned long rfdc_reg;
|
|
unsigned long rfdc_reg;
|
|
unsigned long rffd;
|
|
unsigned long rffd;
|
|
- unsigned long rqdc_reg;
|
|
|
|
- unsigned long rqfd;
|
|
|
|
unsigned long val;
|
|
unsigned long val;
|
|
- long rqfd_average;
|
|
|
|
long rffd_average;
|
|
long rffd_average;
|
|
long max_start;
|
|
long max_start;
|
|
long min_end;
|
|
long min_end;
|
|
@@ -2533,10 +2523,14 @@ static void DQS_calibration_process(void)
|
|
long max_end;
|
|
long max_end;
|
|
unsigned char fail_found;
|
|
unsigned char fail_found;
|
|
unsigned char pass_found;
|
|
unsigned char pass_found;
|
|
|
|
+#if !defined(CONFIG_DDR_RQDC_FIXED)
|
|
|
|
+ u32 rqdc_reg;
|
|
|
|
+ u32 rqfd;
|
|
u32 rqfd_start;
|
|
u32 rqfd_start;
|
|
|
|
+ u32 rqfd_average;
|
|
|
|
+ int loopi = 0;
|
|
char str[] = "Auto calibration -";
|
|
char str[] = "Auto calibration -";
|
|
char slash[] = "\\|/-\\|/-";
|
|
char slash[] = "\\|/-\\|/-";
|
|
- int loopi = 0;
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------
|
|
/*------------------------------------------------------------------
|
|
* Test to determine the best read clock delay tuning bits.
|
|
* Test to determine the best read clock delay tuning bits.
|
|
@@ -2571,6 +2565,16 @@ calibration_loop:
|
|
mfsdram(SDRAM_RQDC, rqdc_reg);
|
|
mfsdram(SDRAM_RQDC, rqdc_reg);
|
|
mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
|
|
mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
|
|
SDRAM_RQDC_RQFD_ENCODE(rqfd_start));
|
|
SDRAM_RQDC_RQFD_ENCODE(rqfd_start));
|
|
|
|
+#else /* CONFIG_DDR_RQDC_FIXED */
|
|
|
|
+ /*
|
|
|
|
+ * On Katmai the complete auto-calibration somehow doesn't seem to
|
|
|
|
+ * produce the best results, meaning optimal values for RQFD/RFFD.
|
|
|
|
+ * This was discovered by GDA using a high bandwidth scope,
|
|
|
|
+ * analyzing the DDR2 signals. GDA provided a fixed value for RQFD,
|
|
|
|
+ * so now on Katmai "only" RFFD is auto-calibrated.
|
|
|
|
+ */
|
|
|
|
+ mtsdram(SDRAM_RQDC, CONFIG_DDR_RQDC_FIXED);
|
|
|
|
+#endif /* CONFIG_DDR_RQDC_FIXED */
|
|
|
|
|
|
max_start = 0;
|
|
max_start = 0;
|
|
min_end = 0;
|
|
min_end = 0;
|
|
@@ -2655,6 +2659,7 @@ calibration_loop:
|
|
/* now fix RFDC[RFFD] found and find RQDC[RQFD] */
|
|
/* now fix RFDC[RFFD] found and find RQDC[RQFD] */
|
|
mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
|
|
mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
|
|
|
|
|
|
|
|
+#if !defined(CONFIG_DDR_RQDC_FIXED)
|
|
max_pass_length = 0;
|
|
max_pass_length = 0;
|
|
max_start = 0;
|
|
max_start = 0;
|
|
max_end = 0;
|
|
max_end = 0;
|
|
@@ -2727,8 +2732,6 @@ calibration_loop:
|
|
spd_ddr_init_hang ();
|
|
spd_ddr_init_hang ();
|
|
}
|
|
}
|
|
|
|
|
|
- blank_string(strlen(str));
|
|
|
|
-
|
|
|
|
if (rqfd_average < 0)
|
|
if (rqfd_average < 0)
|
|
rqfd_average = 0;
|
|
rqfd_average = 0;
|
|
|
|
|
|
@@ -2739,12 +2742,31 @@ calibration_loop:
|
|
(rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
|
|
(rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
|
|
SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
|
|
SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
|
|
|
|
|
|
|
|
+ blank_string(strlen(str));
|
|
|
|
+#endif /* CONFIG_DDR_RQDC_FIXED */
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Now complete RDSS configuration as mentioned on page 7 of the AMCC
|
|
|
|
+ * PowerPC440SP/SPe DDR2 application note:
|
|
|
|
+ * "DDR1/DDR2 Initialization Sequence and Dynamic Tuning"
|
|
|
|
+ */
|
|
|
|
+ mfsdram(SDRAM_RTSR, val);
|
|
|
|
+ if ((val & SDRAM_RTSR_TRK1SM_MASK) == SDRAM_RTSR_TRK1SM_ATPLS1) {
|
|
|
|
+ mfsdram(SDRAM_RDCC, val);
|
|
|
|
+ if ((val & SDRAM_RDCC_RDSS_MASK) != SDRAM_RDCC_RDSS_T4) {
|
|
|
|
+ val += 0x40000000;
|
|
|
|
+ mtsdram(SDRAM_RDCC, val);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
mfsdram(SDRAM_DLCR, val);
|
|
mfsdram(SDRAM_DLCR, val);
|
|
debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
mfsdram(SDRAM_RQDC, val);
|
|
mfsdram(SDRAM_RQDC, val);
|
|
debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
mfsdram(SDRAM_RFDC, val);
|
|
mfsdram(SDRAM_RFDC, val);
|
|
debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
|
|
+ mfsdram(SDRAM_RDCC, val);
|
|
|
|
+ debug("%s[%d] RDCC: 0x%08X\n", __FUNCTION__, __LINE__, val);
|
|
}
|
|
}
|
|
#else /* calibration test with hardvalues */
|
|
#else /* calibration test with hardvalues */
|
|
/*-----------------------------------------------------------------------------+
|
|
/*-----------------------------------------------------------------------------+
|