@ -39,42 +39,108 @@ void fsl_ddr_get_spd(ddr2_spd_eeprom_t *ctrl_dimms_spd,
}
}
typedef struct {
u32 datarate_mhz_low ;
u32 datarate_mhz_high ;
u32 n_ranks ;
u32 clk_adjust ;
u32 cpo ;
u32 write_data_delay ;
u32 force_2T ;
} board_specific_parameters_t ;
/* ranges for parameters:
* wr_data_delay = 0 - 6
* clk adjust = 0 - 8
* cpo 2 - 0x1E ( 30 )
*/
/* XXX: these values need to be checked for all interleaving modes. */
/* XXX: No reliable dual-rank 800 MHz setting has been found. It may
* seem reliable , but errors will appear when memory intensive
* program is run . */
/* XXX: Single rank at 800 MHz is OK. */
const board_specific_parameters_t board_specific_parameters [ ] [ 20 ] = {
{
/* memory controller 0 */
/* lo| hi| num| clk| cpo|wrdata|2T */
/* mhz| mhz|ranks|adjst| | delay| */
{ 0 , 333 , 2 , 6 , 7 , 3 , 0 } ,
{ 334 , 400 , 2 , 6 , 9 , 3 , 0 } ,
{ 401 , 549 , 2 , 6 , 11 , 3 , 0 } ,
{ 550 , 680 , 2 , 1 , 10 , 5 , 0 } ,
{ 681 , 850 , 2 , 1 , 12 , 5 , 1 } ,
{ 0 , 333 , 1 , 6 , 7 , 3 , 0 } ,
{ 334 , 400 , 1 , 6 , 9 , 3 , 0 } ,
{ 401 , 549 , 1 , 6 , 11 , 3 , 0 } ,
{ 550 , 680 , 1 , 1 , 10 , 5 , 0 } ,
{ 681 , 850 , 1 , 1 , 12 , 5 , 0 }
} ,
{
/* memory controller 1 */
/* lo| hi| num| clk| cpo|wrdata|2T */
/* mhz| mhz|ranks|adjst| | delay| */
{ 0 , 333 , 2 , 6 , 7 , 3 , 0 } ,
{ 334 , 400 , 2 , 6 , 9 , 3 , 0 } ,
{ 401 , 549 , 2 , 6 , 11 , 3 , 0 } ,
{ 550 , 680 , 2 , 1 , 11 , 6 , 0 } ,
{ 681 , 850 , 2 , 1 , 13 , 6 , 1 } ,
{ 0 , 333 , 1 , 6 , 7 , 3 , 0 } ,
{ 334 , 400 , 1 , 6 , 9 , 3 , 0 } ,
{ 401 , 549 , 1 , 6 , 11 , 3 , 0 } ,
{ 550 , 680 , 1 , 1 , 11 , 6 , 0 } ,
{ 681 , 850 , 1 , 1 , 13 , 6 , 0 }
}
} ;
void fsl_ddr_board_options ( memctl_options_t * popts ,
dimm_params_t * pdimm ,
unsigned int ctrl_num )
{
/*
* Factors to consider for clock adjust :
* - number of chips on bus
* - position of slot
* - DDR1 vs . DDR2 ?
* - ? ? ?
*
* This needs to be determined on a board - by - board basis .
* 0110 3 / 4 cycle late
* 0111 7 / 8 cycle late
*/
popts - > clk_adjust = 7 ;
const board_specific_parameters_t * pbsp =
& ( board_specific_parameters [ ctrl_num ] [ 0 ] ) ;
u32 num_params = sizeof ( board_specific_parameters [ ctrl_num ] ) /
sizeof ( board_specific_parameters [ 0 ] [ 0 ] ) ;
u32 i ;
ulong ddr_freq ;
/*
* Factors to consider for CPO :
* - frequency
* - ddr1 vs . ddr2
/* set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in
* that controller , set odt_wr_cfg to 4 for CS0 , and 0 to CS1 . If
* there are two dimms in the controller , set odt_rd_cfg to 3 and
* odt_wr_cfg to 3 for the even CS , 0 for the odd CS .
*/
popts - > cpo_override = 10 ;
for ( i = 0 ; i < CONFIG_CHIP_SELECTS_PER_CTRL ; i + + ) {
if ( i & 1 ) { /* odd CS */
popts - > cs_local_opts [ i ] . odt_rd_cfg = 0 ;
popts - > cs_local_opts [ i ] . odt_wr_cfg = 0 ;
} else { /* even CS */
if ( CONFIG_DIMM_SLOTS_PER_CTLR = = 1 ) {
popts - > cs_local_opts [ i ] . odt_rd_cfg = 0 ;
popts - > cs_local_opts [ i ] . odt_wr_cfg = 4 ;
} else if ( CONFIG_DIMM_SLOTS_PER_CTLR = = 2 ) {
popts - > cs_local_opts [ i ] . odt_rd_cfg = 3 ;
popts - > cs_local_opts [ i ] . odt_wr_cfg = 3 ;
}
}
}
/*
* Factors to consider for write data delay :
* - number of DIMMs
*
* 1 = 1 / 4 clock delay
* 2 = 1 / 2 clock delay
* 3 = 3 / 4 clock delay
* 4 = 1 clock delay
* 5 = 5 / 4 clock delay
* 6 = 3 / 2 clock delay
/* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
* freqency and n_banks specified in board_specific_parameters table .
*/
popts - > write_data_delay = 5 ;
ddr_freq = get_ddr_freq ( 0 ) / 1000000 ;
for ( i = 0 ; i < num_params ; i + + ) {
if ( ddr_freq > = pbsp - > datarate_mhz_low & &
ddr_freq < = pbsp - > datarate_mhz_high & &
pdimm - > n_ranks = = pbsp - > n_ranks ) {
popts - > clk_adjust = pbsp - > clk_adjust ;
popts - > cpo_override = pbsp - > cpo ;
popts - > write_data_delay = pbsp - > write_data_delay ;
popts - > twoT_en = pbsp - > force_2T ;
}
pbsp + + ;
}
/*
* Factors to consider for half - strength driver enable :