ppc4xx: Update Katmai/44x_spd_ddr2.c code for optimal DDR2 setup
authorStefan Roese <sr@denx.de>
Sat, 5 Jan 2008 08:12:41 +0000 (09:12 +0100)
committerStefan Roese <sr@denx.de>
Sat, 5 Jan 2008 08:12:41 +0000 (09:12 +0100)
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.

This patch also adds RDCC calibration as mentioned on page 7 of
the AMCC PowerPC440SP/SPe DDR2 application note:
"DDR1/DDR2 Initialization Sequence and Dynamic Tuning"

Signed-off-by: Stefan Roese <sr@denx.de>
board/amcc/katmai/katmai.c
cpu/ppc4xx/44x_spd_ddr2.c
include/configs/katmai.h
include/ppc440.h

index 25c9a22feabf04e4554ab019382852f51740cdfc..e41caaf344cf5d0f60782a3bafe250df5e1405e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -246,6 +246,18 @@ int checkboard (void)
        return 0;
 }
 
+/*
+ * Override the default functions in cpu/ppc4xx/44x_spd_ddr2.c with
+ * board specific values.
+ */
+u32 ddr_wrdtr(u32 default_val) {
+       return (SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_180_DEG_ADV | 0x823);
+}
+
+u32 ddr_clktr(u32 default_val) {
+       return (SDRAM_CLKTR_CLKP_90_DEG_ADV);
+}
+
 #if defined(CFG_DRAM_TEST)
 int testdram (void)
 {
index e19929437e2d4d0c389ada193fa64274da40c6be..2475ed95ecf4d20203a8c1a193fa033c95c4cbda 100644 (file)
@@ -3,7 +3,7 @@
  * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
  * DDR2 controller (non Denali Core). Those are 440SP/SPe.
  *
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * COPYRIGHT   AMCC   CORPORATION 2004
@@ -2409,17 +2409,10 @@ static void program_DQS_calibration(unsigned long *dimm_populated,
         * 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);
        mtsdram(SDRAM_RDCC,
                (val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK))
-               | (SDRAM_RDCC_RDSS_T4 | SDRAM_RDCC_RSAE_DISABLE));
+               | SDRAM_RDCC_RSAE_ENABLE);
 
        /*------------------------------------------------------------------
         * Program RQDC register
@@ -2512,10 +2505,7 @@ static void DQS_calibration_process(void)
 {
        unsigned long rfdc_reg;
        unsigned long rffd;
-       unsigned long rqdc_reg;
-       unsigned long rqfd;
        unsigned long val;
-       long rqfd_average;
        long rffd_average;
        long max_start;
        long min_end;
@@ -2533,10 +2523,14 @@ static void DQS_calibration_process(void)
        long max_end;
        unsigned char fail_found;
        unsigned char pass_found;
+#if !defined(CONFIG_DDR_RQDC_FIXED)
+       u32 rqdc_reg;
+       u32 rqfd;
        u32 rqfd_start;
+       u32 rqfd_average;
+       int loopi = 0;
        char str[] = "Auto calibration -";
        char slash[] = "\\|/-\\|/-";
-       int loopi = 0;
 
        /*------------------------------------------------------------------
         * Test to determine the best read clock delay tuning bits.
@@ -2571,6 +2565,16 @@ calibration_loop:
        mfsdram(SDRAM_RQDC, rqdc_reg);
        mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
                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;
        min_end = 0;
@@ -2655,6 +2659,7 @@ calibration_loop:
        /* now fix RFDC[RFFD] found and find RQDC[RQFD] */
        mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
 
+#if !defined(CONFIG_DDR_RQDC_FIXED)
        max_pass_length = 0;
        max_start = 0;
        max_end = 0;
@@ -2727,8 +2732,6 @@ calibration_loop:
                spd_ddr_init_hang ();
        }
 
-       blank_string(strlen(str));
-
        if (rqfd_average < 0)
                rqfd_average = 0;
 
@@ -2739,12 +2742,31 @@ calibration_loop:
                (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
                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);
        debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val);
        mfsdram(SDRAM_RQDC, val);
        debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
        mfsdram(SDRAM_RFDC, 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 */
 /*-----------------------------------------------------------------------------+
index 0aa4f2dcc05eeb65d1c8fe4ca5804f50c14525bb..78c794a05de0b3e79eaad0368d9d5ebed06bd9aa 100644 (file)
 #define CONFIG_SPD_EEPROM      1       /* Use SPD EEPROM for setup     */
 #define SPD_EEPROM_ADDRESS     {0x51, 0x52}    /* SPD i2c spd addresses*/
 #define CONFIG_DDR_ECC         1       /* with ECC support             */
+#define CONFIG_DDR_RQDC_FIXED  0x80000038 /* optimal value found by GDA*/
 #undef  CONFIG_STRESS
 
 /*-----------------------------------------------------------------------
index 90e56b0989efaa9dfa2b02b4e3a97258642bd1ca..bfd1e10338de56d717b004a2dc25c0b8eaf86316 100644 (file)
 #define SDRAM_ECCCR    0x98    /* ECC error status                          */
 #define SDRAM_CID      0xA4    /* core ID                                   */
 #define SDRAM_RID      0xA8    /* revision ID                               */
+#define SDRAM_RTSR     0xB1    /* run time status tracking                  */
 
 /*-----------------------------------------------------------------------------+
 |  Memory Controller Status
 #define SDRAM_RFDC_ARSE_ENABLE         0x00000000
 #define SDRAM_RFDC_RFOS_MASK           0x007F0000
 #define SDRAM_RFDC_RFOS_ENCODE(n)      ((((unsigned long)(n))&0x7F)<<16)
-#define SDRAM_RFDC_RFFD_MASK           0x000003FF
-#define SDRAM_RFDC_RFFD_ENCODE(n)      ((((unsigned long)(n))&0x3FF)<<0)
+#define SDRAM_RFDC_RFFD_MASK           0x000007FF
+#define SDRAM_RFDC_RFFD_ENCODE(n)      ((((unsigned long)(n))&0x7FF)<<0)
 
 #define SDRAM_RFDC_RFFD_MAX            0x7FF
 
 #define SDRAM_CLKTR_CLKP_MASK          0xC0000000
 #define SDRAM_CLKTR_CLKP_0_DEG         0x00000000
 #define SDRAM_CLKTR_CLKP_180_DEG_ADV   0x80000000
+#define SDRAM_CLKTR_CLKP_90_DEG_ADV    0x40000000
 
 /*-----------------------------------------------------------------------------+
 |  SDRAM Write Timing Register
 #define SDRAM_BXCF_M_BE_DISABLE                0x00000000      /* Memory Bank Enable   */
 #define SDRAM_BXCF_M_BE_ENABLE         0x00000001      /* Memory Bank Enable   */
 
+#define SDRAM_RTSR_TRK1SM_MASK         0xC0000000      /* Tracking State Mach 1*/
+#define SDRAM_RTSR_TRK1SM_ATBASE       0x00000000      /* atbase state         */
+#define SDRAM_RTSR_TRK1SM_MISSED       0x40000000      /* missed state         */
+#define SDRAM_RTSR_TRK1SM_ATPLS1       0x80000000      /* atpls1 state         */
+#define SDRAM_RTSR_TRK1SM_RESET                0xC0000000      /* reset  state         */
+
 #define SDR0_MFR_FIXD                  0x10000000      /* Workaround for PCI/DMA */
 #endif /* CONFIG_440SPE */