@ -34,6 +34,9 @@
# include <asm/io.h>
# include <asm/mmu.h>
# include <asm/fsl_law.h>
# include <post.h>
# include <asm/processor.h>
# include <asm/fsl_ddr_sdram.h>
DECLARE_GLOBAL_DATA_PTR ;
@ -282,3 +285,219 @@ void mpc85xx_reginfo(void)
print_laws ( ) ;
print_lbc_regs ( ) ;
}
# if CONFIG_POST & CONFIG_SYS_POST_MEMORY
/* Board-specific functions defined in each board's ddr.c */
void fsl_ddr_get_spd ( generic_spd_eeprom_t * ctrl_dimms_spd ,
unsigned int ctrl_num ) ;
void read_tlbcam_entry ( int idx , u32 * valid , u32 * tsize , unsigned long * epn ,
phys_addr_t * rpn ) ;
unsigned int
setup_ddr_tlbs_phys ( phys_addr_t p_addr , unsigned int memsize_in_meg ) ;
static void dump_spd_ddr_reg ( void )
{
int i , j , k , m ;
u8 * p_8 ;
u32 * p_32 ;
ccsr_ddr_t * ddr [ CONFIG_NUM_DDR_CONTROLLERS ] ;
generic_spd_eeprom_t
spd [ CONFIG_NUM_DDR_CONTROLLERS ] [ CONFIG_DIMM_SLOTS_PER_CTLR ] ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + )
fsl_ddr_get_spd ( spd [ i ] , i ) ;
puts ( " SPD data of all dimms (zero vaule is omitted)... \n " ) ;
puts ( " Byte (hex) " ) ;
k = 1 ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + ) {
for ( j = 0 ; j < CONFIG_DIMM_SLOTS_PER_CTLR ; j + + )
printf ( " Dimm%d " , k + + ) ;
}
puts ( " \n " ) ;
for ( k = 0 ; k < sizeof ( generic_spd_eeprom_t ) ; k + + ) {
m = 0 ;
printf ( " %3d (0x%02x) " , k , k ) ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + ) {
for ( j = 0 ; j < CONFIG_DIMM_SLOTS_PER_CTLR ; j + + ) {
p_8 = ( u8 * ) & spd [ i ] [ j ] ;
if ( p_8 [ k ] ) {
printf ( " 0x%02x " , p_8 [ k ] ) ;
m + + ;
} else
puts ( " " ) ;
}
}
if ( m )
puts ( " \n " ) ;
else
puts ( " \r " ) ;
}
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + ) {
switch ( i ) {
case 0 :
ddr [ i ] = ( void * ) CONFIG_SYS_MPC85xx_DDR_ADDR ;
break ;
# ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR
case 1 :
ddr [ i ] = ( void * ) CONFIG_SYS_MPC85xx_DDR2_ADDR ;
break ;
# endif
default :
printf ( " %s unexpected controller number = %u \n " ,
__func__ , i ) ;
return ;
}
}
printf ( " DDR registers dump for all controllers "
" (zero vaule is omitted)... \n " ) ;
puts ( " Offset (hex) " ) ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + )
printf ( " Base + 0x%04x " , ( u32 ) ddr [ i ] & 0xFFFF ) ;
puts ( " \n " ) ;
for ( k = 0 ; k < sizeof ( ccsr_ddr_t ) / 4 ; k + + ) {
m = 0 ;
printf ( " %6d (0x%04x) " , k * 4 , k * 4 ) ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + ) {
p_32 = ( u32 * ) ddr [ i ] ;
if ( p_32 [ k ] ) {
printf ( " 0x%08x " , p_32 [ k ] ) ;
m + + ;
} else
puts ( " " ) ;
}
if ( m )
puts ( " \n " ) ;
else
puts ( " \r " ) ;
}
puts ( " \n " ) ;
}
/* invalid the TLBs for DDR and setup new ones to cover p_addr */
static int reset_tlb ( phys_addr_t p_addr , u32 size , phys_addr_t * phys_offset )
{
u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE ;
unsigned long epn ;
u32 tsize , valid , ptr ;
phys_addr_t rpn = 0 ;
int ddr_esel ;
ptr = vstart ;
while ( ptr < ( vstart + size ) ) {
ddr_esel = find_tlb_idx ( ( void * ) ptr , 1 ) ;
if ( ddr_esel ! = - 1 ) {
read_tlbcam_entry ( ddr_esel , & valid , & tsize , & epn , & rpn ) ;
disable_tlb ( ddr_esel ) ;
}
ptr + = TSIZE_TO_BYTES ( tsize ) ;
}
/* Setup new tlb to cover the physical address */
setup_ddr_tlbs_phys ( p_addr , size > > 20 ) ;
ptr = vstart ;
ddr_esel = find_tlb_idx ( ( void * ) ptr , 1 ) ;
if ( ddr_esel ! = - 1 ) {
read_tlbcam_entry ( ddr_esel , & valid , & tsize , & epn , phys_offset ) ;
} else {
printf ( " TLB error in function %s \n " , __func__ ) ;
return - 1 ;
}
return 0 ;
}
/*
* slide the testing window up to test another area
* for 32 _bit system , the maximum testable memory is limited to
* CONFIG_MAX_MEM_MAPPED
*/
int arch_memory_test_advance ( u32 * vstart , u32 * size , phys_addr_t * phys_offset )
{
phys_addr_t test_cap , p_addr ;
phys_size_t p_size = min ( gd - > ram_size , CONFIG_MAX_MEM_MAPPED ) ;
# if !defined(CONFIG_PHYS_64BIT) || \
! defined ( CONFIG_SYS_INIT_RAM_ADDR_PHYS ) | | \
( CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull )
test_cap = p_size ;
# else
test_cap = gd - > ram_size ;
# endif
p_addr = ( * vstart ) + ( * size ) + ( * phys_offset ) ;
if ( p_addr < test_cap - 1 ) {
p_size = min ( test_cap - p_addr , CONFIG_MAX_MEM_MAPPED ) ;
if ( reset_tlb ( p_addr , p_size , phys_offset ) = = - 1 )
return - 1 ;
* vstart = CONFIG_SYS_DDR_SDRAM_BASE ;
* size = ( u32 ) p_size ;
printf ( " Testing 0x%08llx - 0x%08llx \n " ,
( u64 ) ( * vstart ) + ( * phys_offset ) ,
( u64 ) ( * vstart ) + ( * phys_offset ) + ( * size ) - 1 ) ;
} else
return 1 ;
return 0 ;
}
/* initialization for testing area */
int arch_memory_test_prepare ( u32 * vstart , u32 * size , phys_addr_t * phys_offset )
{
phys_size_t p_size = min ( gd - > ram_size , CONFIG_MAX_MEM_MAPPED ) ;
* vstart = CONFIG_SYS_DDR_SDRAM_BASE ;
* size = ( u32 ) p_size ; /* CONFIG_MAX_MEM_MAPPED < 4G */
* phys_offset = 0 ;
# if !defined(CONFIG_PHYS_64BIT) || \
! defined ( CONFIG_SYS_INIT_RAM_ADDR_PHYS ) | | \
( CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull )
if ( gd - > ram_size > CONFIG_MAX_MEM_MAPPED ) {
puts ( " Cannot test more than " ) ;
print_size ( CONFIG_MAX_MEM_MAPPED ,
" without proper 36BIT support. \n " ) ;
}
# endif
printf ( " Testing 0x%08llx - 0x%08llx \n " ,
( u64 ) ( * vstart ) + ( * phys_offset ) ,
( u64 ) ( * vstart ) + ( * phys_offset ) + ( * size ) - 1 ) ;
return 0 ;
}
/* invalid TLBs for DDR and remap as normal after testing */
int arch_memory_test_cleanup ( u32 * vstart , u32 * size , phys_addr_t * phys_offset )
{
unsigned long epn ;
u32 tsize , valid , ptr ;
phys_addr_t rpn = 0 ;
int ddr_esel ;
/* disable the TLBs for this testing */
ptr = * vstart ;
while ( ptr < ( * vstart ) + ( * size ) ) {
ddr_esel = find_tlb_idx ( ( void * ) ptr , 1 ) ;
if ( ddr_esel ! = - 1 ) {
read_tlbcam_entry ( ddr_esel , & valid , & tsize , & epn , & rpn ) ;
disable_tlb ( ddr_esel ) ;
}
ptr + = TSIZE_TO_BYTES ( tsize ) ;
}
puts ( " Remap DDR " ) ;
setup_ddr_tlbs ( gd - > ram_size > > 20 ) ;
puts ( " \n " ) ;
return 0 ;
}
void arch_memory_failure_handle ( void )
{
dump_spd_ddr_reg ( ) ;
}
# endif