@ -212,10 +212,9 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
* Please refer to doc / README . fsl - ddr for the detail .
*
* If memory controller interleaving is enabled , then the data
* bus widths must be programmed identically for the 2 memory
* controllers .
* bus widths must be programmed identically for all memory controllers .
*
* XXX : Attempt to set both controllers to the same chip select
* XXX : Attempt to set all controllers to the same chip select
* interleaving mode . It will do a best effort to get the
* requested ranks interleaved together such that the result
* should be a subset of the requested configuration .
@ -223,15 +222,17 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
# if (CONFIG_NUM_DDR_CONTROLLERS > 1)
if ( hwconfig_sub ( " fsl_ddr " , " ctlr_intlv " ) ) {
if ( pdimm [ 0 ] . n_ranks = = 0 ) {
printf ( " There is no rank on CS0. Because only rank on "
" CS0 and ranks chip-select interleaved with CS0 "
printf ( " There is no rank on CS0 for controller %d . Because only "
" rank on CS0 and ranks chip-select interleaved with CS0"
" are controller interleaved, force non memory "
" controller interleaving \n " ) ;
" controller interleaving \n " , ctrl_num ) ;
popts - > memctl_interleaving = 0 ;
} else {
popts - > memctl_interleaving = 1 ;
/* test null first. if CONFIG_HWCONFIG is not defined
* hwconfig_arg_cmp returns non - zero */
/*
* test null first . if CONFIG_HWCONFIG is not defined
* hwconfig_arg_cmp returns non - zero
*/
if ( hwconfig_subarg_cmp ( " fsl_ddr " , " ctlr_intlv " , " null " ) ) {
popts - > memctl_interleaving = 0 ;
debug ( " memory controller interleaving disabled. \n " ) ;
@ -254,13 +255,12 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
}
}
# endif
if ( ( hwconfig_sub ( " fsl_ddr " , " bank_intlv " ) ) & &
( CONFIG_CHIP_SELECTS_PER_CTRL > 1 ) ) {
/* test null first. if CONFIG_HWCONFIG is not defined,
* hwconfig_arg_cmp returns non - zero */
if ( hwconfig_subarg_cmp ( " fsl_ddr " , " bank_intlv " , " null " ) )
printf ( " bank interleaving disabled. \n " ) ;
debug ( " bank interleaving disabled. \n " ) ;
else if ( hwconfig_subarg_cmp ( " fsl_ddr " , " bank_intlv " , " cs0_cs1 " ) )
popts - > ba_intlv_ctl = FSL_DDR_CS0_CS1 ;
else if ( hwconfig_subarg_cmp ( " fsl_ddr " , " bank_intlv " , " cs2_cs3 " ) )
@ -270,30 +270,70 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
else if ( hwconfig_subarg_cmp ( " fsl_ddr " , " bank_intlv " , " cs0_cs1_cs2_cs3 " ) )
popts - > ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3 ;
else
printf ( " hwconfig has unrecognized parameter for ba_intlv_ctl. \n " ) ;
printf ( " hwconfig has unrecognized parameter for bank_intlv. \n " ) ;
switch ( popts - > ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3 ) {
case FSL_DDR_CS0_CS1_CS2_CS3 :
# if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
if ( pdimm [ 0 ] . n_ranks ! = 4 ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(chip-select) for "
" CS0+CS1+CS2+CS3 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
# elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if ( ( pdimm [ 0 ] . n_ranks ! = 2 ) & & ( pdimm [ 1 ] . n_ranks ! = 2 ) ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(chip-select) for "
" CS0+CS1+CS2+CS3 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
if ( pdimm [ 0 ] . capacity ! = pdimm [ 1 ] . capacity ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not identical DIMM size for "
" CS0+CS1+CS2+CS3 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
# endif
break ;
case FSL_DDR_CS0_CS1 :
if ( pdimm [ 0 ] . n_ranks ! = 2 ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(chip-select) for "
" CS0+CS1, force non-interleaving! \n " ) ;
" CS0+CS1 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
break ;
case FSL_DDR_CS2_CS3 :
if ( pdimm [ 1 ] . n_ranks ! = 2 ) {
# if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
if ( pdimm [ 0 ] . n_ranks ! = 4 ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(chip-select) for CS2+CS3 "
" on controller %d, force non-interleaving! \n " , ctrl_num ) ;
}
# elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if ( pdimm [ 1 ] . n_ranks ! = 2 ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(CS) for CS2+CS3, "
" force non-interleaving! \n " ) ;
printf ( " Not enough bank(chip-select) for CS2+CS3 "
" on controller %d, force non-interleaving!\n " , ctrl_num ) ;
}
# endif
break ;
case FSL_DDR_CS0_CS1_AND_CS2_CS3 :
# if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
if ( pdimm [ 0 ] . n_ranks ! = 4 ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(CS) for CS0+CS1 and "
" CS2+CS3 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
# elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if ( ( pdimm [ 0 ] . n_ranks ! = 2 ) | | ( pdimm [ 1 ] . n_ranks ! = 2 ) ) {
popts - > ba_intlv_ctl = 0 ;
printf ( " Not enough bank(CS) for CS0+CS1 or "
" CS2+CS3, force non-interleaving! \n " ) ;
printf ( " Not enough bank(CS) for CS0+CS1 and "
" CS2+CS3 on controller %d, "
" force non-interleaving! \n " , ctrl_num ) ;
}
# endif
break ;
default :
popts - > ba_intlv_ctl = 0 ;
@ -305,3 +345,34 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
return 0 ;
}
void check_interleaving_options ( fsl_ddr_info_t * pinfo )
{
int i , j , check_n_ranks , intlv_fixed = 0 ;
unsigned long long check_rank_density ;
/*
* Check if all controllers are configured for memory
* controller interleaving . Identical dimms are recommended . At least
* the size should be checked .
*/
j = 0 ;
check_n_ranks = pinfo - > dimm_params [ 0 ] [ 0 ] . n_ranks ;
check_rank_density = pinfo - > dimm_params [ 0 ] [ 0 ] . rank_density ;
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + ) {
if ( ( pinfo - > memctl_opts [ i ] . memctl_interleaving ) & & \
( check_rank_density = = pinfo - > dimm_params [ i ] [ 0 ] . rank_density ) & & \
( check_n_ranks = = pinfo - > dimm_params [ i ] [ 0 ] . n_ranks ) ) {
j + + ;
}
}
if ( j ! = CONFIG_NUM_DDR_CONTROLLERS ) {
for ( i = 0 ; i < CONFIG_NUM_DDR_CONTROLLERS ; i + + )
if ( pinfo - > memctl_opts [ i ] . memctl_interleaving ) {
pinfo - > memctl_opts [ i ] . memctl_interleaving = 0 ;
intlv_fixed = 1 ;
}
if ( intlv_fixed )
printf ( " Not all DIMMs are identical in size. "
" Memory controller interleaving disabled. \n " ) ;
}
}