[U-Boot] [PATCH 0/3] DMA ECC update

These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
cpu/mpc83xx/spd_sdram.c | 57 +++-------------------------------------- drivers/dma/fsl_dma.c | 9 ++---- include/asm-ppc/config.h | 7 ++--- include/configs/MPC8349EMDS.h | 1 + include/configs/MPC8360EMDS.h | 1 + include/configs/MPC8360ERDK.h | 1 + include/configs/MPC837XEMDS.h | 1 + include/configs/MPC837XERDB.h | 1 + include/configs/TQM834x.h | 1 + include/configs/kmeter1.h | 1 + include/configs/sbc8349.h | 1 + 11 files changed, 18 insertions(+), 63 deletions(-)

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.
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc83xx/spd_sdram.c | 57 +++------------------------------------------ drivers/dma/fsl_dma.c | 7 +---- include/asm-ppc/config.h | 7 ++--- 3 files changed, 9 insertions(+), 62 deletions(-)
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 0f61180..8a09a7d 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -825,67 +825,18 @@ 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 __inline__ 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; -} - -/* * 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 t_start, t_end; - register u64 *p; - register uint size; - unsigned int pattern[2]; - - icache_enable(); - t_start = get_tbms(); - pattern[0] = 0xdeadbeef; - pattern[1] = 0xdeadbeef; - -#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA) - dma_meminit(pattern[0], dram_size); -#else - debug("ddr init: CPU FP write method\n"); - size = dram_size; - for (p = 0; p < (u64*)(size); p++) { - ppcDWstore((u32*)p, pattern); - } - __asm__ __volatile__ ("sync"); -#endif
- t_end = get_tbms(); - icache_disable(); + debug("\nInitializing ECC!\n"); + + dma_meminit(0xdeadbeef, dram_size);
- debug("\nREADY!!\n"); - debug("ddr init duration: %ld ms\n", t_end - t_start); + debug("\nREADY!\n");
/* Clear All ECC Errors */ if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME) diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index df33e7a..4e9eafc 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -140,12 +140,9 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { }
/* - * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER - * while 83xx uses dma to initialize SDRAM when CONFIG_DDR_ECC_INIT_VIA_DMA + * Use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER */ -#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) && \ - !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) || \ - (defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA))) +#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) void dma_meminit(uint val, uint size) { uint *p = 0; diff --git a/include/asm-ppc/config.h b/include/asm-ppc/config.h index ca143c7..01668a9 100644 --- a/include/asm-ppc/config.h +++ b/include/asm-ppc/config.h @@ -29,10 +29,9 @@ #endif #endif
-#ifndef CONFIG_FSL_DMA -#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) && \ - !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) || \ - (defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA))) +#if (defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ + defined(CONFIG_MPC86xx)) && !defined CONFIG_FSL_DMA +#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) #define CONFIG_FSL_DMA #endif #endif

Dear Kim & Peter,
In message 1247081322-22392-2-git-send-email-ptyser@xes-inc.com Peter Tyser 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.
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc83xx/spd_sdram.c | 57 +++------------------------------------------ drivers/dma/fsl_dma.c | 7 +---- include/asm-ppc/config.h | 7 ++--- 3 files changed, 9 insertions(+), 62 deletions(-)
What's the status of these 3 patches:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/63152/focus=63154
?
Best regards,
Wolfgang Denk

On Sun, 2009-11-22 at 21:42 +0100, Wolfgang Denk wrote:
Dear Kim & Peter,
In message 1247081322-22392-2-git-send-email-ptyser@xes-inc.com Peter Tyser 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.
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc83xx/spd_sdram.c | 57 +++------------------------------------------ drivers/dma/fsl_dma.c | 7 +---- include/asm-ppc/config.h | 7 ++--- 3 files changed, 9 insertions(+), 62 deletions(-)
What's the status of these 3 patches:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/63152/focus=63154
1/3 can be ignored. After some more testing it was determined using DMA to initialize memory was slower than the original method.
2/3 is up to Kim, but its not really necessary. Right now the 83xx boards are hard-coded to initialize memory with the value of 0xdeadbeef. The change was intended to make the init value configurable based on CONFIG_MEM_INIT_VALUE like the MPC85xx/86xx arches. Let me know if you'd like me to resend Kim - the current patch would need to be rebased/updated.
3/3 is no longer needed. The change was rolled into a resubmission of a different patch I believe.
I won't take any action unless Kim is interested in 2/3.
Best, Peter

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc83xx/spd_sdram.c | 2 +- include/configs/MPC8349EMDS.h | 1 + include/configs/MPC8360EMDS.h | 1 + include/configs/MPC8360ERDK.h | 1 + include/configs/MPC837XEMDS.h | 1 + include/configs/MPC837XERDB.h | 1 + include/configs/TQM834x.h | 1 + include/configs/kmeter1.h | 1 + include/configs/sbc8349.h | 1 + 9 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 8a09a7d..ab6a2bb 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -834,7 +834,7 @@ void ddr_enable_ecc(unsigned int dram_size)
debug("\nInitializing ECC!\n");
- dma_meminit(0xdeadbeef, dram_size); + dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
debug("\nREADY!\n");
diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index ea5fbff..35e6e84 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -76,6 +76,7 @@ */ #define CONFIG_DDR_ECC /* support DDR ECC function */ #define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */ +#define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/
/* diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h index 3497ba0..27b5a58 100644 --- a/include/configs/MPC8360EMDS.h +++ b/include/configs/MPC8360EMDS.h @@ -109,6 +109,7 @@
#define CONFIG_DDR_ECC /* support DDR ECC function */ #define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ +#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
/* * DDRCDR - DDR Control Driver Register diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h index f584435..c2ff098 100644 --- a/include/configs/MPC8360ERDK.h +++ b/include/configs/MPC8360ERDK.h @@ -91,6 +91,7 @@
#define CONFIG_DDR_ECC /* support DDR ECC function */ #define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ +#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
/* * DDRCDR - DDR Control Driver Register diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index 4befcab..aa17220 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -129,6 +129,7 @@
#undef CONFIG_DDR_ECC /* support DDR ECC function */ #undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ +#undef CONFIG_MEM_INIT_VALUE
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ #define CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert ODT to internal IOs */ diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index 2b7d629..6a91395 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -156,6 +156,7 @@
#undef CONFIG_DDR_ECC /* support DDR ECC function */ #undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ +#undef CONFIG_MEM_INIT_VALUE
#undef CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert ODT to internal IOs */
diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index efade69..fbb2e48 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -68,6 +68,7 @@ #define CONFIG_SYS_DDR_SDRAM_BASE CONFIG_SYS_DDR_BASE #define DDR_CASLAT_25 /* CASLAT set to 2.5 */ #undef CONFIG_DDR_ECC /* only for ECC DDR module */ +#undef CONFIG_MEM_INIT_VALUE #undef CONFIG_SPD_EEPROM /* do not use SPD EEPROM for DDR setup */
#undef CONFIG_SYS_DRAM_TEST /* memory test, takes time */ diff --git a/include/configs/kmeter1.h b/include/configs/kmeter1.h index 19da133..d9c88f2 100644 --- a/include/configs/kmeter1.h +++ b/include/configs/kmeter1.h @@ -84,6 +84,7 @@ #define CFG_83XX_DDR_USES_CS0
#undef CONFIG_DDR_ECC +#undef CONFIG_MEM_INIT_VALUE
/* * DDRCDR - DDR Control Driver Register diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 84a251a..5a62c69 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -74,6 +74,7 @@ */ #undef CONFIG_DDR_ECC /* only for ECC DDR module */ #undef CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */ +#undef CONFIG_MEM_INIT_VALUE #define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ #define CONFIG_SYS_83XX_DDR_USES_CS0 /* WRS; Fsl board uses CS2/CS3 */

The initial SDRAM value was being hardcoded to CONFIG_MEM_INIT_VALUE instead of the value passed in 'val'.
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- drivers/dma/fsl_dma.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 4e9eafc..f07b25c 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -152,7 +152,7 @@ void dma_meminit(uint val, uint size) if (((uint)p & 0x1f) == 0) ppcDcbz((ulong)p);
- *p = (uint)CONFIG_MEM_INIT_VALUE; + *p = val;
if (((uint)p & 0x1c) == 0x1c) ppcDcbf((ulong)p);

On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
Other than the speed, I can confirm that it works as expected on my 8349emds-based board. I see no reason why there would be a problem on the mpc8349emds, though I cannot test on the eval board itself. I do not have an ECC SDRAM module.
Ira

On Wed, 2009-07-08 at 15:31 -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
Other than the speed, I can confirm that it works as expected on my 8349emds-based board. I see no reason why there would be a problem on the mpc8349emds, though I cannot test on the eval board itself. I do not have an ECC SDRAM module.
Thanks for testing Ira. The original code had the instruction cache enabled during SDRAM init, but it'd be pretty amazing if it gave that much performance boost. I would have guessed that the DMA init would have been faster even without the icache enabled.
If you have a second, could you try adding this patch on top of the previous ones? It'd be interesting to see where the bottleneck is with and without the icache...
Thanks, Peter
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f07b25c..24b31c7 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -148,6 +148,8 @@ void dma_meminit(uint val, uint size) uint *p = 0; uint i = 0;
+icache_enable() +printf("%d\n", __LINE__); for (*p = 0; p < (uint *)(8 * 1024); p++) { if (((uint)p & 0x1f) == 0) ppcDcbz((ulong)p); @@ -157,6 +159,7 @@ void dma_meminit(uint val, uint size) if (((uint)p & 0x1c) == 0x1c) ppcDcbf((ulong)p); } +printf("%d\n", __LINE__);
dmacpy(0x002000, 0, 0x002000); /* 8K */ dmacpy(0x004000, 0, 0x004000); /* 16K */ @@ -169,7 +172,10 @@ void dma_meminit(uint val, uint size) dmacpy(0x200000, 0, 0x200000); /* 2M */ dmacpy(0x400000, 0, 0x400000); /* 4M */
+printf("%d\n", __LINE__); for (i = 1; i < size / 0x800000; i++) dmacpy((0x800000 * i), 0, 0x800000); +printf("%d\n", __LINE__); +icache_disable(); } #endif

On Wed, Jul 08, 2009 at 05:59:33PM -0500, Peter Tyser wrote:
On Wed, 2009-07-08 at 15:31 -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
Other than the speed, I can confirm that it works as expected on my 8349emds-based board. I see no reason why there would be a problem on the mpc8349emds, though I cannot test on the eval board itself. I do not have an ECC SDRAM module.
Thanks for testing Ira. The original code had the instruction cache enabled during SDRAM init, but it'd be pretty amazing if it gave that much performance boost. I would have guessed that the DMA init would have been faster even without the icache enabled.
If you have a second, could you try adding this patch on top of the previous ones? It'd be interesting to see where the bottleneck is with and without the icache...
It didn't apply cleanly (I'm not sure why), but I applied it (fixed the missing semicolon).
It makes the DMA initialization normal speed again. The DMA in the for loop takes the longest (as expected).
So yes, strangely it makes a HUGE difference. The total time is <3 seconds now. It is now faster than the previous CPU method.
Ira
Thanks, Peter
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f07b25c..24b31c7 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -148,6 +148,8 @@ void dma_meminit(uint val, uint size) uint *p = 0; uint i = 0;
+icache_enable() +printf("%d\n", __LINE__); for (*p = 0; p < (uint *)(8 * 1024); p++) { if (((uint)p & 0x1f) == 0) ppcDcbz((ulong)p); @@ -157,6 +159,7 @@ void dma_meminit(uint val, uint size) if (((uint)p & 0x1c) == 0x1c) ppcDcbf((ulong)p); } +printf("%d\n", __LINE__);
dmacpy(0x002000, 0, 0x002000); /* 8K */ dmacpy(0x004000, 0, 0x004000); /* 16K */
@@ -169,7 +172,10 @@ void dma_meminit(uint val, uint size) dmacpy(0x200000, 0, 0x200000); /* 2M */ dmacpy(0x400000, 0, 0x400000); /* 4M */
+printf("%d\n", __LINE__); for (i = 1; i < size / 0x800000; i++) dmacpy((0x800000 * i), 0, 0x800000); +printf("%d\n", __LINE__); +icache_disable(); } #endif

On Wed, 2009-07-08 at 16:13 -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 05:59:33PM -0500, Peter Tyser wrote:
On Wed, 2009-07-08 at 15:31 -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
Other than the speed, I can confirm that it works as expected on my 8349emds-based board. I see no reason why there would be a problem on the mpc8349emds, though I cannot test on the eval board itself. I do not have an ECC SDRAM module.
Thanks for testing Ira. The original code had the instruction cache enabled during SDRAM init, but it'd be pretty amazing if it gave that much performance boost. I would have guessed that the DMA init would have been faster even without the icache enabled.
If you have a second, could you try adding this patch on top of the previous ones? It'd be interesting to see where the bottleneck is with and without the icache...
It didn't apply cleanly (I'm not sure why), but I applied it (fixed the missing semicolon).
It makes the DMA initialization normal speed again. The DMA in the for loop takes the longest (as expected).
So yes, strangely it makes a HUGE difference. The total time is <3 seconds now. It is now faster than the previous CPU method.
Thanks a lot Ira, I'll resubmit with the cache enable/disable for 83xx.
Peter

Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 05:59:33PM -0500, Peter Tyser wrote:
On Wed, 2009-07-08 at 15:31 -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
Other than the speed, I can confirm that it works as expected on my 8349emds-based board. I see no reason why there would be a problem on the mpc8349emds, though I cannot test on the eval board itself. I do not have an ECC SDRAM module.
Thanks for testing Ira. The original code had the instruction cache enabled during SDRAM init, but it'd be pretty amazing if it gave that much performance boost. I would have guessed that the DMA init would have been faster even without the icache enabled.
If you have a second, could you try adding this patch on top of the previous ones? It'd be interesting to see where the bottleneck is with and without the icache...
It didn't apply cleanly (I'm not sure why), but I applied it (fixed the missing semicolon).
It makes the DMA initialization normal speed again. The DMA in the for loop takes the longest (as expected).
So yes, strangely it makes a HUGE difference. The total time is <3 seconds now. It is now faster than the previous CPU method.
Not that strangely. In fsl_dma.c, the dma_check() routine does a busy-poll to wait for the DMA to complete:
80 static uint dma_check(void) { 81 volatile fsl_dma_t *dma = &dma_base->dma[0]; 82 uint status; 83 84 /* While the channel is busy, spin */ 85 do { 86 status = in_dma32(&dma->sr); 87 } while (status & FSL_DMA_SR_CB);
With icache enabled, this is going to run out of instruction cache and not compete with the DMA engine on the SDRAM bus. With icache disabled, the processor is going to be fetching instructions from SDRAM *one* *by* *one* (no bursting - quadruple whammy), competing with the DMA engine and thus destroying the DMA engine's performance.
Aside: SDRAM performance *sucks* when address/data pipelining and bursting is turned off or gets defeated. I ran the numbers a while back and came to the realization that dynamic RAM access times have *not* changed substantially in 20 years. The difference is that the memory subsystem is now a WHOLE lot better at hiding the access delay by pipelining additional requests to fill the time waiting for the first access to produce its data.
IOW, cache on the CPU and the SDRAM bursting/pipelining is what is faster, not the memory within the SDRAM itself.
[snip]
Ira
Thanks, Peter
Thanks, gvb

On Wed, Jul 08, 2009 at 03:31:29PM -0700, Ira W. Snyder wrote:
On Wed, Jul 08, 2009 at 02:28:39PM -0500, Peter Tyser wrote:
These changes bring the 83xx SDRAM ECC initialization in line with the 85xx/86xx boards and also fixes a minor bug in fsl_dma.c.
I don't have any 83xx boards to test on, so it would be appreciated if someone with 83xx hardware that uses ECC could give the patches a shot.
It'd be nice if SDRAM could be initialized via the DDR controller with CONFIG_ECC_INIT_VIA_DDRCONTROLLER on the 83xx platform too, but I'm not going to tackle it:)
The patches also resolve the compile error Stefan brought up with non-freescale boards with CONFIG_ECC.
Peter Tyser (3): 83xx: Default to using DMA to initialize SDRAM 83xx: Added CONFIG_MEM_INIT_VALUE for boards with ECC fsl_dma: Fix SDRAM initial value
Something in this patch makes the ECC DDR initialization VERY slow. It used to take <5 seconds, now it takes ~20 seconds for the memory to initialize.
I wonder why the CPU method would be so much faster?
As a further quick note, I just hacked in support for initializing the DDR via the DDR controller. Nothing good for submission, but it works fine for my board. (We're using fixed_sdram(), no SPD code).
The DDR controller takes about 3 seconds to initialize all 256MB of RAM on the board.
Ira
participants (4)
-
Ira W. Snyder
-
Jerry Van Baren
-
Peter Tyser
-
Wolfgang Denk