@ -650,6 +650,17 @@ const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
0xAA55AA55 , 0xAA55AA55 }
} ;
/* bank_parms is used to sort the bank sizes by descending order */
struct bank_param {
unsigned long cr ;
unsigned long bank_size_bytes ;
} ;
typedef struct bank_param BANKPARMS ;
# ifdef CFG_SIMULATE_SPD_EEPROM
extern unsigned char cfg_simulate_spd_eeprom [ 128 ] ;
# endif
unsigned char spd_read ( uchar chip , uint addr ) ;
@ -806,9 +817,19 @@ long int spd_sdram(void) {
return total_size ;
}
unsigned char spd_read ( uchar chip , uint addr ) {
unsigned char spd_read ( uchar chip , uint addr )
{
unsigned char data [ 2 ] ;
# ifdef CFG_SIMULATE_SPD_EEPROM
if ( chip = = CFG_SIMULATE_SPD_EEPROM ) {
/*
* Onboard spd eeprom requested - > simulate values
*/
return cfg_simulate_spd_eeprom [ addr ] ;
}
# endif /* CFG_SIMULATE_SPD_EEPROM */
if ( i2c_probe ( chip ) = = 0 ) {
if ( i2c_read ( chip , addr , 1 , data , 1 ) = = 0 ) {
return data [ 0 ] ;
@ -849,12 +870,10 @@ void get_spd_info(unsigned long* dimm_populated,
}
}
# ifndef CONFIG_BAMBOO /* bamboo has onboard DDR _and_ DDR DIMM's */
if ( dimm_found = = FALSE ) {
printf ( " ERROR - No memory installed. Install a DDR-SDRAM DIMM. \n \n " ) ;
hang ( ) ;
}
# endif /* CONFIG_BAMBOO */
}
void check_mem_type ( unsigned long * dimm_populated ,
@ -1593,35 +1612,56 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
{
unsigned long dimm_num ;
unsigned long bank_base_addr ;
unsigned long bank_size_bytes ;
unsigned long cr ;
unsigned long i ;
unsigned long j ;
unsigned long temp ;
unsigned char num_row_addr ;
unsigned char num_col_addr ;
unsigned char num_banks ;
unsigned char bank_size_id ;
# ifndef CONFIG_BAMBOO
unsigned long bxcr_num ;
unsigned long ctrl_bank_num [ MAXBANKS ] ;
unsigned long bx_cr_num ;
unsigned long largest_size_index ;
unsigned long largest_size ;
unsigned long current_size_index ;
BANKPARMS bank_parms [ MAXBXCR ] ;
unsigned long sorted_bank_num [ MAXBXCR ] ; /* DDR Controller bank number table (sorted by size) */
unsigned long sorted_bank_size [ MAXBXCR ] ; /* DDR Controller bank size table (sorted by size)*/
/*
* Set the BxCR regs . First , wipe out the bank config registers .
*/
for ( bxcr_num = 0 ; bxcr_num < MAXBXCR ; bxcr_num + + ) {
mtdcr ( memcfga , mem_b0cr + ( bxcr_num < < 2 ) ) ;
for ( bx_ cr_num = 0 ; bx_ cr_num < MAXBXCR ; bx_ cr_num + + ) {
mtdcr ( memcfga , mem_b0cr + ( bx_ cr_num < < 2 ) ) ;
mtdcr ( memcfgd , 0x00000000 ) ;
bank_parms [ bx_cr_num ] . bank_size_bytes = 0 ;
}
# ifdef CONFIG_BAMBOO
/*
* This next section is hardware dependent and must be programmed
* to match the hardware . For bammboo , the following holds . . .
* 1. SDRAM0_B0CR : Bank 0 of dimm 0 ctrl_bank_num : 0
* 2. SDRAM0_B1CR : Bank 0 of dimm 1 ctrl_bank_num : 1
* 3. SDRAM0_B2CR : Bank 1 of dimm 1 ctrl_bank_num : 1
* 4. SDRAM0_B3CR : Bank 0 of dimm 2 ctrl_bank_num : 3
* ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM
*/
ctrl_bank_num [ 0 ] = 0 ;
ctrl_bank_num [ 1 ] = 1 ;
ctrl_bank_num [ 2 ] = 3 ;
# else
ctrl_bank_num [ 0 ] = 0 ;
ctrl_bank_num [ 1 ] = 1 ;
ctrl_bank_num [ 2 ] = 2 ;
ctrl_bank_num [ 3 ] = 3 ;
# endif
/*
* reset the bank_base address
*/
# ifndef CONFIG_BAMBOO
bank_base_addr = CFG_SDRAM_BASE ;
# else
bank_base_addr = CFG_SDRAM_ONBOARD_SIZE ;
# endif
for ( dimm_num = 0 ; dimm_num < num_dimm_banks ; dimm_num + + ) {
if ( dimm_populated [ dimm_num ] = = TRUE ) {
@ -1634,7 +1674,6 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
* Set the SDRAM0_BxCR regs
*/
cr = 0 ;
bank_size_bytes = 4 * 1024 * 1024 * bank_size_id ;
switch ( bank_size_id ) {
case 0x02 :
cr | = SDRAM_BXCR_SDSZ_8 ;
@ -1693,46 +1732,56 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
*/
cr | = SDRAM_BXCR_SDBE ;
/*------------------------------------------------------------------
| This next section is hardware dependent and must be programmed
| to match the hardware .
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if ( dimm_num = = 0 ) {
for ( i = 0 ; i < num_banks ; i + + ) {
# ifndef CONFIG_BAMBOO
mtdcr ( memcfga , mem_b0cr + ( i < < 2 ) ) ;
# else
mtdcr ( memcfga , mem_b1cr + ( i < < 2 ) ) ;
# endif
temp = mfdcr ( memcfgd ) & ~ ( SDRAM_BXCR_SDBA_MASK |
SDRAM_BXCR_SDSZ_MASK |
SDRAM_BXCR_SDAM_MASK |
SDRAM_BXCR_SDBE ) ;
cr | = temp ;
cr | = bank_base_addr & SDRAM_BXCR_SDBA_MASK ;
mtdcr ( memcfgd , cr ) ;
bank_base_addr + = bank_size_bytes ;
}
} else {
for ( i = 0 ; i < num_banks ; i + + ) {
# ifndef CONFIG_BAMBOO
mtdcr ( memcfga , mem_b2cr + ( i < < 2 ) ) ;
# else
mtdcr ( memcfga , mem_b3cr + ( i < < 2 ) ) ;
# endif
temp = mfdcr ( memcfgd ) & ~ ( SDRAM_BXCR_SDBA_MASK |
SDRAM_BXCR_SDSZ_MASK |
SDRAM_BXCR_SDAM_MASK |
SDRAM_BXCR_SDBE ) ;
cr | = temp ;
cr | = bank_base_addr & SDRAM_BXCR_SDBA_MASK ;
mtdcr ( memcfgd , cr ) ;
bank_base_addr + = bank_size_bytes ;
}
for ( i = 0 ; i < num_banks ; i + + ) {
bank_parms [ ctrl_bank_num [ dimm_num ] + i ] . bank_size_bytes =
( 4 * 1024 * 1024 ) * bank_size_id ;
bank_parms [ ctrl_bank_num [ dimm_num ] + i ] . cr = cr ;
}
}
}
/* Initialize sort tables */
for ( i = 0 ; i < MAXBXCR ; i + + ) {
sorted_bank_num [ i ] = i ;
sorted_bank_size [ i ] = bank_parms [ i ] . bank_size_bytes ;
}
for ( i = 0 ; i < MAXBXCR - 1 ; i + + ) {
largest_size = sorted_bank_size [ i ] ;
largest_size_index = 255 ;
/* Find the largest remaining value */
for ( j = i + 1 ; j < MAXBXCR ; j + + ) {
if ( sorted_bank_size [ j ] > largest_size ) {
/* Save largest remaining value and its index */
largest_size = sorted_bank_size [ j ] ;
largest_size_index = j ;
}
}
if ( largest_size_index ! = 255 ) {
/* Swap the current and largest values */
current_size_index = sorted_bank_num [ largest_size_index ] ;
sorted_bank_size [ largest_size_index ] = sorted_bank_size [ i ] ;
sorted_bank_size [ i ] = largest_size ;
sorted_bank_num [ largest_size_index ] = sorted_bank_num [ i ] ;
sorted_bank_num [ i ] = current_size_index ;
}
}
/* Set the SDRAM0_BxCR regs thanks to sort tables */
for ( bx_cr_num = 0 , bank_base_addr = 0 ; bx_cr_num < MAXBXCR ; bx_cr_num + + ) {
if ( bank_parms [ sorted_bank_num [ bx_cr_num ] ] . bank_size_bytes ) {
mtdcr ( memcfga , mem_b0cr + ( sorted_bank_num [ bx_cr_num ] < < 2 ) ) ;
temp = mfdcr ( memcfgd ) & ~ ( SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |
SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE ) ;
temp = temp | ( bank_base_addr & SDRAM_BXCR_SDBA_MASK ) |
bank_parms [ sorted_bank_num [ bx_cr_num ] ] . cr ;
mtdcr ( memcfgd , temp ) ;
bank_base_addr + = bank_parms [ sorted_bank_num [ bx_cr_num ] ] . bank_size_bytes ;
}
}
return ( bank_base_addr ) ;
}