* Alain Saurel,           AMCC/IBM, alain.saurel@fr.ibm.com
  * Robert Snyder,          AMCC/IBM, rob.snyder@fr.ibm.com
  *
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * This program is free software; you can redistribute it and/or
 #include <asm/mmu.h>
 #include <asm/io.h>
 #include <ppc440.h>
+#include <watchdog.h>
 
 /*
  * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
         */
 }
 
-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');
-}
-
 static void program_ecc(u32 start_address,
                        u32 num_bytes,
                        u32 tlb_word2_i_value)
 {
-       u32 current_address;
-       u32 end_address;
-       u32 address_increment;
        u32 val;
-       char str[] = "ECC generation -";
-       char slash[] = "\\|/-\\|/-";
-       int loop = 0;
-       int loopi = 0;
-
-       current_address = start_address;
+       u32 current_addr = start_address;
+       int bytes_remaining;
 
        sync();
-       eieio();
        wait_ddr_idle();
 
-       if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
-               /* ECC bit set method for non-cached memory */
-               address_increment = 4;
-               end_address = current_address + num_bytes;
-
-               puts(str);
-
-               while (current_address < end_address) {
-                       *((u32 *)current_address) = 0x00000000;
-                       current_address += address_increment;
-
-                       if ((loop++ % (2 << 20)) == 0) {
-                               putc('\b');
-                               putc(slash[loopi++ % 8]);
-                       }
-               }
+       /*
+        * Because of 440EPx errata CHIP 11, we don't touch the last 256
+        * bytes of SDRAM.
+        */
+       bytes_remaining = num_bytes - CFG_MEM_TOP_HIDE;
 
-               blank_string(strlen(str));
-       } else {
-               /* ECC bit set method for cached memory */
-#if 0 /* test-only: will remove this define later, when ECC problems are solved! */
-               /*
-                * Some boards (like lwmon5) need to preserve the memory
-                * content upon ECC generation (for the log-buffer).
-                * Therefore we don't fill the memory with a pattern or
-                * just zero it, but write the same values back that are
-                * already in the memory cells.
-                */
-               address_increment = CFG_CACHELINE_SIZE;
-               end_address = current_address + num_bytes;
-
-               current_address = start_address;
-               while (current_address < end_address) {
-                       /*
-                        * TODO: Th following sequence doesn't work correctly.
-                        * Just invalidating and flushing the cache doesn't
-                        * seem to trigger the re-write of the memory.
-                        */
-                       ppcDcbi(current_address);
-                       ppcDcbf(current_address);
-                       current_address += CFG_CACHELINE_SIZE;
-               }
-#else
-               dcbz_area(start_address, num_bytes);
-               dflush();
-#endif
+       /*
+        * We have to write the ECC bytes by zeroing and flushing in smaller
+        * steps, since the whole 256MByte takes too long for the external
+        * watchdog.
+        */
+       while (bytes_remaining > 0) {
+               dcbz_area(current_addr, min((64 << 20), bytes_remaining));
+               current_addr += 64 << 20;
+               bytes_remaining -= 64 << 20;
+               WATCHDOG_RESET();
        }
+       dflush();
 
        sync();
-       eieio();
        wait_ddr_idle();
 
        /* Clear error status */
        mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF));
 
        sync();
-       eieio();
        wait_ddr_idle();
 }
 #endif
 
 /*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * This program is free software; you can redistribute it and/or
 #define CFG_MBYTES_SDRAM       (256)           /* 256MB                        */
 #define CFG_DDR_CACHED_ADDR    0x40000000      /* setup 2nd TLB cached here    */
 #define CONFIG_DDR_DATA_EYE    1               /* use DDR2 optimization        */
-#if 0 /* test-only: disable ECC for now */
 #define CONFIG_DDR_ECC         1               /* enable ECC                   */
 #define CFG_POST_ECC_ON                CFG_POST_ECC
-#else
-#define CFG_POST_ECC_ON                0
-#endif
 
 /* POST support */
 #define CONFIG_POST            (CFG_POST_CACHE    | \