On Wed, Jul 08, 2009 at 05:58:50PM -0700, Ira W. Snyder wrote: > On Wed, Jul 08, 2009 at 07:32:26PM -0500, Peter Tyser wrote: > > On Thu, 2009-07-09 at 08:24 +0800, Liu Dave-R63238 wrote: > > > > When SDRAM ECC is enabled and CONFIG_ECC_INIT_VIA_DDRCONTROLLER is not > > > > defined use DMA to set SDRAM to a known state. Previously a > > > > sequence of > > > > 64-bit stores was used. > > > > > > IIRC, the DMA init SDRAM is slower than the 64bit stores. > > > It is why I added these code here. > > > > > > I suggest to keep the way. > > > > According to Ira, the DMA method was faster than the cpu method: > > "It makes the DMA initialization normal speed again. The DMA in the for > > loop takes the longest (as expected). > > > > So yes, strangely it (enabling the icache) makes a HUGE difference. The > > total time is <3 seconds now. It is now faster than the previous CPU > > method." > > > > > > Logically the DMA method should be faster, and Ira's results seem to > > reinforce this. I don't have an 83xx board to test on, so let me know > > if others have different results than Ira. > > > > I didn't check the SDRAM init time with code, only by a rough estimate. > (Counting "one one-thousand, two one-thousand..."). I can add back the > time measuring code, and be really sure which one is faster. > > Both the DMA and CPU methods are definitely on the same order of > magnitude. The time taken by the CFI flash driver is MUCH longer than > the SDRAM initialization. I wonder, should the icache be enabled for > that as well? > > I'll do some more testing when I get back to the office tomorrow. >
Ok, I've added back the get_tbms() code, and created a routine to initialize ECC with the CPU. I've inlined my patch below, just for reference. DMA 945ms CPU 581ms As an interesting comparison, I also benchmarked the method of using the DDR controller to initialize ECC. DDRC 129ms So there you have it. Dave Liu is correct, the CPU method is faster, though definitely on the same order of magnitude with the icache_enable()/icache_disable() patch. I may stick with the DDRC method on my board, the difference is just amazing. The flash init still takes up most of the boot process, however. Peter, feel free to fold the patch below into your own work. Ira >From 5cc24043352a90bf8ac89b5db0bc07a97e24d5d1 Mon Sep 17 00:00:00 2001 From: Ira W. Snyder <i...@ovro.caltech.edu> Date: Thu, 9 Jul 2009 08:45:09 -0700 Subject: [PATCH] mpc83xx: initialize ECC SDRAM with CPU Signed-off-by: Ira W. Snyder <i...@ovro.caltech.edu> --- cpu/mpc83xx/spd_sdram.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 insertions(+), 0 deletions(-) diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index ab6a2bb..7e093ae 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -1,3 +1,4 @@ +#define DEBUG 1 /* * (C) Copyright 2006-2007 Freescale Semiconductor, Inc. * @@ -825,18 +826,75 @@ long int spd_sdram() #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) /* + * Use timebase counter, get_timer() is not availabe + * at this point of initialization yet. + */ +static unsigned long get_tbms (void) +{ + unsigned long tbl; + unsigned long tbu1, tbu2; + unsigned long ms; + unsigned long long tmp; + + ulong tbclk = get_tbclk(); + + /* get the timebase ticks */ + do { + asm volatile ("mftbu %0":"=r" (tbu1):); + asm volatile ("mftb %0":"=r" (tbl):); + asm volatile ("mftbu %0":"=r" (tbu2):); + } while (tbu1 != tbu2); + + /* convert ticks to ms */ + tmp = (unsigned long long)(tbu1); + tmp = (tmp << 32); + tmp += (unsigned long long)(tbl); + ms = tmp/(tbclk/1000); + + return ms; +} + +void cpu_meminit(uint val, uint size) +{ + register u64 *p; + unsigned int pattern[2]; + + icache_enable(); + + pattern[0] = val; + pattern[1] = val; + + for (p = 0; p < (u64*)(size); p++) + ppcDWstore((u32*)p, pattern); + + asm volatile ("sync"); + + icache_disable(); +} + +/* * Initialize all of memory for ECC, then enable errors. */ void ddr_enable_ecc(unsigned int dram_size) { volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; volatile ddr83xx_t *ddr= &immap->ddr; + unsigned long s, e; debug("\nInitializing ECC!\n"); + s = get_tbms(); +#if 0 + debug("\nInitializing ECC (using DMA)!\n"); dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size); +#else + debug("\nInitializing ECC (using CPU)!\n"); + cpu_meminit(CONFIG_MEM_INIT_VALUE, dram_size); +#endif + e = get_tbms(); debug("\nREADY!\n"); + debug("ddr init duration: %ld ms\n", e - s); /* Clear All ECC Errors */ if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME) -- 1.5.4.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot