]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - board/lwmon5/sdram.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / lwmon5 / sdram.c
index affaeff1ae47f978aad928d9a05817750c554832..72968d78035240961f36eee324d79f64407adf96 100644 (file)
@@ -6,7 +6,7 @@
  * 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
@@ -34,7 +34,9 @@
 #include <asm/processor.h>
 #include <asm/mmu.h>
 #include <asm/io.h>
+#include <asm/cache.h>
 #include <ppc440.h>
+#include <watchdog.h>
 
 /*
  * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
  * memory.
  *
  * If at some time this restriction doesn't apply anymore, just define
- * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * CONFIG_SYS_ENABLE_SDRAM_CACHE in the board config file and this code should setup
  * everything correctly.
  */
-#ifdef CFG_ENABLE_SDRAM_CACHE
+#ifdef CONFIG_SYS_ENABLE_SDRAM_CACHE
 #define MY_TLB_WORD2_I_ENABLE  0                       /* enable caching on SDRAM */
 #else
 #define MY_TLB_WORD2_I_ENABLE  TLB_WORD2_I_ENABLE      /* disable caching on SDRAM */
@@ -58,7 +60,6 @@
 extern int denali_wait_for_dlllock(void);
 extern void denali_core_search_data_eye(void);
 extern void dcbz_area(u32 start_address, u32 num_bytes);
-extern void dflush(void);
 
 static u32 is_ecc_enabled(void)
 {
@@ -83,7 +84,7 @@ void board_add_ram_info(int use_default)
                puts(" (ECC not");
 
        get_sys_info(&board_cfg);
-       printf(" enabled, %d MHz", (board_cfg.freqPLB * 2) / 1000000);
+       printf(" enabled, %ld MHz", (board_cfg.freqPLB * 2) / 1000000);
 
        mfsdram(DDR0_03, val);
        val = DDR0_03_CASLAT_DECODE(val);
@@ -99,87 +100,44 @@ static void wait_ddr_idle(void)
         */
 }
 
-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;
+       u32 size;
+       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;
+       /*
+        * Because of 440EPx errata CHIP 11, we don't touch the last 256
+        * bytes of SDRAM.
+        */
+       bytes_remaining = num_bytes - CONFIG_SYS_MEM_TOP_HIDE;
 
-               puts(str);
+       /*
+        * 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) {
+               size = min((64 << 20), bytes_remaining);
 
-               while (current_address < end_address) {
-                       *((u32 *)current_address) = 0x00000000;
-                       current_address += address_increment;
+               /* Write zero's to SDRAM */
+               dcbz_area(current_addr, size);
 
-                       if ((loop++ % (2 << 20)) == 0) {
-                               putc('\b');
-                               putc(slash[loopi++ % 8]);
-                       }
-               }
+               /* Write modified dcache lines back to memory */
+               clean_dcache_range(current_addr, current_addr + size);
 
-               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
+               current_addr += 64 << 20;
+               bytes_remaining -= 64 << 20;
+               WATCHDOG_RESET();
        }
 
        sync();
-       eieio();
        wait_ddr_idle();
 
        /* Clear error status */
@@ -191,7 +149,6 @@ static void program_ecc(u32 start_address,
        mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF));
 
        sync();
-       eieio();
        wait_ddr_idle();
 }
 #endif
@@ -201,7 +158,7 @@ static void program_ecc(u32 start_address,
  * initdram -- 440EPx's DDR controller is a DENALI Core
  *
  ************************************************************************/
-long int initdram (int board_type)
+phys_size_t initdram (int board_type)
 {
 #if 0 /* test-only: will remove this define later, when ECC problems are solved! */
        /* CL=3 */
@@ -295,29 +252,29 @@ long int initdram (int board_type)
        /* -----------------------------------------------------------+
         * Perform data eye search if requested.
         * ----------------------------------------------------------*/
-       program_tlb(0, CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20,
+       program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20,
                    TLB_WORD2_I_ENABLE);
        denali_core_search_data_eye();
-       remove_tlb(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20);
+       remove_tlb(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20);
 #endif
 
        /*
         * Program tlb entries for this size (dynamic)
         */
-       program_tlb(0, CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20,
+       program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20,
                    MY_TLB_WORD2_I_ENABLE);
 
        /*
         * Setup 2nd TLB with same physical address but different virtual address
         * with cache enabled. This is done for fast ECC generation.
         */
-       program_tlb(0, CFG_DDR_CACHED_ADDR, CFG_MBYTES_SDRAM << 20, 0);
+       program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0);
 
 #ifdef CONFIG_DDR_ECC
        /*
         * If ECC is enabled, initialize the parity bits.
         */
-       program_ecc(CFG_DDR_CACHED_ADDR, CFG_MBYTES_SDRAM << 20, 0);
+       program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0);
 #endif
 
        /*
@@ -327,5 +284,5 @@ long int initdram (int board_type)
         */
        set_mcsr(get_mcsr());
 
-       return (CFG_MBYTES_SDRAM << 20);
+       return (CONFIG_SYS_MBYTES_SDRAM << 20);
 }