diff options
Diffstat (limited to 'drivers/ddr/fsl/ctrl_regs.c')
-rw-r--r-- | drivers/ddr/fsl/ctrl_regs.c | 122 |
1 files changed, 87 insertions, 35 deletions
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index c0ee858a02e..8b8727116da 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -1,5 +1,6 @@ /* - * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2008-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0+ */ @@ -492,7 +493,7 @@ static void set_timing_cfg_3(const unsigned int ctrl_num, | ((ext_pretoact & 0x1) << 28) | ((ext_acttopre & 0x3) << 24) | ((ext_acttorw & 0x1) << 22) - | ((ext_refrec & 0x1F) << 16) + | ((ext_refrec & 0x3F) << 16) | ((ext_caslat & 0x3) << 12) | ((ext_add_lat & 0x1) << 10) | ((ext_wrrec & 0x1) << 8) @@ -723,16 +724,31 @@ static void set_timing_cfg_2(const unsigned int ctrl_num, } /* DDR SDRAM Register Control Word */ -static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) +static void set_ddr_sdram_rcw(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 ddr_freq = get_ddr_freq(ctrl_num) / 1000000; + unsigned int rc0a, rc0f; + if (common_dimm->all_dimms_registered && !common_dimm->all_dimms_unbuffered) { 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 { + rc0a = ddr_freq > 3200 ? 0x7 : + (ddr_freq > 2933 ? 0x6 : + (ddr_freq > 2666 ? 0x5 : + (ddr_freq > 2400 ? 0x4 : + (ddr_freq > 2133 ? 0x3 : + (ddr_freq > 1866 ? 0x2 : + (ddr_freq > 1600 ? 1 : 0)))))); + rc0f = ddr_freq > 3200 ? 0x3 : + (ddr_freq > 2400 ? 0x2 : + (ddr_freq > 2133 ? 0x1 : 0)); ddr->ddr_sdram_rcw_1 = common_dimm->rcw[0] << 28 | \ common_dimm->rcw[1] << 24 | \ @@ -745,15 +761,21 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, ddr->ddr_sdram_rcw_2 = common_dimm->rcw[8] << 28 | \ common_dimm->rcw[9] << 24 | \ - common_dimm->rcw[10] << 20 | \ + rc0a << 20 | \ common_dimm->rcw[11] << 16 | \ common_dimm->rcw[12] << 12 | \ common_dimm->rcw[13] << 8 | \ common_dimm->rcw[14] << 4 | \ - common_dimm->rcw[15]; + rc0f; + ddr->ddr_sdram_rcw_3 = + ((ddr_freq - 1260 + 19) / 20) << 8; } - 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); } } @@ -880,7 +902,7 @@ static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, } } sr_ie = popts->self_refresh_interrupt_en; - num_pr = 1; /* Make this configurable */ + num_pr = popts->package_3ds + 1; /* * 8572 manual says @@ -1159,8 +1181,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; @@ -1182,7 +1210,7 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, * need 0x500 to park. */ - debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); + 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 && @@ -1193,7 +1221,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; @@ -1257,7 +1287,7 @@ static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, | ((esdmode6 & 0xffff) << 16) | ((esdmode7 & 0xffff) << 0) ); - debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10); + debug("FSLDDR: ddr_sdram_mode_10 = 0x%08x\n", ddr->ddr_sdram_mode_10); if (unq_mrs_en) { /* unique mode registers are supported */ for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { switch (i) { @@ -1965,6 +1995,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 +2006,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 = (ddr->ddr_sdram_rcw_2 & 0xf) + 1; + debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps); } cs_to_cmd = 0; @@ -2024,11 +2050,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) @@ -2070,9 +2096,23 @@ static void set_timing_cfg_8(const unsigned int ctrl_num, debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); } -static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr) +static void set_timing_cfg_9(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm) { - ddr->timing_cfg_9 = 0; + unsigned int refrec_cid_mclk = 0; + unsigned int acttoact_cid_mclk = 0; + + if (popts->package_3ds) { + refrec_cid_mclk = + picos_to_mclk(ctrl_num, common_dimm->trfc_slr_ps); + acttoact_cid_mclk = 4U; /* tRRDS_slr */ + } + + ddr->timing_cfg_9 = (refrec_cid_mclk & 0x3ff) << 16 | + (acttoact_cid_mclk & 0xf) << 8; + debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); } @@ -2130,6 +2170,18 @@ 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; + + if (popts->package_3ds) { /* only 2,4,8 are supported */ + if ((popts->package_3ds + 1) & 0x1) { + printf("Error: Unsupported 3DS DIMM with %d die\n", + popts->package_3ds + 1); + } else { + ddr->ddr_sdram_cfg_3 |= ((popts->package_3ds + 1) >> 1) + << 4; + } + } debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); } @@ -2525,6 +2577,8 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); #endif + set_ddr_sdram_rcw(ctrl_num, ddr, popts, common_dimm); + set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); set_ddr_data_init(ddr); set_ddr_sdram_clk_cntl(ddr, popts); @@ -2535,9 +2589,9 @@ 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_timing_cfg_9(ctrl_num, ddr, popts, common_dimm); set_ddr_dq_mapping(ddr, dimm_params); #endif @@ -2546,8 +2600,6 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_sr_cntr(ddr, sr_it); - set_ddr_sdram_rcw(ddr, popts, common_dimm); - #ifdef CONFIG_SYS_FSL_DDR_EMU /* disble DDR training for emulator */ ddr->debug[2] = 0x00000400; |