diff options
Diffstat (limited to 'drivers/ddr/fsl/ctrl_regs.c')
-rw-r--r-- | drivers/ddr/fsl/ctrl_regs.c | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 391925751a..8367c95cf8 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -313,7 +313,10 @@ static void set_timing_cfg_0(const unsigned int ctrl_num, #ifdef CONFIG_SYS_FSL_DDR4 /* tXP=max(4nCK, 6ns) */ int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */ - trwt_mclk = 2; + unsigned int data_rate = get_ddr_freq(ctrl_num); + + /* for faster clock, need more time for data setup */ + trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2; twrt_mclk = 1; act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); pre_pd_exit_mclk = act_pd_exit_mclk; @@ -338,7 +341,7 @@ static void set_timing_cfg_0(const unsigned int ctrl_num, */ txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); - ip_rev = fsl_ddr_get_version(); + ip_rev = fsl_ddr_get_version(ctrl_num); if (ip_rev >= 0x40700) { /* * MRS_CYC = max(tMRD, tMOD) @@ -544,7 +547,7 @@ static void set_timing_cfg_1(const unsigned int ctrl_num, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (fsl_ddr_get_version() <= 0x40400) + if (fsl_ddr_get_version(ctrl_num) <= 0x40400) caslat_ctrl = 2 * cas_latency - 1; else caslat_ctrl = (cas_latency - 1) << 1; @@ -1113,16 +1116,32 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, int i; unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ unsigned short esdmode5; /* Extended SDRAM mode 5 */ + int rtt_park = 0; - esdmode5 = 0x00000400; /* Data mask enabled */ + if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) { + esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */ + rtt_park = 1; + } else { + esdmode5 = 0x00000400; /* Data mask enabled */ + } ddr->ddr_sdram_mode_9 = (0 | ((esdmode4 & 0xffff) << 16) | ((esdmode5 & 0xffff) << 0) ); + + /* only mode_9 use 0x500, others use 0x400 */ + debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); if (unq_mrs_en) { /* unique mode registers are supported */ for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + if (!rtt_park && + (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) { + esdmode5 |= 0x00000500; /* RTT_PARK */ + rtt_park = 1; + } else { + esdmode5 = 0x00000400; + } switch (i) { case 1: ddr->ddr_sdram_mode_11 = (0 @@ -1970,31 +1989,41 @@ static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, const dimm_params_t *dimm_params) { unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; + int i; + + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + if (dimm_params[i].n_ranks) + break; + } + if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) { + puts("DDR error: no DIMM found!\n"); + return; + } - ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) | - ((dimm_params->dq_mapping[1] & 0x3F) << 20) | - ((dimm_params->dq_mapping[2] & 0x3F) << 14) | - ((dimm_params->dq_mapping[3] & 0x3F) << 8) | - ((dimm_params->dq_mapping[4] & 0x3F) << 2); + ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[4] & 0x3F) << 2); - ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) | - ((dimm_params->dq_mapping[6] & 0x3F) << 20) | - ((dimm_params->dq_mapping[7] & 0x3F) << 14) | - ((dimm_params->dq_mapping[10] & 0x3F) << 8) | - ((dimm_params->dq_mapping[11] & 0x3F) << 2); + ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[11] & 0x3F) << 2); - ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) | - ((dimm_params->dq_mapping[13] & 0x3F) << 20) | - ((dimm_params->dq_mapping[14] & 0x3F) << 14) | - ((dimm_params->dq_mapping[15] & 0x3F) << 8) | - ((dimm_params->dq_mapping[16] & 0x3F) << 2); + ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[16] & 0x3F) << 2); /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ - ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) | - ((dimm_params->dq_mapping[8] & 0x3F) << 20) | + ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) | (acc_ecc_en ? 0 : - (dimm_params->dq_mapping[9] & 0x3F) << 14) | - dimm_params->dq_mapping_ors; + (dimm_params[i].dq_mapping[9] & 0x3F) << 14) | + dimm_params[i].dq_mapping_ors; debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); @@ -2357,7 +2386,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_cdr1(ddr, popts); set_ddr_cdr2(ddr, popts); set_ddr_sdram_cfg(ddr, popts, common_dimm); - ip_rev = fsl_ddr_get_version(); + ip_rev = fsl_ddr_get_version(ctrl_num); if (ip_rev > 0x40400) unq_mrs_en = 1; |