/* for faster clock, need more time for data setup */
trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
- twrt_mclk = 1;
+
+ /*
+ * for single quad-rank DIMM and two-slot DIMMs
+ * to avoid ODT overlap
+ */
+ switch (avoid_odt_overlap(dimm_params)) {
+ case 2:
+ twrt_mclk = 2;
+ twwt_mclk = 2;
+ trrt_mclk = 2;
+ break;
+ default:
+ twrt_mclk = 1;
+ twwt_mclk = 1;
+ trrt_mclk = 0;
+ break;
+ }
+
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
/*
break;
}
}
-
+ sr_ie = popts->self_refresh_interrupt_en;
num_pr = 1; /* Make this configurable */
/*
slow = get_ddr_freq(ctrl_num) < 1249000000;
#endif
- if (popts->registered_dimm_en) {
+ if (popts->registered_dimm_en)
rcw_en = 1;
- ap_en = popts->ap_en;
- } else {
+
+ /* DDR4 can have address parity for UDIMM and discrete */
+ if ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) &&
+ (!popts->registered_dimm_en)) {
ap_en = 0;
+ } else {
+ ap_en = popts->ap_en;
}
x4_en = popts->x4_en ? 1 : 0;
unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */
unsigned short esdmode5; /* Extended SDRAM mode 5 */
int rtt_park = 0;
-
+ bool four_cs = false;
+ const unsigned int mclk_ps = get_memory_clk_period_ps(0);
+
+#if CONFIG_CHIP_SELECTS_PER_CTRL == 4
+ if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[1].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[2].config & SDRAM_CS_CONFIG_EN) &&
+ (ddr->cs[3].config & SDRAM_CS_CONFIG_EN))
+ four_cs = true;
+#endif
if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) {
esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */
- rtt_park = 1;
+ rtt_park = four_cs ? 0 : 1;
} else {
esdmode5 = 0x00000400; /* Data mask enabled */
}
+ /* set command/address parity latency */
+ if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
+ if (mclk_ps >= 935) {
+ /* for DDR4-1600/1866/2133 */
+ esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
+ } else if (mclk_ps >= 833) {
+ /* for DDR4-2400 */
+ esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
+ } else {
+ printf("parity: mclk_ps = %d not supported\n", mclk_ps);
+ }
+ }
+
ddr->ddr_sdram_mode_9 = (0
| ((esdmode4 & 0xffff) << 16)
| ((esdmode5 & 0xffff) << 0)
);
- /* only mode_9 use 0x500, others use 0x400 */
+ /* Normally only the first enabled CS use 0x500, others use 0x400
+ * But when four chip-selects are all enabled, all mode registers
+ * need 0x500 to park.
+ */
debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
if (unq_mrs_en) { /* unique mode registers are supported */
if (!rtt_park &&
(ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) {
esdmode5 |= 0x00000500; /* RTT_PARK */
- rtt_park = 1;
+ rtt_park = four_cs ? 0 : 1;
} else {
esdmode5 = 0x00000400;
}
+
+ if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
+ if (mclk_ps >= 935) {
+ /* for DDR4-1600/1866/2133 */
+ esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
+ } else if (mclk_ps >= 833) {
+ /* for DDR4-2400 */
+ esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
+ } else {
+ printf("parity: mclk_ps = %d not supported\n",
+ mclk_ps);
+ }
+ }
+
switch (i) {
case 1:
ddr->ddr_sdram_mode_11 = (0
esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
+ if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
+ esdmode6 |= 1 << 6; /* Range 2 */
+
ddr->ddr_sdram_mode_10 = (0
| ((esdmode6 & 0xffff) << 16)
| ((esdmode7 & 0xffff) << 0)
unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
+ unsigned int trwt_mclk = 0; /* ext_rwt */
unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
wwt = 2; /* BL/2 + 2 clocks */
}
#endif
-
#ifdef CONFIG_SYS_FSL_DDR4
dll_lock = 2; /* tDLLK = 1024 clocks */
#elif defined(CONFIG_SYS_FSL_DDR3)
dll_lock = 1; /* tDLLK = 512 clocks from spec */
#endif
+
+ if (popts->trwt_override)
+ trwt_mclk = popts->trwt;
+
ddr->timing_cfg_4 = (0
| ((rwt & 0xf) << 28)
| ((wrt & 0xf) << 24)
| ((rrt & 0xf) << 20)
| ((wwt & 0xf) << 16)
+ | ((trwt_mclk & 0xc) << 12)
| (dll_lock & 0x3)
);
debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4);
const common_timing_params_t *common_dimm)
{
unsigned int txpr, tcksre, tcksrx;
- unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
+ unsigned int cke_rst, cksre, cksrx, par_lat = 0, cs_to_cmd;
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
- par_lat = 0;
+
+ 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);
+ }
+ }
+
cs_to_cmd = 0;
if (txpr <= 200)