@ -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
@ -35,6 +35,7 @@
# 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
@ -99,87 +100,37 @@ 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 ;
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 440 EPx 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 256 MByte 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 */
@ -191,7 +142,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