@ -48,8 +48,6 @@
# include <asm/mmu.h>
# include <asm/cache.h>
# include "ecc.h"
# if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
# define PPC4xx_IBM_DDR2_DUMP_REGISTER(mnemonic) \
@ -86,8 +84,240 @@
/* disable caching on SDRAM */
# define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
# endif /* CONFIG_4xx_DCACHE */
void dcbz_area ( u32 start_address , u32 num_bytes ) ;
# endif /* CONFIG_440 */
# define MAXRANKS 4
# define MAXBXCF 4
# define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
static unsigned long is_ecc_enabled ( void ) ;
/*-----------------------------------------------------------------------------+
* wait_ddr_idle
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void wait_ddr_idle ( void )
{
u32 val ;
do {
mfsdram ( SDRAM_MCSTAT , val ) ;
} while ( ( val & SDRAM_MCSTAT_IDLE_MASK ) = = SDRAM_MCSTAT_IDLE_NOT ) ;
}
/*-----------------------------------------------------------------------------+
* sdram_memsize
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static phys_size_t sdram_memsize ( void )
{
phys_size_t mem_size ;
unsigned long mcopt2 ;
unsigned long mcstat ;
unsigned long mb0cf ;
unsigned long sdsz ;
unsigned long i ;
mem_size = 0 ;
mfsdram ( SDRAM_MCOPT2 , mcopt2 ) ;
mfsdram ( SDRAM_MCSTAT , mcstat ) ;
/* DDR controller must be enabled and not in self-refresh. */
/* Otherwise memsize is zero. */
if ( ( ( mcopt2 & SDRAM_MCOPT2_DCEN_MASK ) = = SDRAM_MCOPT2_DCEN_ENABLE )
& & ( ( mcopt2 & SDRAM_MCOPT2_SREN_MASK ) = = SDRAM_MCOPT2_SREN_EXIT )
& & ( ( mcstat & ( SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK ) )
= = ( SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF ) ) ) {
for ( i = 0 ; i < MAXBXCF ; i + + ) {
mfsdram ( SDRAM_MB0CF + ( i < < 2 ) , mb0cf ) ;
/* Banks enabled */
if ( ( mb0cf & SDRAM_BXCF_M_BE_MASK ) = = SDRAM_BXCF_M_BE_ENABLE ) {
# if defined(CONFIG_440)
sdsz = mfdcr_any ( SDRAM_R0BAS + i ) & SDRAM_RXBAS_SDSZ_MASK ;
# else
sdsz = mb0cf & SDRAM_RXBAS_SDSZ_MASK ;
# endif
switch ( sdsz ) {
case SDRAM_RXBAS_SDSZ_8 :
mem_size + = 8 ;
break ;
case SDRAM_RXBAS_SDSZ_16 :
mem_size + = 16 ;
break ;
case SDRAM_RXBAS_SDSZ_32 :
mem_size + = 32 ;
break ;
case SDRAM_RXBAS_SDSZ_64 :
mem_size + = 64 ;
break ;
case SDRAM_RXBAS_SDSZ_128 :
mem_size + = 128 ;
break ;
case SDRAM_RXBAS_SDSZ_256 :
mem_size + = 256 ;
break ;
case SDRAM_RXBAS_SDSZ_512 :
mem_size + = 512 ;
break ;
case SDRAM_RXBAS_SDSZ_1024 :
mem_size + = 1024 ;
break ;
case SDRAM_RXBAS_SDSZ_2048 :
mem_size + = 2048 ;
break ;
case SDRAM_RXBAS_SDSZ_4096 :
mem_size + = 4096 ;
break ;
default :
printf ( " WARNING: Unsupported bank size (SDSZ=0x%lx)! \n "
, sdsz ) ;
mem_size = 0 ;
break ;
}
}
}
}
return mem_size < < 20 ;
}
/*-----------------------------------------------------------------------------+
* board_add_ram_info
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void board_add_ram_info ( int use_default )
{
PPC4xx_SYS_INFO board_cfg ;
u32 val ;
if ( is_ecc_enabled ( ) )
puts ( " (ECC " ) ;
else
puts ( " (ECC not " ) ;
get_sys_info ( & board_cfg ) ;
# if defined(CONFIG_440)
mfsdr ( SDR0_DDR0 , val ) ;
val = MULDIV64 ( ( board_cfg . freqPLB ) , SDR0_DDR0_DDRM_DECODE ( val ) , 1 ) ;
# else
mfsdr ( SDR0_SDSTP0 , val ) ;
val = MULDIV64 ( ( board_cfg . freqPLB ) , SDR0_SDSTP0_PLB2xDV0_DECODE ( val ) , 1 ) ;
# endif
printf ( " enabled, %d MHz " , ( val * 2 ) / 1000000 ) ;
mfsdram ( SDRAM_MMODE , val ) ;
val = ( val & SDRAM_MMODE_DCL_MASK ) > > 4 ;
printf ( " , CL%d) " , val ) ;
}
# ifdef CONFIG_DDR_ECC
/*-----------------------------------------------------------------------------+
* program_ecc_addr .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void program_ecc_addr ( unsigned long start_address ,
unsigned long num_bytes ,
unsigned long tlb_word2_i_value )
{
unsigned long current_address ;
unsigned long end_address ;
unsigned long address_increment ;
unsigned long mcopt1 ;
char str [ ] = " ECC generation - " ;
char slash [ ] = " \\ |/- \\ |/- " ;
int loop = 0 ;
int loopi = 0 ;
current_address = start_address ;
mfsdram ( SDRAM_MCOPT1 , mcopt1 ) ;
if ( ( mcopt1 & SDRAM_MCOPT1_MCHK_MASK ) ! = SDRAM_MCOPT1_MCHK_NON ) {
mtsdram ( SDRAM_MCOPT1 ,
( mcopt1 & ~ SDRAM_MCOPT1_MCHK_MASK ) | SDRAM_MCOPT1_MCHK_GEN ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
puts ( str ) ;
# ifdef CONFIG_440
if ( tlb_word2_i_value = = TLB_WORD2_I_ENABLE ) {
# endif
/* ECC bit set method for non-cached memory */
if ( ( mcopt1 & SDRAM_MCOPT1_DMWD_MASK ) = = SDRAM_MCOPT1_DMWD_32 )
address_increment = 4 ;
else
address_increment = 8 ;
end_address = current_address + num_bytes ;
while ( current_address < end_address ) {
* ( ( unsigned long * ) current_address ) = 0x00000000 ;
current_address + = address_increment ;
if ( ( loop + + % ( 2 < < 20 ) ) = = 0 ) {
putc ( ' \b ' ) ;
putc ( slash [ loopi + + % 8 ] ) ;
}
}
# ifdef CONFIG_440
} else {
/* ECC bit set method for cached memory */
dcbz_area ( start_address , num_bytes ) ;
/* Write modified dcache lines back to memory */
clean_dcache_range ( start_address , start_address + num_bytes ) ;
}
# endif /* CONFIG_440 */
blank_string ( strlen ( str ) ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
/* clear ECC error repoting registers */
mtsdram ( SDRAM_ECCCR , 0xffffffff ) ;
mtdcr ( 0x4c , 0xffffffff ) ;
mtsdram ( SDRAM_MCOPT1 ,
( mcopt1 & ~ SDRAM_MCOPT1_MCHK_MASK ) | SDRAM_MCOPT1_MCHK_CHK_REP ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
}
}
/*-----------------------------------------------------------------------------+
* do_program_ecc .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void do_program_ecc ( unsigned long tlb_word2_i_value )
{
unsigned long mcopt1 ;
unsigned long mcopt2 ;
unsigned long mcstat ;
phys_size_t memsize = sdram_memsize ( ) ;
if ( memsize > CONFIG_MAX_MEM_MAPPED ) {
printf ( " \n Warning: Can't enable ECC on systems with more than 2GB of SDRAM! \n " ) ;
return ;
}
mfsdram ( SDRAM_MCOPT1 , mcopt1 ) ;
mfsdram ( SDRAM_MCOPT2 , mcopt2 ) ;
if ( ( mcopt1 & SDRAM_MCOPT1_MCHK_MASK ) ! = SDRAM_MCOPT1_MCHK_NON ) {
/* DDR controller must be enabled and not in self-refresh. */
mfsdram ( SDRAM_MCSTAT , mcstat ) ;
if ( ( ( mcopt2 & SDRAM_MCOPT2_DCEN_MASK ) = = SDRAM_MCOPT2_DCEN_ENABLE )
& & ( ( mcopt2 & SDRAM_MCOPT2_SREN_MASK ) = = SDRAM_MCOPT2_SREN_EXIT )
& & ( ( mcstat & ( SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK ) )
= = ( SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF ) ) ) {
program_ecc_addr ( 0 , memsize , tlb_word2_i_value ) ;
}
}
}
# endif /* CONFIG_DDR_ECC */
# if defined(CONFIG_SPD_EEPROM)
/*-----------------------------------------------------------------------------+
@ -105,14 +335,10 @@
# define SDRAM_NONE 0
# define MAXDIMMS 2
# define MAXRANKS 4
# define MAXBXCF 4
# define MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */
# define ONE_BILLION 1000000000
# define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
# define CMD_NOP (7 << 19)
# define CMD_PRECHARGE (2 << 19)
# define CMD_REFRESH (1 << 19)
@ -257,15 +483,11 @@ static void program_initplr(unsigned long *dimm_populated,
unsigned long num_dimm_banks ,
ddr_cas_id_t selected_cas ,
int write_recovery ) ;
static unsigned long is_ecc_enabled ( void ) ;
# ifdef CONFIG_DDR_ECC
static void program_ecc ( unsigned long * dimm_populated ,
unsigned char * iic0_dimm_addr ,
unsigned long num_dimm_banks ,
unsigned long tlb_word2_i_value ) ;
static void program_ecc_addr ( unsigned long start_address ,
unsigned long num_bytes ,
unsigned long tlb_word2_i_value ) ;
# endif
# if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
static void program_DQS_calibration ( unsigned long * dimm_populated ,
@ -278,7 +500,6 @@ static void DQS_calibration_process(void);
# endif
# endif
int do_reset ( cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ) ;
void dcbz_area ( u32 start_address , u32 num_bytes ) ;
static unsigned char spd_read ( uchar chip , uint addr )
{
@ -292,79 +513,6 @@ static unsigned char spd_read(uchar chip, uint addr)
}
/*-----------------------------------------------------------------------------+
* sdram_memsize
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static phys_size_t sdram_memsize ( void )
{
phys_size_t mem_size ;
unsigned long mcopt2 ;
unsigned long mcstat ;
unsigned long mb0cf ;
unsigned long sdsz ;
unsigned long i ;
mem_size = 0 ;
mfsdram ( SDRAM_MCOPT2 , mcopt2 ) ;
mfsdram ( SDRAM_MCSTAT , mcstat ) ;
/* DDR controller must be enabled and not in self-refresh. */
/* Otherwise memsize is zero. */
if ( ( ( mcopt2 & SDRAM_MCOPT2_DCEN_MASK ) = = SDRAM_MCOPT2_DCEN_ENABLE )
& & ( ( mcopt2 & SDRAM_MCOPT2_SREN_MASK ) = = SDRAM_MCOPT2_SREN_EXIT )
& & ( ( mcstat & ( SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK ) )
= = ( SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF ) ) ) {
for ( i = 0 ; i < MAXBXCF ; i + + ) {
mfsdram ( SDRAM_MB0CF + ( i < < 2 ) , mb0cf ) ;
/* Banks enabled */
if ( ( mb0cf & SDRAM_BXCF_M_BE_MASK ) = = SDRAM_BXCF_M_BE_ENABLE ) {
sdsz = mfdcr_any ( SDRAM_R0BAS + i ) & SDRAM_RXBAS_SDSZ_MASK ;
switch ( sdsz ) {
case SDRAM_RXBAS_SDSZ_8 :
mem_size + = 8 ;
break ;
case SDRAM_RXBAS_SDSZ_16 :
mem_size + = 16 ;
break ;
case SDRAM_RXBAS_SDSZ_32 :
mem_size + = 32 ;
break ;
case SDRAM_RXBAS_SDSZ_64 :
mem_size + = 64 ;
break ;
case SDRAM_RXBAS_SDSZ_128 :
mem_size + = 128 ;
break ;
case SDRAM_RXBAS_SDSZ_256 :
mem_size + = 256 ;
break ;
case SDRAM_RXBAS_SDSZ_512 :
mem_size + = 512 ;
break ;
case SDRAM_RXBAS_SDSZ_1024 :
mem_size + = 1024 ;
break ;
case SDRAM_RXBAS_SDSZ_2048 :
mem_size + = 2048 ;
break ;
case SDRAM_RXBAS_SDSZ_4096 :
mem_size + = 4096 ;
break ;
default :
printf ( " WARNING: Unsupported bank size (SDSZ=0x%lx)! \n "
, sdsz ) ;
mem_size = 0 ;
break ;
}
}
}
}
return mem_size < < 20 ;
}
/*-----------------------------------------------------------------------------+
* initdram . Initializes the 440 SP Memory Queue and DDR SDRAM controller .
* Note : This routine runs from flash with a stack set up in the chip ' s
* sram space . It is important that the routine does not require . sbss , . bss or
@ -643,26 +791,6 @@ static void get_spd_info(unsigned long *dimm_populated,
}
}
void board_add_ram_info ( int use_default )
{
PPC4xx_SYS_INFO board_cfg ;
u32 val ;
if ( is_ecc_enabled ( ) )
puts ( " (ECC " ) ;
else
puts ( " (ECC not " ) ;
get_sys_info ( & board_cfg ) ;
mfsdr ( SDR0_DDR0 , val ) ;
val = MULDIV64 ( ( board_cfg . freqPLB ) , SDR0_DDR0_DDRM_DECODE ( val ) , 1 ) ;
printf ( " enabled, %d MHz " , ( val * 2 ) / 1000000 ) ;
mfsdram ( SDRAM_MMODE , val ) ;
val = ( val & SDRAM_MMODE_DCL_MASK ) > > 4 ;
printf ( " , CL%d) " , val ) ;
}
/*------------------------------------------------------------------
* For the memory DIMMs installed , this routine verifies that they
@ -2305,9 +2433,6 @@ static void program_ecc(unsigned long *dimm_populated,
unsigned long num_dimm_banks ,
unsigned long tlb_word2_i_value )
{
unsigned long mcopt1 ;
unsigned long mcopt2 ;
unsigned long mcstat ;
unsigned long dimm_num ;
unsigned long ecc ;
@ -2321,105 +2446,7 @@ static void program_ecc(unsigned long *dimm_populated,
if ( ecc = = 0 )
return ;
if ( sdram_memsize ( ) > CONFIG_MAX_MEM_MAPPED ) {
printf ( " \n Warning: Can't enable ECC on systems with more than 2GB of SDRAM! \n " ) ;
return ;
}
mfsdram ( SDRAM_MCOPT1 , mcopt1 ) ;
mfsdram ( SDRAM_MCOPT2 , mcopt2 ) ;
if ( ( mcopt1 & SDRAM_MCOPT1_MCHK_MASK ) ! = SDRAM_MCOPT1_MCHK_NON ) {
/* DDR controller must be enabled and not in self-refresh. */
mfsdram ( SDRAM_MCSTAT , mcstat ) ;
if ( ( ( mcopt2 & SDRAM_MCOPT2_DCEN_MASK ) = = SDRAM_MCOPT2_DCEN_ENABLE )
& & ( ( mcopt2 & SDRAM_MCOPT2_SREN_MASK ) = = SDRAM_MCOPT2_SREN_EXIT )
& & ( ( mcstat & ( SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK ) )
= = ( SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF ) ) ) {
program_ecc_addr ( 0 , sdram_memsize ( ) , tlb_word2_i_value ) ;
}
}
return ;
}
static void wait_ddr_idle ( void )
{
u32 val ;
do {
mfsdram ( SDRAM_MCSTAT , val ) ;
} while ( ( val & SDRAM_MCSTAT_IDLE_MASK ) = = SDRAM_MCSTAT_IDLE_NOT ) ;
}
/*-----------------------------------------------------------------------------+
* program_ecc_addr .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void program_ecc_addr ( unsigned long start_address ,
unsigned long num_bytes ,
unsigned long tlb_word2_i_value )
{
unsigned long current_address ;
unsigned long end_address ;
unsigned long address_increment ;
unsigned long mcopt1 ;
char str [ ] = " ECC generation - " ;
char slash [ ] = " \\ |/- \\ |/- " ;
int loop = 0 ;
int loopi = 0 ;
current_address = start_address ;
mfsdram ( SDRAM_MCOPT1 , mcopt1 ) ;
if ( ( mcopt1 & SDRAM_MCOPT1_MCHK_MASK ) ! = SDRAM_MCOPT1_MCHK_NON ) {
mtsdram ( SDRAM_MCOPT1 ,
( mcopt1 & ~ SDRAM_MCOPT1_MCHK_MASK ) | SDRAM_MCOPT1_MCHK_GEN ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
puts ( str ) ;
if ( tlb_word2_i_value = = TLB_WORD2_I_ENABLE ) {
/* ECC bit set method for non-cached memory */
if ( ( mcopt1 & SDRAM_MCOPT1_DMWD_MASK ) = = SDRAM_MCOPT1_DMWD_32 )
address_increment = 4 ;
else
address_increment = 8 ;
end_address = current_address + num_bytes ;
while ( current_address < end_address ) {
* ( ( unsigned long * ) current_address ) = 0x00000000 ;
current_address + = address_increment ;
if ( ( loop + + % ( 2 < < 20 ) ) = = 0 ) {
putc ( ' \b ' ) ;
putc ( slash [ loopi + + % 8 ] ) ;
}
}
} else {
/* ECC bit set method for cached memory */
dcbz_area ( start_address , num_bytes ) ;
/* Write modified dcache lines back to memory */
clean_dcache_range ( start_address , start_address + num_bytes ) ;
}
blank_string ( strlen ( str ) ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
/* clear ECC error repoting registers */
mtsdram ( SDRAM_ECCCR , 0xffffffff ) ;
mtdcr ( 0x4c , 0xffffffff ) ;
mtsdram ( SDRAM_MCOPT1 ,
( mcopt1 & ~ SDRAM_MCOPT1_MCHK_MASK ) | SDRAM_MCOPT1_MCHK_CHK_REP ) ;
sync ( ) ;
eieio ( ) ;
wait_ddr_idle ( ) ;
}
do_program_ecc ( tlb_word2_i_value ) ;
}
# endif
@ -2962,6 +2989,21 @@ static void test(void)
# else /* CONFIG_SPD_EEPROM */
/*-----------------------------------------------------------------------------+
* is_ecc_enabled
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static unsigned long is_ecc_enabled ( void )
{
unsigned long ecc ;
unsigned long val ;
ecc = 0 ;
mfsdram ( SDRAM_MCOPT1 , val ) ;
ecc = max ( ecc , SDRAM_MCOPT1_MCHK_CHK_DECODE ( val ) ) ;
return ecc ;
}
/*-----------------------------------------------------------------------------
* Function : initdram
* Description : Configures the PPC4xx IBM DDR1 / DDR2 SDRAM memory controller .
@ -3106,7 +3148,7 @@ phys_size_t initdram(int board_type)
# endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
# if defined(CONFIG_DDR_ECC)
ecc_init ( CONFIG_SYS_SDRAM_BASE , CONFIG_SYS_MBYTES_SDRAM < < 2 0) ;
do_program_ecc ( 0 ) ;
# endif /* defined(CONFIG_DDR_ECC) */
# if defined(CONFIG_440)