Commit 03e664d8 authored by York Sun's avatar York Sun

driver/ddr/fsl: Add support for multiple DDR clocks

Controller number is passed for function calls to support individual
DDR clock, depending on SoC implementation. It is backward compatible
with exising platforms. Multiple clocks have been verifyed on LS2085A
emulator.
Signed-off-by: default avatarYork Sun <yorksun@freescale.com>
parent b87e6f88
......@@ -222,7 +222,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 1;
(get_ddr_freq(ctrl_num) >> 20)) << 1;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
......
This diff is collapsed.
......@@ -228,10 +228,10 @@ compute_derated_DDR1_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
unsigned int
ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr1_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
......@@ -311,16 +311,16 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
pdimm->caslat_lowest_derated
= compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps());
pdimm->caslat_lowest_derated = compute_derated_DDR1_CAS_latency(
get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;
pdimm->trp_ps = spd->trp * 250;
pdimm->tras_ps = spd->tras * 1000;
pdimm->twr_ps = mclk_to_picos(3);
pdimm->twtr_ps = mclk_to_picos(1);
pdimm->twr_ps = mclk_to_picos(ctrl_num, 3);
pdimm->twtr_ps = mclk_to_picos(ctrl_num, 1);
pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc);
pdimm->trrd_ps = spd->trrd * 250;
......@@ -335,7 +335,7 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
pdimm->tdh_ps
= convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
pdimm->trtp_ps = mclk_to_picos(2); /* By the book. */
pdimm->trtp_ps = mclk_to_picos(ctrl_num, 2); /* By the book. */
pdimm->tdqsq_max_ps = spd->tdqsq * 10;
pdimm->tqhs_ps = spd->tqhs * 10;
......
......@@ -211,10 +211,10 @@ compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
unsigned int
ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr2_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
......@@ -310,8 +310,8 @@ ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
pdimm->caslat_lowest_derated
= compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps());
pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;
......
......@@ -83,10 +83,10 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
unsigned int
ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr3_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
unsigned int mtb_ps;
......
......@@ -119,10 +119,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
unsigned int
ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
int i;
......
......@@ -287,7 +287,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 2;
(get_ddr_freq(ctrl_num) >> 20)) << 2;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
......
......@@ -13,7 +13,8 @@
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
compute_cas_latency(const dimm_params_t *dimm_params,
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
......@@ -22,7 +23,7 @@ compute_cas_latency(const dimm_params_t *dimm_params,
unsigned int caslat_actual;
unsigned int retry = 16;
unsigned int tmp;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int taamax = 20000;
#else
......@@ -72,12 +73,13 @@ compute_cas_latency(const dimm_params_t *dimm_params,
}
#else /* for DDR1 and DDR2 */
static unsigned int
compute_cas_latency(const dimm_params_t *dimm_params,
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
int i;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
unsigned int lowest_good_caslat;
unsigned int not_ok;
unsigned int temp1, temp2;
......@@ -212,7 +214,8 @@ compute_cas_latency(const dimm_params_t *dimm_params,
* by dimm_params.
*/
unsigned int
compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
const unsigned int number_of_dimms)
{
......@@ -442,7 +445,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
printf("ERROR: Mix different RDIMM detected!\n");
/* calculate cas latency for all DDR types */
if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
if (compute_cas_latency(ctrl_num, dimm_params,
outpdimm, number_of_dimms))
return 1;
/* Determine if all DIMMs ECC capable. */
......@@ -518,11 +522,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
#if defined(CONFIG_SYS_FSL_DDR2)
if ((outpdimm->lowest_common_spd_caslat < 4) &&
(picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(trcd_ps) -
(picos_to_mclk(ctrl_num, trcd_ps) >
outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
outpdimm->lowest_common_spd_caslat;
if (mclk_to_picos(additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(trcd_ps);
if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency);
}
......@@ -534,7 +539,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
*
* AL <= tRCD(min)
*/
if (mclk_to_picos(additive_latency) > trcd_ps) {
if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
printf("Error: invalid additive latency exceeds tRCD(min).\n");
return 1;
}
......
......@@ -450,7 +450,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
&(pinfo->spd_installed_dimms[i][j]);
dimm_params_t *pdimm =
&(pinfo->dimm_params[i][j]);
retval = compute_dimm_parameters(spd, pdimm, i);
retval = compute_dimm_parameters(
i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (!i && !j && retval) {
printf("SPD error on controller %d! "
......@@ -507,10 +508,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
for (i = first_ctrl; i <= last_ctrl; i++) {
debug("Computing lowest common DIMM"
" parameters for memctl=%u\n", i);
compute_lowest_common_dimm_parameters(
pinfo->dimm_params[i],
&timing_params[i],
CONFIG_DIMM_SLOTS_PER_CTLR);
compute_lowest_common_dimm_parameters
(i,
pinfo->dimm_params[i],
&timing_params[i],
CONFIG_DIMM_SLOTS_PER_CTLR);
}
case STEP_GATHER_OPTS:
......@@ -562,12 +564,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
continue;
}
compute_fsl_memctl_config_regs(
&pinfo->memctl_opts[i],
&ddr_reg[i], &timing_params[i],
pinfo->dimm_params[i],
dbw_capacity_adjust[i],
size_only);
compute_fsl_memctl_config_regs
(i,
&pinfo->memctl_opts[i],
&ddr_reg[i], &timing_params[i],
pinfo->dimm_params[i],
dbw_capacity_adjust[i],
size_only);
}
default:
......
......@@ -426,7 +426,7 @@ step2:
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 1;
(get_ddr_freq(ctrl_num) >> 20)) << 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
timeout_save = timeout;
#endif
......@@ -538,12 +538,14 @@ step2:
case 1:
out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
break;
#if CONFIG_CHIP_SELECTS_PER_CTRL > 2
case 2:
out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
break;
case 3:
out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
break;
#endif
}
clrbits_be32(&ddr->sdram_cfg, 0x2);
}
......
......@@ -732,7 +732,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
#endif
/* Global Timing Parameters. */
debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
/* Pick a caslat override. */
popts->cas_latency_override = 0;
......@@ -785,7 +785,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
* FIXME: width, was considering looking at pdimm->primary_sdram_width
*/
#if defined(CONFIG_SYS_FSL_DDR1)
popts->tfaw_window_four_activates_ps = mclk_to_picos(1);
popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
#elif defined(CONFIG_SYS_FSL_DDR2)
/*
......@@ -1036,7 +1036,7 @@ done:
if (pdimm[0].n_ranks == 4)
popts->quad_rank_present = 1;
ddr_freq = get_ddr_freq(0) / 1000000;
ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
if (popts->registered_dimm_en) {
popts->rcw_override = 1;
popts->rcw_1 = 0x000a5a00;
......
......@@ -43,9 +43,9 @@ u32 fsl_ddr_get_version(void)
* propagation, compute a suitably rounded mclk_ps to compute
* a working memory controller configuration.
*/
unsigned int get_memory_clk_period_ps(void)
unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
{
unsigned int data_rate = get_ddr_freq(0);
unsigned int data_rate = get_ddr_freq(ctrl_num);
unsigned int result;
/* Round to nearest 10ps, being careful about 64-bit multiply/divide */
......@@ -59,10 +59,10 @@ unsigned int get_memory_clk_period_ps(void)
}
/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
unsigned int picos_to_mclk(unsigned int picos)
unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
{
unsigned long long clks, clks_rem;
unsigned long data_rate = get_ddr_freq(0);
unsigned long data_rate = get_ddr_freq(ctrl_num);
/* Short circuit for zero picos */
if (!picos)
......@@ -88,9 +88,9 @@ unsigned int picos_to_mclk(unsigned int picos)
return (unsigned int) clks;
}
unsigned int mclk_to_picos(unsigned int mclk)
unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
{
return get_memory_clk_period_ps() * mclk;
return get_memory_clk_period_ps(ctrl_num) * mclk;
}
#ifdef CONFIG_PPC
......
......@@ -44,11 +44,12 @@ u32 fsl_ddr_get_version(void);
* to this specific DDR technology.
*/
static __inline__ int
compute_dimm_parameters(const generic_spd_eeprom_t *spd,
compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
return ddr_compute_dimm_parameters(spd, pdimm, dimm_number);
return ddr_compute_dimm_parameters(ctrl_num, spd, pdimm, dimm_number);
}
#endif
......@@ -92,13 +93,15 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
unsigned int size_only);
const char *step_to_string(unsigned int step);
unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts,
unsigned int compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
const memctl_options_t *popts,
fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm,
const dimm_params_t *dimm_parameters,
unsigned int dbw_capacity_adjust,
unsigned int size_only);
unsigned int compute_lowest_common_dimm_parameters(
const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms);
......@@ -108,9 +111,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
unsigned int ctrl_num);
void check_interleaving_options(fsl_ddr_info_t *pinfo);
unsigned int mclk_to_picos(unsigned int mclk);
unsigned int get_memory_clk_period_ps(void);
unsigned int picos_to_mclk(unsigned int picos);
unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk);
unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num);
unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos);
void fsl_ddr_set_lawbar(
const common_timing_params_t *memctl_common_params,
unsigned int memctl_interleaved,
......
......@@ -112,7 +112,7 @@ typedef struct dimm_params_s {
#endif
} dimm_params_t;
extern unsigned int ddr_compute_dimm_parameters(
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment