mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 13:43:28 +00:00
drivers/ddr/fsl: Fix DDR4 RDIMM support
For DDR4, command/address delay in mode registers and parity latency in timing config register are only needed for UDIMMs, but not RDIMMs. Add additional register rcw_3 for DDR4 RDIMM. Fix mirrored bit for dual rank RDIMMs. Set sdram_cfg_3[DIS_MRS_PAR] for RDIMMs. Fix calculation of timing config registers. Use hexadecimal format for printing RCW (register control word) registers. Signed-off-by: York Sun <york.sun@nxp.com>
This commit is contained in:
parent
a9b1c2164a
commit
426230a65f
4 changed files with 41 additions and 22 deletions
|
@ -732,6 +732,7 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
|
|||
if (popts->rcw_override) {
|
||||
ddr->ddr_sdram_rcw_1 = popts->rcw_1;
|
||||
ddr->ddr_sdram_rcw_2 = popts->rcw_2;
|
||||
ddr->ddr_sdram_rcw_3 = popts->rcw_3;
|
||||
} else {
|
||||
ddr->ddr_sdram_rcw_1 =
|
||||
common_dimm->rcw[0] << 28 | \
|
||||
|
@ -752,8 +753,12 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
|
|||
common_dimm->rcw[14] << 4 | \
|
||||
common_dimm->rcw[15];
|
||||
}
|
||||
debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1);
|
||||
debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2);
|
||||
debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n",
|
||||
ddr->ddr_sdram_rcw_1);
|
||||
debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n",
|
||||
ddr->ddr_sdram_rcw_2);
|
||||
debug("FSLDDR: ddr_sdram_rcw_3 = 0x%08x\n",
|
||||
ddr->ddr_sdram_rcw_3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1159,8 +1164,14 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
|
|||
esdmode5 = 0x00000400; /* Data mask enabled */
|
||||
}
|
||||
|
||||
/* set command/address parity latency */
|
||||
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||
/*
|
||||
* For DDR3, set C/A latency if address parity is enabled.
|
||||
* For DDR4, set C/A latency for UDIMM only. For RDIMM the delay is
|
||||
* handled by register chip and RCW settings.
|
||||
*/
|
||||
if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) &&
|
||||
((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) ||
|
||||
!popts->registered_dimm_en)) {
|
||||
if (mclk_ps >= 935) {
|
||||
/* for DDR4-1600/1866/2133 */
|
||||
esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
|
||||
|
@ -1193,7 +1204,9 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
|
|||
esdmode5 = 0x00000400;
|
||||
}
|
||||
|
||||
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||
if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) &&
|
||||
((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) ||
|
||||
!popts->registered_dimm_en)) {
|
||||
if (mclk_ps >= 935) {
|
||||
/* for DDR4-1600/1866/2133 */
|
||||
esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
|
||||
|
@ -1965,6 +1978,7 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
|
|||
|
||||
static void set_timing_cfg_7(const unsigned int ctrl_num,
|
||||
fsl_ddr_cfg_regs_t *ddr,
|
||||
const memctl_options_t *popts,
|
||||
const common_timing_params_t *common_dimm)
|
||||
{
|
||||
unsigned int txpr, tcksre, tcksrx;
|
||||
|
@ -1975,16 +1989,11 @@ static void set_timing_cfg_7(const unsigned int ctrl_num,
|
|||
tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
|
||||
tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
|
||||
|
||||
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||
if (mclk_ps >= 935) {
|
||||
/* parity latency 4 clocks in case of 1600/1866/2133 */
|
||||
par_lat = 4;
|
||||
} else if (mclk_ps >= 833) {
|
||||
/* parity latency 5 clocks for DDR4-2400 */
|
||||
par_lat = 5;
|
||||
} else {
|
||||
printf("parity: mclk_ps = %d not supported\n", mclk_ps);
|
||||
}
|
||||
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN &&
|
||||
CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4) {
|
||||
/* for DDR4 only */
|
||||
par_lat = (popts->rcw_2 & 0xf) + 1;
|
||||
debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps);
|
||||
}
|
||||
|
||||
cs_to_cmd = 0;
|
||||
|
@ -2024,11 +2033,11 @@ static void set_timing_cfg_8(const unsigned int ctrl_num,
|
|||
const common_timing_params_t *common_dimm,
|
||||
unsigned int cas_latency)
|
||||
{
|
||||
unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
|
||||
int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
|
||||
unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
|
||||
unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
|
||||
unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
|
||||
((ddr->timing_cfg_2 & 0x00040000) >> 14);
|
||||
int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
|
||||
int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
|
||||
((ddr->timing_cfg_2 & 0x00040000) >> 14);
|
||||
|
||||
rwt_bg = cas_latency + 2 + 4 - wr_lat;
|
||||
if (rwt_bg < tccdl)
|
||||
|
@ -2130,6 +2139,8 @@ static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr,
|
|||
rd_pre = popts->quad_rank_present ? 1 : 0;
|
||||
|
||||
ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16;
|
||||
/* Disable MRS on parity error for RDIMMs */
|
||||
ddr->ddr_sdram_cfg_3 |= popts->registered_dimm_en ? 1 : 0;
|
||||
|
||||
debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3);
|
||||
}
|
||||
|
@ -2535,7 +2546,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
|
|||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
set_ddr_sdram_cfg_3(ddr, popts);
|
||||
set_timing_cfg_6(ddr);
|
||||
set_timing_cfg_7(ctrl_num, ddr, common_dimm);
|
||||
set_timing_cfg_7(ctrl_num, ddr, popts, common_dimm);
|
||||
set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
|
||||
set_timing_cfg_9(ddr);
|
||||
set_ddr_dq_mapping(ddr, dimm_params);
|
||||
|
|
|
@ -179,6 +179,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
|
|||
case DDR4_SPD_MODULETYPE_RDIMM:
|
||||
/* Registered/buffered DIMMs */
|
||||
pdimm->registered_dimm = 1;
|
||||
if (spd->mod_section.registered.reg_map & 0x1)
|
||||
pdimm->mirrored_dimm = 1;
|
||||
break;
|
||||
|
||||
case DDR4_SPD_MODULETYPE_UDIMM:
|
||||
|
|
|
@ -558,6 +558,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
|
|||
*/
|
||||
CTRL_OPTIONS(twot_en),
|
||||
CTRL_OPTIONS(threet_en),
|
||||
CTRL_OPTIONS(mirrored_dimm),
|
||||
CTRL_OPTIONS(ap_en),
|
||||
CTRL_OPTIONS(x4_en),
|
||||
CTRL_OPTIONS(bstopre),
|
||||
|
@ -568,6 +569,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
|
|||
CTRL_OPTIONS(rcw_override),
|
||||
CTRL_OPTIONS(rcw_1),
|
||||
CTRL_OPTIONS(rcw_2),
|
||||
CTRL_OPTIONS(rcw_3),
|
||||
CTRL_OPTIONS(ddr_cdr1),
|
||||
CTRL_OPTIONS(ddr_cdr2),
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
|
@ -660,6 +662,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
|
|||
CFG_REGS(ddr_sr_cntr),
|
||||
CFG_REGS(ddr_sdram_rcw_1),
|
||||
CFG_REGS(ddr_sdram_rcw_2),
|
||||
CFG_REGS(ddr_sdram_rcw_3),
|
||||
CFG_REGS(ddr_cdr1),
|
||||
CFG_REGS(ddr_cdr2),
|
||||
CFG_REGS(dq_map_0),
|
||||
|
@ -750,6 +753,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
|
|||
CFG_REGS(ddr_sr_cntr),
|
||||
CFG_REGS(ddr_sdram_rcw_1),
|
||||
CFG_REGS(ddr_sdram_rcw_2),
|
||||
CFG_REGS(ddr_sdram_rcw_3),
|
||||
CFG_REGS(ddr_cdr1),
|
||||
CFG_REGS(ddr_cdr2),
|
||||
CFG_REGS(dq_map_0),
|
||||
|
@ -857,8 +861,9 @@ static void print_memctl_options(const memctl_options_t *popts)
|
|||
CTRL_OPTIONS(wrlvl_start),
|
||||
CTRL_OPTIONS_HEX(cswl_override),
|
||||
CTRL_OPTIONS(rcw_override),
|
||||
CTRL_OPTIONS(rcw_1),
|
||||
CTRL_OPTIONS(rcw_2),
|
||||
CTRL_OPTIONS_HEX(rcw_1),
|
||||
CTRL_OPTIONS_HEX(rcw_2),
|
||||
CTRL_OPTIONS_HEX(rcw_3),
|
||||
CTRL_OPTIONS_HEX(ddr_cdr1),
|
||||
CTRL_OPTIONS_HEX(ddr_cdr2),
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
|
|
|
@ -408,6 +408,7 @@ typedef struct memctl_options_s {
|
|||
unsigned int rcw_override;
|
||||
unsigned int rcw_1;
|
||||
unsigned int rcw_2;
|
||||
unsigned int rcw_3;
|
||||
/* control register 1 */
|
||||
unsigned int ddr_cdr1;
|
||||
unsigned int ddr_cdr2;
|
||||
|
|
Loading…
Reference in a new issue