]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - cpu/ppc4xx/44x_spd_ddr2.c
Merge branch 'master' of /home/stefan/git/u-boot/u-boot
[karo-tx-uboot.git] / cpu / ppc4xx / 44x_spd_ddr2.c
index d7177c9908975d008731af094612420e7b7b70d4..3bafea3a95834b37e6a83e4f103c0f93b831cccb 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
@@ -58,8 +58,8 @@
 #define SDRAM_DDR2     2
 #define SDRAM_NONE     0
 
-#define MAXDIMMS       2
-#define MAXRANKS       4
+#define MAXDIMMS       2
+#define MAXRANKS       4
 #define MAXBXCF                4
 #define MAX_SPD_BYTES  256   /* Max number of bytes on the DIMM's SPD EEPROM */
 
 #define CALC_ODT_RW(n) (CALC_ODT_R(n) | CALC_ODT_W(n))
 
 /* Defines for the Read Cycle Delay test */
-#define NUMMEMTESTS 8
-#define NUMMEMWORDS 8
-
-#define CONFIG_ECC_ERROR_RESET         /* test-only: see description below, at check_ecc() */
+#define NUMMEMTESTS    8
+#define NUMMEMWORDS    8
+#define NUMLOOPS       64              /* memory test loops */
 
 /*
  * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
  * memory.
  *
  * If at some time this restriction doesn't apply anymore, just define
- * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * CONFIG_4xx_DCACHE in the board config file and this code should setup
  * everything correctly.
  */
-#ifdef CFG_ENABLE_SDRAM_CACHE
+#ifdef CONFIG_4xx_DCACHE
 #define MY_TLB_WORD2_I_ENABLE  0                       /* enable caching on SDRAM */
 #else
 #define MY_TLB_WORD2_I_ENABLE  TLB_WORD2_I_ENABLE      /* disable caching on SDRAM */
 #endif
 
+/*
+ * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
+ */
+void __spd_ddr_init_hang (void)
+{
+       hang ();
+}
+void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
+
+/*
+ * To provide an interface for board specific config values in this common
+ * DDR setup code, we implement he "weak" default functions here. They return
+ * the default value back to the caller.
+ *
+ * Please see include/configs/yucca.h for an example fora board specific
+ * implementation.
+ */
+u32 __ddr_wrdtr(u32 default_val)
+{
+       return default_val;
+}
+u32 ddr_wrdtr(u32) __attribute__((weak, alias("__ddr_wrdtr")));
+
+u32 __ddr_clktr(u32 default_val)
+{
+       return default_val;
+}
+u32 ddr_clktr(u32) __attribute__((weak, alias("__ddr_clktr")));
+
+
 /* Private Structure Definitions */
 
 /* enum only to ease code for cas latency setting */
@@ -143,7 +172,6 @@ typedef enum ddr_cas_id {
  * Prototypes
  *-----------------------------------------------------------------------------*/
 static unsigned long sdram_memsize(void);
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
 static void get_spd_info(unsigned long *dimm_populated,
                         unsigned char *iic0_dimm_addr,
                         unsigned long num_dimm_banks);
@@ -205,9 +233,7 @@ static void test(void);
 #else
 static void    DQS_calibration_process(void);
 #endif
-#if defined(DEBUG)
 static void ppc440sp_sdram_register_dump(void);
-#endif
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 void dcbz_area(u32 start_address, u32 num_bytes);
 void dflush(void);
@@ -361,9 +387,9 @@ long int initdram(int board_type)
        unsigned char spd1[MAX_SPD_BYTES];
        unsigned char *dimm_spd[MAXDIMMS];
        unsigned long dimm_populated[MAXDIMMS];
-       unsigned long num_dimm_banks;               /* on board dimm banks */
+       unsigned long num_dimm_banks;           /* on board dimm banks */
        unsigned long val;
-       ddr_cas_id_t  selected_cas;
+       ddr_cas_id_t selected_cas = DDR_CAS_5;  /* preset to silence compiler */
        int write_recovery;
        unsigned long dram_size = 0;
 
@@ -458,13 +484,14 @@ long int initdram(int board_type)
         *-----------------------------------------------------------------*/
        mfsdram(SDRAM_WRDTR, val);
        mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |
-               (SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV));
+               ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV));
 
        /*------------------------------------------------------------------
         * Set the SDRAM Clock Timing Register
         *-----------------------------------------------------------------*/
        mfsdram(SDRAM_CLKTR, val);
-       mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_0_DEG);
+       mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) |
+               ddr_clktr(SDRAM_CLKTR_CLKP_0_DEG));
 
        /*------------------------------------------------------------------
         * Program the BxCF registers.
@@ -523,7 +550,12 @@ long int initdram(int board_type)
        dram_size = sdram_memsize();
 
        /* and program tlb entries for this size (dynamic) */
-       program_tlb(0, dram_size, MY_TLB_WORD2_I_ENABLE);
+
+       /*
+        * Program TLB entries with caches enabled, for best performace
+        * while auto-calibrating and ECC generation
+        */
+       program_tlb(0, 0, dram_size, 0);
 
        /*------------------------------------------------------------------
         * DQS calibration.
@@ -534,12 +566,18 @@ long int initdram(int board_type)
        /*------------------------------------------------------------------
         * If ecc is enabled, initialize the parity bits.
         *-----------------------------------------------------------------*/
-       program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, MY_TLB_WORD2_I_ENABLE);
+       program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, 0);
 #endif
 
-#ifdef DEBUG
+       /*
+        * Now after initialization (auto-calibration and ECC generation)
+        * remove the TLB entries with caches enabled and program again with
+        * desired cache functionality
+        */
+       remove_tlb(0, dram_size);
+       program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE);
+
        ppc440sp_sdram_register_dump();
-#endif
 
        return dram_size;
 }
@@ -577,19 +615,30 @@ static void get_spd_info(unsigned long *dimm_populated,
 
        if (dimm_found == FALSE) {
                printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
-               hang();
+               spd_ddr_init_hang ();
        }
 }
 
-#ifdef CONFIG_ADD_RAM_INFO
 void board_add_ram_info(int use_default)
 {
+       PPC4xx_SYS_INFO board_cfg;
+       u32 val;
+
        if (is_ecc_enabled())
-               puts(" (ECC enabled)");
+               puts(" (ECC");
        else
-               puts(" (ECC not enabled)");
+               puts(" (ECC not");
+
+       get_sys_info(&board_cfg);
+
+       mfsdr(SDR0_DDR0, val);
+       val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
+       printf(" enabled, %d MHz", (val * 2) / 1000000);
+
+       mfsdram(SDRAM_MMODE, val);
+       val = (val & SDRAM_MMODE_DCL_MASK) >> 4;
+       printf(", CL%d)", val);
 }
-#endif
 
 /*------------------------------------------------------------------
  * For the memory DIMMs installed, this routine verifies that they
@@ -611,42 +660,42 @@ static void check_mem_type(unsigned long *dimm_populated,
                                       "slot %d.\n", (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 2:
                                printf("ERROR: EDO DIMM detected in slot %d.\n",
                                       (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 3:
                                printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n",
                                       (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 4:
                                printf("ERROR: SDRAM DIMM detected in slot %d.\n",
                                       (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 5:
                                printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n",
                                       (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 6:
                                printf("ERROR: SGRAM DIMM detected in slot %d.\n",
                                       (unsigned int)dimm_num);
                                printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 7:
                                debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num);
@@ -661,7 +710,7 @@ static void check_mem_type(unsigned long *dimm_populated,
                                       (unsigned int)dimm_num);
                                printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n");
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        }
                }
@@ -671,7 +720,7 @@ static void check_mem_type(unsigned long *dimm_populated,
                    && (dimm_populated[dimm_num]   != SDRAM_NONE)
                    && (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) {
                        printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n");
-                       hang();
+                       spd_ddr_init_hang ();
                }
        }
 }
@@ -690,7 +739,7 @@ static void check_frequency(unsigned long *dimm_populated,
        unsigned long calc_cycle_time;
        unsigned long sdram_freq;
        unsigned long sdr_ddrpll;
-       PPC440_SYS_INFO board_cfg;
+       PPC4xx_SYS_INFO board_cfg;
 
        /*------------------------------------------------------------------
         * Get the board configuration info.
@@ -731,6 +780,7 @@ static void check_frequency(unsigned long *dimm_populated,
                        else
                                cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) +
                                        ((tcyc_reg & 0x0F)*10);
+                       debug("cycle_time=%d [10 picoseconds]\n", cycle_time);
 
                        if  (cycle_time > (calc_cycle_time + 10)) {
                                /*
@@ -745,7 +795,7 @@ static void check_frequency(unsigned long *dimm_populated,
                                       (unsigned int)(calc_cycle_time*10));
                                printf("Replace the DIMM, or change DDR frequency via "
                                       "strapping bits.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                        }
                }
        }
@@ -777,7 +827,7 @@ static void check_rank_number(unsigned long *dimm_populated,
                                       "slot %d is not supported.\n", dimm_rank, dimm_num);
                                printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                        } else
                                total_rank += dimm_rank;
                }
@@ -786,7 +836,7 @@ static void check_rank_number(unsigned long *dimm_populated,
                               "for all slots.\n", (unsigned int)total_rank);
                        printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
                        printf("Remove one of the DIMM modules.\n\n");
-                       hang();
+                       spd_ddr_init_hang ();
                }
        }
 }
@@ -811,28 +861,28 @@ static void check_voltage_type(unsigned long *dimm_populated,
                                printf("This DIMM is 5.0 Volt/TTL.\n");
                                printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
                                       (unsigned int)dimm_num);
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 0x01:
                                printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
                                printf("This DIMM is LVTTL.\n");
                                printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
                                       (unsigned int)dimm_num);
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 0x02:
                                printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
                                printf("This DIMM is 1.5 Volt.\n");
                                printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
                                       (unsigned int)dimm_num);
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 0x03:
                                printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
                                printf("This DIMM is 3.3 Volt/TTL.\n");
                                printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
                                       (unsigned int)dimm_num);
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        case 0x04:
                                /* 2.5 Voltage only for DDR1 */
@@ -844,7 +894,7 @@ static void check_voltage_type(unsigned long *dimm_populated,
                                printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
                                printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
                                       (unsigned int)dimm_num);
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        }
                }
@@ -987,13 +1037,13 @@ static void program_copt1(unsigned long *dimm_populated,
        if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) {
                if (buf0 != buf1) {
                        printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n");
-                       hang();
+                       spd_ddr_init_hang ();
                }
        }
 
        if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) {
                printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n");
-               hang();
+               spd_ddr_init_hang ();
        }
        else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) {
                mcopt1 |= SDRAM_MCOPT1_DMWD_64;
@@ -1001,7 +1051,7 @@ static void program_copt1(unsigned long *dimm_populated,
                mcopt1 |= SDRAM_MCOPT1_DMWD_32;
        } else {
                printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n");
-               hang();
+               spd_ddr_init_hang ();
        }
 
        if (ecc_enabled == TRUE)
@@ -1102,7 +1152,8 @@ static void program_codt(unsigned long *dimm_populated,
                                modt3 = 0x00000000;
                        }
                        if (total_rank == 4) {
-                               codt |= CALC_ODT_R(0) | CALC_ODT_R(1) | CALC_ODT_R(2) | CALC_ODT_R(3);
+                               codt |= CALC_ODT_R(0) | CALC_ODT_R(1) |
+                                       CALC_ODT_R(2) | CALC_ODT_R(3);
                                modt0 = CALC_ODT_RW(2);
                                modt1 = 0x00000000;
                                modt2 = CALC_ODT_RW(0);
@@ -1189,7 +1240,7 @@ static void program_initplr(unsigned long *dimm_populated,
                        break;
                default:
                        printf("ERROR: ucode error on selected_cas value %d", selected_cas);
-                       hang();
+                       spd_ddr_init_hang ();
                        break;
                }
 
@@ -1221,7 +1272,7 @@ static void program_initplr(unsigned long *dimm_populated,
                        break;
                default:
                        printf("ERROR: write recovery not support (%d)", write_recovery);
-                       hang();
+                       spd_ddr_init_hang ();
                        break;
                }
 #else
@@ -1239,7 +1290,7 @@ static void program_initplr(unsigned long *dimm_populated,
                        ods = ODS_REDUCED;
                } else {
                        printf("ERROR: Unsupported number of DIMM's (%d)", total_dimm);
-                       hang();
+                       spd_ddr_init_hang ();
                }
 
                mr = CMD_EMR | SELECT_MR | BURST_LEN_4 | wr | cas;
@@ -1264,7 +1315,7 @@ static void program_initplr(unsigned long *dimm_populated,
                mtsdram(SDRAM_INITPLR13, 0x80800000 | emr);             /* EMR OCD Exit */
        } else {
                printf("ERROR: ucode error as unknown DDR type in program_initplr");
-               hang();
+               spd_ddr_init_hang ();
        }
 }
 
@@ -1300,7 +1351,7 @@ static void program_mode(unsigned long *dimm_populated,
        unsigned long max_4_0_tcyc_ns_x_100;
        unsigned long max_5_0_tcyc_ns_x_100;
        unsigned long cycle_time_ns_x_100[3];
-       PPC440_SYS_INFO board_cfg;
+       PPC4xx_SYS_INFO board_cfg;
        unsigned char cas_2_0_available;
        unsigned char cas_2_5_available;
        unsigned char cas_3_0_available;
@@ -1315,6 +1366,7 @@ static void program_mode(unsigned long *dimm_populated,
 
        mfsdr(SDR0_DDR0, sdr_ddrpll);
        sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1);
+       debug("sdram_freq=%d\n", sdram_freq);
 
        /*------------------------------------------------------------------
         * Handle the timing.  We need to find the worst case timing of all
@@ -1344,6 +1396,7 @@ static void program_mode(unsigned long *dimm_populated,
 
                        /* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /*  not used in this loop. */
                        cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
+                       debug("cas_bit[SPD byte 18]=%02x\n", cas_bit);
 
                        /* For a particular DIMM, grab the three CAS values it supports */
                        for (cas_index = 0; cas_index < 3; cas_index++) {
@@ -1362,17 +1415,21 @@ static void program_mode(unsigned long *dimm_populated,
                                if ((tcyc_reg & 0x0F) >= 10) {
                                        if ((tcyc_reg & 0x0F) == 0x0D) {
                                                /* Convert from hex to decimal */
-                                               cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + 75;
+                                               cycle_time_ns_x_100[cas_index] =
+                                                       (((tcyc_reg & 0xF0) >> 4) * 100) + 75;
                                        } else {
                                                printf("ERROR: SPD reported Tcyc is incorrect for DIMM "
                                                       "in slot %d\n", (unsigned int)dimm_num);
-                                               hang();
+                                               spd_ddr_init_hang ();
                                        }
                                } else {
                                        /* Convert from hex to decimal */
-                                       cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) +
+                                       cycle_time_ns_x_100[cas_index] =
+                                               (((tcyc_reg & 0xF0) >> 4) * 100) +
                                                ((tcyc_reg & 0x0F)*10);
                                }
+                               debug("cas_index=%d: cycle_time_ns_x_100=%d\n", cas_index,
+                                     cycle_time_ns_x_100[cas_index]);
                        }
 
                        /* The rest of this routine determines if CAS 2.0, 2.5, 3.0, 4.0 and 5.0 are */
@@ -1385,8 +1442,10 @@ static void program_mode(unsigned long *dimm_populated,
                                 *  Bit   7    6    5    4    3    2    1    0
                                 *       TBD  4.0  3.5  3.0  2.5  2.0  1.5  1.0
                                 */
-                               if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1394,8 +1453,10 @@ static void program_mode(unsigned long *dimm_populated,
                                        cas_4_0_available = FALSE;
                                }
 
-                               if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1403,8 +1464,10 @@ static void program_mode(unsigned long *dimm_populated,
                                        cas_3_0_available = FALSE;
                                }
 
-                               if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1412,8 +1475,10 @@ static void program_mode(unsigned long *dimm_populated,
                                        cas_2_5_available = FALSE;
                                }
 
-                               if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1426,8 +1491,10 @@ static void program_mode(unsigned long *dimm_populated,
                                 *  Bit   7    6    5    4    3    2    1    0
                                 *       TBD  6.0  5.0  4.0  3.0  2.0  TBD  TBD
                                 */
-                               if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1435,8 +1502,10 @@ static void program_mode(unsigned long *dimm_populated,
                                        cas_5_0_available = FALSE;
                                }
 
-                               if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1444,8 +1513,10 @@ static void program_mode(unsigned long *dimm_populated,
                                        cas_4_0_available = FALSE;
                                }
 
-                               if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) {
-                                       max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]);
+                               if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) &&
+                                   (cycle_time_ns_x_100[cas_index] != 0)) {
+                                       max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100,
+                                                                   cycle_time_ns_x_100[cas_index]);
                                        cas_index++;
                                } else {
                                        if (cas_index != 0)
@@ -1468,6 +1539,9 @@ static void program_mode(unsigned long *dimm_populated,
        cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100) + 10;
        cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100) + 10;
        cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100) + 10;
+       debug("cycle_3_0_clk=%d\n", cycle_3_0_clk);
+       debug("cycle_4_0_clk=%d\n", cycle_4_0_clk);
+       debug("cycle_5_0_clk=%d\n", cycle_5_0_clk);
 
        if (sdram_ddr1 == TRUE) { /* DDR1 */
                if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) {
@@ -1483,9 +1557,12 @@ static void program_mode(unsigned long *dimm_populated,
                        printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n");
                        printf("Only DIMMs DDR1 with CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
                        printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n");
-                       hang();
+                       spd_ddr_init_hang ();
                }
        } else { /* DDR2 */
+               debug("cas_3_0_available=%d\n", cas_3_0_available);
+               debug("cas_4_0_available=%d\n", cas_4_0_available);
+               debug("cas_5_0_available=%d\n", cas_5_0_available);
                if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) {
                        mmode |= SDRAM_MMODE_DCL_DDR2_3_0_CLK;
                        *selected_cas = DDR_CAS_3;
@@ -1503,7 +1580,7 @@ static void program_mode(unsigned long *dimm_populated,
                               cas_3_0_available, cas_4_0_available, cas_5_0_available);
                        printf("sdram_freq=%d cycle3=%d cycle4=%d cycle5=%d\n\n",
                               sdram_freq, cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
-                       hang();
+                       spd_ddr_init_hang ();
                }
        }
 
@@ -1561,7 +1638,7 @@ static void program_rtr(unsigned long *dimm_populated,
                        unsigned char *iic0_dimm_addr,
                        unsigned long num_dimm_banks)
 {
-       PPC440_SYS_INFO board_cfg;
+       PPC4xx_SYS_INFO board_cfg;
        unsigned long max_refresh_rate;
        unsigned long dimm_num;
        unsigned long refresh_rate_type;
@@ -1612,7 +1689,7 @@ static void program_rtr(unsigned long *dimm_populated,
                                printf("ERROR: DIMM %d unsupported refresh rate/type.\n",
                                       (unsigned int)dimm_num);
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                                break;
                        }
 
@@ -1658,7 +1735,7 @@ static void program_tr(unsigned long *dimm_populated,
        unsigned long sdram_freq;
        unsigned long sdr_ddrpll;
 
-       PPC440_SYS_INFO board_cfg;
+       PPC4xx_SYS_INFO board_cfg;
 
        /*------------------------------------------------------------------
         * Get the board configuration info.
@@ -1969,14 +2046,10 @@ static void program_bxcf(unsigned long *dimm_populated,
        /*------------------------------------------------------------------
         * Set the BxCF regs.  First, wipe out the bank config registers.
         *-----------------------------------------------------------------*/
-       mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF);
-       mtdcr(SDRAMC_CFGDATA, 0x00000000);
-       mtdcr(SDRAMC_CFGADDR, SDRAM_MB1CF);
-       mtdcr(SDRAMC_CFGDATA, 0x00000000);
-       mtdcr(SDRAMC_CFGADDR, SDRAM_MB2CF);
-       mtdcr(SDRAMC_CFGDATA, 0x00000000);
-       mtdcr(SDRAMC_CFGADDR, SDRAM_MB3CF);
-       mtdcr(SDRAMC_CFGDATA, 0x00000000);
+       mtsdram(SDRAM_MB0CF, 0x00000000);
+       mtsdram(SDRAM_MB1CF, 0x00000000);
+       mtsdram(SDRAM_MB2CF, 0x00000000);
+       mtsdram(SDRAM_MB3CF, 0x00000000);
 
        mode = SDRAM_BXCF_M_BE_ENABLE;
 
@@ -2020,7 +2093,7 @@ static void program_bxcf(unsigned long *dimm_populated,
                                        printf("ERROR: Unsupported value for number of "
                                               "column addresses: %d.\n", (unsigned int)num_col_addr);
                                        printf("Replace the DIMM module with a supported DIMM.\n\n");
-                                       hang();
+                                       spd_ddr_init_hang ();
                                }
                        }
 
@@ -2028,8 +2101,9 @@ static void program_bxcf(unsigned long *dimm_populated,
                                bank_0_populated = 1;
 
                        for (ind_rank = 0; ind_rank < num_ranks; ind_rank++) {
-                               mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF + ((dimm_num + bank_0_populated + ind_rank) << 2));
-                               mtdcr(SDRAMC_CFGDATA, mode);
+                               mtsdram(SDRAM_MB0CF +
+                                       ((dimm_num + bank_0_populated + ind_rank) << 2),
+                                       mode);
                        }
                }
        }
@@ -2102,7 +2176,7 @@ static void program_memory_queue(unsigned long *dimm_populated,
                                printf("ERROR: Unsupported value for the banksize: %d.\n",
                                       (unsigned int)rank_size_id);
                                printf("Replace the DIMM module with a supported DIMM.\n\n");
-                               hang();
+                               spd_ddr_init_hang ();
                        }
 
                        if ((dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_num == 1))
@@ -2137,6 +2211,18 @@ static unsigned long is_ecc_enabled(void)
        return ecc;
 }
 
+static void blank_string(int size)
+{
+       int i;
+
+       for (i=0; i<size; i++)
+               putc('\b');
+       for (i=0; i<size; i++)
+               putc(' ');
+       for (i=0; i<size; i++)
+               putc('\b');
+}
+
 #ifdef CONFIG_DDR_ECC
 /*-----------------------------------------------------------------------------+
  * program_ecc.
@@ -2180,39 +2266,6 @@ static void program_ecc(unsigned long *dimm_populated,
        return;
 }
 
-#ifdef CONFIG_ECC_ERROR_RESET
-/*
- * Check for ECC errors and reset board upon any error here
- *
- * On the Katmai 440SPe eval board, from time to time, the first
- * lword write access after DDR2 initializazion with ECC checking
- * enabled, leads to an ECC error. I couldn't find a configuration
- * without this happening. On my board with the current setup it
- * happens about 1 from 10 times.
- *
- * The ECC modules used for testing are:
- * - Kingston ValueRAM KVR667D2E5/512 (tested with 1 and 2 DIMM's)
- *
- * This has to get fixed for the Katmai and tested for the other
- * board (440SP/440SPe) that will eventually use this code in the
- * future.
- *
- * 2007-03-01, sr
- */
-static void check_ecc(void)
-{
-       u32 val;
-
-       mfsdram(SDRAM_ECCCR, val);
-       if (val != 0) {
-               printf("\nECC error: MCIF0_ECCES=%08lx MQ0_ESL=%08lx address=%08lx\n",
-                      val, mfdcr(0x4c), mfdcr(0x4e));
-               printf("ECC error occured, resetting board...\n");
-               do_reset(NULL, 0, 0, NULL);
-       }
-}
-#endif
-
 static void wait_ddr_idle(void)
 {
        u32 val;
@@ -2233,8 +2286,10 @@ static void program_ecc_addr(unsigned long start_address,
        unsigned long end_address;
        unsigned long address_increment;
        unsigned long mcopt1;
-       char str[] = "ECC generation...";
-       int i;
+       char str[] = "ECC generation -";
+       char slash[] = "\\|/-\\|/-";
+       int loop = 0;
+       int loopi = 0;
 
        current_address = start_address;
        mfsdram(SDRAM_MCOPT1, mcopt1);
@@ -2257,14 +2312,20 @@ static void program_ecc_addr(unsigned long start_address,
                        while (current_address < end_address) {
                                *((unsigned long *)current_address) = 0x00000000;
                                current_address += address_increment;
+
+                               if ((loop++ % (2 << 20)) == 0) {
+                                       putc('\b');
+                                       putc(slash[loopi++ % 8]);
+                               }
                        }
+
                } else {
                        /* ECC bit set method for cached memory */
                        dcbz_area(start_address, num_bytes);
                        dflush();
                }
-               for (i=0; i<strlen(str); i++)
-                       putc('\b');
+
+               blank_string(strlen(str));
 
                sync();
                eieio();
@@ -2279,15 +2340,6 @@ static void program_ecc_addr(unsigned long start_address,
                sync();
                eieio();
                wait_ddr_idle();
-
-#ifdef CONFIG_ECC_ERROR_RESET
-               /*
-                * One write to 0 is enough to trigger this ECC error
-                * (see description above)
-                */
-               out_be32(0, 0x12345678);
-               check_ecc();
-#endif
        }
 }
 #endif
@@ -2313,17 +2365,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
@@ -2347,7 +2392,7 @@ static void program_DQS_calibration(unsigned long *dimm_populated,
 #endif
 }
 
-static u32 short_mem_test(void)
+static int short_mem_test(void)
 {
        u32 *membase;
        u32 bxcr_num;
@@ -2371,42 +2416,41 @@ static u32 short_mem_test(void)
                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
                {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} };
+       int l;
 
        for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
                mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf);
 
                /* Banks enabled */
                if ((bxcf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
-
                        /* Bank is enabled */
-                       membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));
 
                        /*------------------------------------------------------------------
                         * Run the short memory test.
                         *-----------------------------------------------------------------*/
+                       membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));
+
                        for (i = 0; i < NUMMEMTESTS; i++) {
                                for (j = 0; j < NUMMEMWORDS; j++) {
                                        membase[j] = test[i][j];
                                        ppcDcbf((u32)&(membase[j]));
                                }
                                sync();
-                               for (j = 0; j < NUMMEMWORDS; j++) {
-                                       if (membase[j] != test[i][j]) {
+                               for (l=0; l<NUMLOOPS; l++) {
+                                       for (j = 0; j < NUMMEMWORDS; j++) {
+                                               if (membase[j] != test[i][j]) {
+                                                       ppcDcbf((u32)&(membase[j]));
+                                                       return 0;
+                                               }
                                                ppcDcbf((u32)&(membase[j]));
-                                               break;
                                        }
-                                       ppcDcbf((u32)&(membase[j]));
+                                       sync();
                                }
-                               sync();
-                               if (j < NUMMEMWORDS)
-                                       break;
                        }
-                       if (i < NUMMEMTESTS)
-                               break;
                }       /* if bank enabled */
        }               /* for bxcf_num */
 
-       return bxcr_num;
+       return 1;
 }
 
 #ifndef HARD_CODED_DQS
@@ -2415,14 +2459,9 @@ static u32 short_mem_test(void)
  *-----------------------------------------------------------------------------*/
 static void DQS_calibration_process(void)
 {
-       unsigned long ecc_temp;
        unsigned long rfdc_reg;
        unsigned long rffd;
-       unsigned long rqdc_reg;
-       unsigned long rqfd;
-       unsigned long bxcr_num;
        unsigned long val;
-       long rqfd_average;
        long rffd_average;
        long max_start;
        long min_end;
@@ -2440,6 +2479,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[] = "\\|/-\\|/-";
 
        /*------------------------------------------------------------------
         * Test to determine the best read clock delay tuning bits.
@@ -2464,11 +2511,26 @@ static void DQS_calibration_process(void)
         * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed),
         * from experimentation it is safe to say you will always have a failure.
         *-----------------------------------------------------------------*/
-       mfsdram(SDRAM_MCOPT1, ecc_temp);
-       ecc_temp &= SDRAM_MCOPT1_MCHK_MASK;
-       mfsdram(SDRAM_MCOPT1, val);
-       mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) |
-               SDRAM_MCOPT1_MCHK_NON);
+
+       /* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */
+       rqfd_start = 64; /* test-only: don't know if this is the _best_ start value */
+
+       puts(str);
+
+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;
@@ -2492,9 +2554,6 @@ static void DQS_calibration_process(void)
        fail_found = FALSE;
        pass_found = FALSE;
 
-       /* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */
-       /* rqdc_reg = mfsdram(SDRAM_RQDC) & ~(SDRAM_RQDC_RQFD_MASK); */
-
        /*
         * get the delay line calibration register value
         */
@@ -2510,13 +2569,10 @@ static void DQS_calibration_process(void)
                 *-----------------------------------------------------------------*/
                mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
 
-               /* do the small memory test */
-               bxcr_num = short_mem_test();
-
                /*------------------------------------------------------------------
                 * See if the rffd value passed.
                 *-----------------------------------------------------------------*/
-               if (bxcr_num == MAXBXCF) {
+               if (short_mem_test()) {
                        if (fail_found == TRUE) {
                                pass_found = TRUE;
                                if (current_pass_length == 0)
@@ -2559,6 +2615,7 @@ static void DQS_calibration_process(void)
        /* 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;
@@ -2578,13 +2635,10 @@ static void DQS_calibration_process(void)
                 *-----------------------------------------------------------------*/
                mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
 
-               /* do the small memory test */
-               bxcr_num = short_mem_test();
-
                /*------------------------------------------------------------------
                 * See if the rffd value passed.
                 *-----------------------------------------------------------------*/
-               if (bxcr_num == MAXBXCF) {
+               if (short_mem_test()) {
                        if (fail_found == TRUE) {
                                pass_found = TRUE;
                                if (current_pass_length == 0)
@@ -2612,40 +2666,63 @@ static void DQS_calibration_process(void)
                }
        }
 
+       rqfd_average = ((max_start + max_end) >> 1);
+
        /*------------------------------------------------------------------
         * Make sure we found the valid read passing window.  Halt if not
         *-----------------------------------------------------------------*/
        if (window_found == FALSE) {
-               printf("ERROR: Cannot determine a common read delay for the "
+               if (rqfd_start < SDRAM_RQDC_RQFD_MAX) {
+                       putc('\b');
+                       putc(slash[loopi++ % 8]);
+
+                       /* try again from with a different RQFD start value */
+                       rqfd_start++;
+                       goto calibration_loop;
+               }
+
+               printf("\nERROR: Cannot determine a common read delay for the "
                       "DIMM(s) installed.\n");
                debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__);
-               hang();
+               ppc440sp_sdram_register_dump();
+               spd_ddr_init_hang ();
        }
 
-       rqfd_average = ((max_start + max_end) >> 1);
-
        if (rqfd_average < 0)
                rqfd_average = 0;
 
        if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
                rqfd_average = SDRAM_RQDC_RQFD_MAX;
 
-       /*------------------------------------------------------------------
-        * Restore the ECC variable to what it originally was
-        *-----------------------------------------------------------------*/
-       mfsdram(SDRAM_MCOPT1, val);
-       mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | ecc_temp);
-
        mtsdram(SDRAM_RQDC,
                (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 */
 /*-----------------------------------------------------------------------------+
@@ -2781,7 +2858,7 @@ static void test(void)
        if (window_found == FALSE) {
                printf("ERROR: Cannot determine a common read delay for the "
                       "DIMM(s) installed.\n");
-               hang();
+               spd_ddr_init_hang ();
        }
 
        /*------------------------------------------------------------------
@@ -2950,5 +3027,9 @@ static void ppc440sp_sdram_register_dump(void)
        dcr_data = mfdcr(SDRAM_R3BAS);
        printf("        MQ3_B0BAS       = 0x%08X\n", dcr_data);
 }
+#else
+static void ppc440sp_sdram_register_dump(void)
+{
+}
 #endif
 #endif /* CONFIG_SPD_EEPROM */