* 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/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 */
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)
{
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);
*/
}
-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 */
mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF));
sync();
- eieio();
wait_ddr_idle();
}
#endif
* 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 */
/* -----------------------------------------------------------+
* 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
/*
*/
set_mcsr(get_mcsr());
- return (CFG_MBYTES_SDRAM << 20);
+ return (CONFIG_SYS_MBYTES_SDRAM << 20);
}