[U-Boot-Users] [PATCH] PPC405EX(r) ECC and SDRAM Initialization Clean-ups

Grant Erickson gerickson at nuovations.com
Mon Apr 28 10:53:07 CEST 2008


The primary goal of this patch is to unify some of the low-level SDRAM and
ECC initialization code for the PPC4xx processors that use a common DDR2
SDRAM controller.

In particular, in the case of the 405EX[r], it must initialize SDRAM before
a primordial stack is available since OCM doesn't exist and the data cache
doesn't work for such a purpose. As a consequence, the ECC (and SDRAM)
initialization code must be stack-free.

This patch creates such a stack-free ecc_init() routine that should,
nonetheless, still be compatible from a C runtime environment.

In addition, the patch cleans-up the Kilauea and Makalu SDRAM initialization
code by polling SDRAM0_MCSTAT[MIC] as recommended by AMCC AN2131 rather than
just waiting some arbitrary period of time. Also, the final controller
initialization is generalized by ORing in SDRAM_MCOPT2_DCEN_ENABLE rather
than just slamming 0x28000000 into the register. This is to make way for a
future patch that uses CFG_SDRAM0_* values for boards that use such
low-level initialization so they might share this SDRAM init code. Finally,
while neither Kilauea nor Makalu have ECC memory, code is added to init.S
for each to demonstrate how ecc_init() would be called if it were available
as a reference.

Signed-off-by: Grant Erickson <gerickson at nuovations.com>

---
 board/amcc/kilauea/init.S |   53
+++++++++++++++++++++++++++++++++++++++------
 board/amcc/makalu/init.S  |   53
+++++++++++++++++++++++++++++++++++++++------
 cpu/ppc4xx/Makefile       |    1 +
 cpu/ppc4xx/sdram.c        |   47 +++------------------------------------
 4 files changed, 97 insertions(+), 57 deletions(-)

diff --git a/board/amcc/kilauea/init.S b/board/amcc/kilauea/init.S
index 053fe19..7603fcf 100644
--- a/board/amcc/kilauea/init.S
+++ b/board/amcc/kilauea/init.S
@@ -36,6 +36,10 @@
     ori     r4,r4,value at l    ;    \
     mtdcr   memcfgd,r4    ;
 
+#if defined(CONFIG_SDRAM_ECC)
+    .extern    ecc_init
+#endif /* defined(CONFIG_SDRAM_ECC) */
+
     .globl  ext_bus_cntlr_init
 ext_bus_cntlr_init:
 #if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
@@ -126,12 +130,19 @@ ext_bus_cntlr_init:
     /* SDRAM0_MCOPT2 (0X21) Start initialization */
     mtsdram_as(SDRAM_MCOPT2, 0x20000000);
 
-    /* Step 5 */
-    lis     r3,0x1    /* 400000 =  wait 100ms */
-    mtctr   r3
+    /*
+     * Step 5: Poll SDRAM0_MCSTAT[MIC] for assertion to indicate the
+     * completion of initialization.
+     */
 
-pll_wait:
-    bdnz    pll_wait
+    li      r4,SDRAM_MCSTAT
+    lis    r2,SDRAM_MCSTAT_MIC_COMP at h
+    ori    r2,r2,SDRAM_MCSTAT_MIC_COMP at l
+0:    mtdcr   memcfga,r4
+    mfdcr   r3,memcfgd
+    clrrwi    r3,r3,31        // Clear all bits except MCSTAT[MIC].
+    cmpw    cr7,r3,r2        // Check if MCSTAT[MIC] = 1.
+    bne+    cr7,0b            // No, not ready yet, keep polling.
 
     /* Step 6 */
 
@@ -147,8 +158,36 @@ pll_wait:
     /* SDRAM_RFDC */
     mtsdram_as(SDRAM_RFDC, 0x00000209);
 
-    /* Enable memory controller */
-    mtsdram_as(SDRAM_MCOPT2, 0x28000000);
+    /*
+     * Enable Controller by SDRAM0_MCOPT2[DCEN] = 1:
+     *
+     *   mcopt2 = mfsdram(SDRAM_MCOPT2)
+     */
+
+    li    r4,SDRAM_MCOPT2
+    mtdcr    memcfga,r4
+    mfdcr    r3,memcfgd
+
+    /*
+     *   mtsdram(SDRAM_MCOPT2, mcopt2 | SDRAM_MCOPT2_DCEN_ENABLE)
+     */
+
+    mtdcr    memcfga,r4
+    oris    r3,r3,SDRAM_MCOPT2_DCEN_ENABLE at h
+    ori    r3,r3,SDRAM_MCOPT2_DCEN_ENABLE at l
+    mtdcr    memcfgd,r3
+
+#if defined(CONFIG_SDRAM_ECC)
+    mflr    r13
+    lis    r3,CFG_SDRAM_BASE at h
+    ori    r3,r3,CFG_SDRAM_BASE at l
+    lis    r4,(CFG_MBYTES_SDRAM << 20)@h
+    ori    r4,r4,(CFG_MBYTES_SDRAM << 20)@l
+    bl    ecc_init
+    mtlr    r13
+#endif /* defined(CONFIG_SDRAM_ECC) */
 #endif /* #ifndef CONFIG_NAND_U_BOOT */
+    
+    /* SDRAM is now ready for use. Return to the caller. */
 
     blr
diff --git a/board/amcc/makalu/init.S b/board/amcc/makalu/init.S
index 5e9a5e0..c40d8d1 100644
--- a/board/amcc/makalu/init.S
+++ b/board/amcc/makalu/init.S
@@ -36,6 +36,10 @@
     ori     r4,r4,value at l    ;    \
     mtdcr   memcfgd,r4    ;
 
+#if defined(CONFIG_SDRAM_ECC)
+    .extern    ecc_init
+#endif /* defined(CONFIG_SDRAM_ECC) */
+
     .globl  ext_bus_cntlr_init
 ext_bus_cntlr_init:
 
@@ -121,12 +125,19 @@ ext_bus_cntlr_init:
     /* SDRAM0_MCOPT2 (0X21) Start initialization */
     mtsdram_as(SDRAM_MCOPT2, 0x20000000);
 
-    /* Step 5 */
-    lis     r3,0x1    /* 400000 =  wait 100ms */
-    mtctr   r3
+    /*
+     * Step 5: Poll SDRAM0_MCSTAT[MIC] for assertion to indicate the
+     * completion of initialization.
+     */
 
-pll_wait:
-    bdnz    pll_wait
+    li      r4,SDRAM_MCSTAT
+    lis    r2,SDRAM_MCSTAT_MIC_COMP at h
+    ori    r2,r2,SDRAM_MCSTAT_MIC_COMP at l
+0:    mtdcr   memcfga,r4
+    mfdcr   r3,memcfgd
+    clrrwi    r3,r3,31        // Clear all bits except MCSTAT[MIC].
+    cmpw    cr7,r3,r2        // Check if MCSTAT[MIC] = 1.
+    bne+    cr7,0b            // No, not ready yet, keep polling.
 
     /* Step 6 */
 
@@ -142,7 +153,35 @@ pll_wait:
     /* SDRAM_RFDC */
     mtsdram_as(SDRAM_RFDC, 0x00000209);
 
-    /* Enable memory controller */
-    mtsdram_as(SDRAM_MCOPT2, 0x28000000);
+    /*
+     * Enable Controller by SDRAM0_MCOPT2[DCEN] = 1:
+     *
+     *   mcopt2 = mfsdram(SDRAM_MCOPT2)
+     */
+
+    li    r4,SDRAM_MCOPT2
+    mtdcr    memcfga,r4
+    mfdcr    r3,memcfgd
+
+    /*
+     *   mtsdram(SDRAM_MCOPT2, mcopt2 | SDRAM_MCOPT2_DCEN_ENABLE)
+     */
+
+    mtdcr    memcfga,r4
+    oris    r3,r3,SDRAM_MCOPT2_DCEN_ENABLE at h
+    ori    r3,r3,SDRAM_MCOPT2_DCEN_ENABLE at l
+    mtdcr    memcfgd,r3
+
+#if defined(CONFIG_SDRAM_ECC)
+    mflr    r13
+    lis    r3,CFG_SDRAM_BASE at h
+    ori    r3,r3,CFG_SDRAM_BASE at l
+    lis    r4,(CFG_MBYTES_SDRAM << 20)@h
+    ori    r4,r4,(CFG_MBYTES_SDRAM << 20)@l
+    bl    ecc_init
+    mtlr    r13
+#endif /* defined(CONFIG_SDRAM_ECC) */
+    
+    /* SDRAM is now ready for use. Return to the caller. */
 
     blr
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index 178c5c6..f1e7ad2 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -31,6 +31,7 @@ START    += start.o
 SOBJS    := cache.o
 SOBJS    += dcr.o
 SOBJS    += kgdb.o
+SOBJS    += ecc.o
 
 COBJS    := 40x_spd_sdram.o
 COBJS    += 44x_spd_ddr.o
diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
index 2724d91..66d9ae8 100644
--- a/cpu/ppc4xx/sdram.c
+++ b/cpu/ppc4xx/sdram.c
@@ -32,6 +32,10 @@
 #include <asm/processor.h>
 #include "sdram.h"
 
+#if defined(CONFIG_SDRAM_ECC)
+extern void ecc_init(volatile ulong * const start, ulong size);
+#endif
+
 #ifdef CONFIG_SDRAM_BANK0
 
 #ifndef CONFIG_440
@@ -332,49 +336,6 @@ static void sdram_tr1_set(int ram_address, int*
tr1_value)
     *tr1_value = (first_good + last_bad) / 2;
 }
 
-#ifdef CONFIG_SDRAM_ECC
-static void ecc_init(ulong start, ulong size)
-{
-    ulong    current_addr;        /* current byte address */
-    ulong    end_addr;        /* end of memory region */
-    ulong    addr_inc;        /* address skip between writes */
-    ulong    cfg0_reg;        /* for restoring ECC state */
-
-    /*
-     * TODO: Enable dcache before running this test (speedup)
-     */
-
-    mfsdram(mem_cfg0, cfg0_reg);
-    mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) |
SDRAM_CFG0_MEMCHK_GEN);
-
-    /*
-     * look at geometry of SDRAM (data width) to determine whether we
-     * can skip words when writing
-     */
-    if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32)
-        addr_inc = 4;
-    else
-        addr_inc = 8;
-
-    current_addr = start;
-    end_addr = start + size;
-
-    while (current_addr < end_addr) {
-        *((ulong *)current_addr) = 0x00000000;
-        current_addr += addr_inc;
-    }
-
-    /*
-     * TODO: Flush dcache and disable it again
-     */
-
-    /*
-     * Enable ecc checking and parity errors
-     */
-    mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) |
SDRAM_CFG0_MEMCHK_CHK);
-}
-#endif
-
 /*
  * Autodetect onboard DDR SDRAM on 440 platforms
  *







More information about the U-Boot mailing list