[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