All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support
@ 2018-01-29 17:44 York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 2/8] drivers/ddr/fsl: Fix workaround for A009803 York Sun
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

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>

---

Changes in v4:
Fix calculation of timing_cfg_7 using rcw_2
Fix calculation of timing_cfg_8

Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/ctrl_regs.c        | 51 +++++++++++++++++++++++---------------
 drivers/ddr/fsl/ddr4_dimm_params.c |  2 ++
 drivers/ddr/fsl/interactive.c      |  9 +++++--
 include/fsl_ddr_sdram.h            |  1 +
 4 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index c0ee858..33adfb1 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -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);
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index 42834ca..6e26ba8 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -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:
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index c99bd2f..660060d 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -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),
diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h
index 6a1f04b..de7ef9b 100644
--- a/include/fsl_ddr_sdram.h
+++ b/include/fsl_ddr_sdram.h
@@ -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;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 2/8] drivers/ddr/fsl: Fix workaround for A009803
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 3/8] drivers/ddr/fsl: Add 3DS RDIMM support York Sun
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

Wrong field was masked in this workaround due to wrong endianness. The
impacted SoCs have big-endian.

Signed-off-by: York Sun <york.sun@nxp.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/fsl_ddr_gen4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index b3a27ec..7df9178 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -210,7 +210,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 	if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
 		if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */
 			ddr_out32(&ddr->ddr_sdram_rcw_2,
-				  regs->ddr_sdram_rcw_2 & ~0x0f000000);
+				  regs->ddr_sdram_rcw_2 & ~0xf0);
 		}
 		ddr_out32(&ddr->err_disable, regs->err_disable |
 			  DDR_ERR_DISABLE_APED);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 3/8] drivers/ddr/fsl: Add 3DS RDIMM support
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 2/8] drivers/ddr/fsl: Fix workaround for A009803 York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 4/8] drivers/ddr/fsl: Add calculation of register control words York Sun
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

On top of RDIMM support, add new register calculation to support
3DS RDIMMs. Only symmetrical 3DS is supported at this time.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
New patch to add 3DS support.

Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/ctrl_regs.c             | 43 ++++++++++++++++++++++++++-------
 drivers/ddr/fsl/ddr4_dimm_params.c      | 26 ++++++++++++++++++--
 drivers/ddr/fsl/interactive.c           | 13 +++++++++-
 drivers/ddr/fsl/lc_common_dimm_params.c |  8 +++++-
 drivers/ddr/fsl/options.c               |  5 +++-
 include/common_timing_params.h          |  1 +
 include/fsl_ddr_dimm_params.h           |  6 ++++-
 include/fsl_ddr_sdram.h                 |  4 ++-
 8 files changed, 90 insertions(+), 16 deletions(-)

diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 33adfb1..bcab904 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)
@@ -885,7 +886,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
@@ -1193,7 +1194,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 &&
@@ -1270,7 +1271,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) {
@@ -1992,7 +1993,7 @@ static void set_timing_cfg_7(const unsigned int ctrl_num,
 	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;
+		par_lat = (ddr->ddr_sdram_rcw_2 & 0xf) + 1;
 		debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps);
 	}
 
@@ -2079,9 +2080,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);
 }
 
@@ -2142,6 +2157,16 @@ static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr,
 	/* 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);
 }
 #endif	/* CONFIG_SYS_FSL_DDR4 */
@@ -2548,7 +2573,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
 	set_timing_cfg_6(ddr);
 	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
 
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index 6e26ba8..0d3d137 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -1,5 +1,8 @@
 /*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP Semiconductor
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
  *
  * calculate the organization and timing parameter
  * from ddr3 spd, please refer to the spec
@@ -98,6 +101,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
 	if ((spd->organization & 0x7) < 4)
 		nbit_sdram_width = (spd->organization & 0x7) + 2;
 	package_3ds = (spd->package_type & 0x3) == 0x2;
+	if ((spd->package_type & 0x80) && !package_3ds) { /* other than 3DS */
+		printf("Warning: not supported SDRAM package type\n");
+		return 0;
+	}
 	if (package_3ds)
 		die_count = (spd->package_type >> 4) & 0x7;
 
@@ -105,7 +112,7 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
 			 nbit_primary_bus_width - nbit_sdram_width +
 			 die_count);
 
-	debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
+	debug("DDR: DDR rank density = 0x%16llx\n", bsize);
 
 	return bsize;
 }
@@ -132,6 +139,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	};
 	int spd_error = 0;
 	u8 *ptr;
+	u8 val;
 
 	if (spd->mem_type) {
 		if (spd->mem_type != SPD_MEMTYPE_DDR4) {
@@ -163,6 +171,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1;
 	pdimm->rank_density = compute_ranksize(spd);
 	pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
+	pdimm->die_density = spd->density_banks & 0xf;
 	pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7));
 	if ((spd->bus_width >> 3) & 0x3)
 		pdimm->ec_sdram_width = 8;
@@ -171,6 +180,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	pdimm->data_width = pdimm->primary_sdram_width
 			  + pdimm->ec_sdram_width;
 	pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
+	pdimm->package_3ds = (spd->package_type & 0x3) == 0x2 ?
+			     (spd->package_type >> 4) & 0x7 : 0;
 
 	/* These are the types defined by the JEDEC SPD spec */
 	pdimm->mirrored_dimm = 0;
@@ -310,6 +321,17 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	/* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */
 	pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min);
 
+	if (pdimm->package_3ds) {
+		if (pdimm->die_density <= 0x4) {
+			pdimm->trfc_slr_ps = 260000;
+		} else if (pdimm->die_density <= 0x5) {
+			pdimm->trfc_slr_ps = 350000;
+		} else {
+			printf("WARN: Unsupported logical rank density 0x%x\n",
+			       pdimm->die_density);
+		}
+	}
+
 	/*
 	 * Average periodic refresh interval
 	 * tREFI = 7.8 us at normal temperature range
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 660060d..78ca03b 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010-2014 Freescale Semiconductor, Inc.
+ * Copyright 2010-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP Semiconductor
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -168,6 +169,7 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		COMMON_TIMING(trrds_ps),
 		COMMON_TIMING(trrdl_ps),
 		COMMON_TIMING(tccdl_ps),
+		COMMON_TIMING(trfc_slr_ps),
 #else
 		COMMON_TIMING(twtr_ps),
 		COMMON_TIMING(trfc_ps),
@@ -223,6 +225,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		DIMM_PARM(data_width),
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
+		DIMM_PARM(package_3ds),
 		DIMM_PARM(registered_dimm),
 		DIMM_PARM(mirrored_dimm),
 		DIMM_PARM(device_width),
@@ -233,6 +236,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 #ifdef CONFIG_SYS_FSL_DDR4
 		DIMM_PARM(bank_addr_bits),
 		DIMM_PARM(bank_group_bits),
+		DIMM_PARM_HEX(die_density),
 #else
 		DIMM_PARM(n_banks_per_sdram_device),
 #endif
@@ -260,6 +264,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		DIMM_PARM(trrds_ps),
 		DIMM_PARM(trrdl_ps),
 		DIMM_PARM(tccdl_ps),
+		DIMM_PARM(trfc_slr_ps),
 #else
 		DIMM_PARM(twr_ps),
 		DIMM_PARM(twtr_ps),
@@ -320,6 +325,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(data_width),
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
+		DIMM_PARM(package_3ds),
 		DIMM_PARM(registered_dimm),
 		DIMM_PARM(mirrored_dimm),
 		DIMM_PARM(device_width),
@@ -330,6 +336,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 #ifdef CONFIG_SYS_FSL_DDR4
 		DIMM_PARM(bank_addr_bits),
 		DIMM_PARM(bank_group_bits),
+		DIMM_PARM_HEX(die_density),
 #else
 		DIMM_PARM(n_banks_per_sdram_device),
 #endif
@@ -359,6 +366,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(trrds_ps),
 		DIMM_PARM(trrdl_ps),
 		DIMM_PARM(tccdl_ps),
+		DIMM_PARM(trfc_slr_ps),
 #else
 		DIMM_PARM(twr_ps),
 		DIMM_PARM(twtr_ps),
@@ -437,6 +445,7 @@ static void print_lowest_common_dimm_parameters(
 		COMMON_TIMING(trrds_ps),
 		COMMON_TIMING(trrdl_ps),
 		COMMON_TIMING(tccdl_ps),
+		COMMON_TIMING(trfc_slr_ps),
 #else
 		COMMON_TIMING(twtr_ps),
 		COMMON_TIMING(trfc_ps),
@@ -561,6 +570,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
 		CTRL_OPTIONS(mirrored_dimm),
 		CTRL_OPTIONS(ap_en),
 		CTRL_OPTIONS(x4_en),
+		CTRL_OPTIONS(package_3ds),
 		CTRL_OPTIONS(bstopre),
 		CTRL_OPTIONS(wrlvl_override),
 		CTRL_OPTIONS(wrlvl_sample),
@@ -855,6 +865,7 @@ static void print_memctl_options(const memctl_options_t *popts)
 		CTRL_OPTIONS(mirrored_dimm),
 		CTRL_OPTIONS(ap_en),
 		CTRL_OPTIONS(x4_en),
+		CTRL_OPTIONS(package_3ds),
 		CTRL_OPTIONS(bstopre),
 		CTRL_OPTIONS(wrlvl_override),
 		CTRL_OPTIONS(wrlvl_sample),
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index 850c8f6..6599901 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.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
  */
@@ -234,6 +235,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
 	unsigned int trrds_ps = 0;
 	unsigned int trrdl_ps = 0;
 	unsigned int tccdl_ps = 0;
+	unsigned int trfc_slr_ps = 0;
 #else
 	unsigned int twr_ps = 0;
 	unsigned int twtr_ps = 0;
@@ -313,6 +315,8 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
 			       (unsigned int)dimm_params[i].trrdl_ps);
 		tccdl_ps = max(tccdl_ps,
 			       (unsigned int)dimm_params[i].tccdl_ps);
+		trfc_slr_ps = max(trfc_slr_ps,
+				  (unsigned int)dimm_params[i].trfc_slr_ps);
 #else
 		twr_ps = max(twr_ps, (unsigned int)dimm_params[i].twr_ps);
 		twtr_ps = max(twtr_ps, (unsigned int)dimm_params[i].twtr_ps);
@@ -365,6 +369,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
 	outpdimm->trrds_ps = trrds_ps;
 	outpdimm->trrdl_ps = trrdl_ps;
 	outpdimm->tccdl_ps = tccdl_ps;
+	outpdimm->trfc_slr_ps = trfc_slr_ps;
 #else
 	outpdimm->twtr_ps = twtr_ps;
 	outpdimm->trfc_ps = trfc_ps;
@@ -567,6 +572,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
 	debug("trrds_ps = %u\n", trrds_ps);
 	debug("trrdl_ps = %u\n", trrdl_ps);
 	debug("tccdl_ps = %u\n", tccdl_ps);
+	debug("trfc_slr_ps = %u\n", trfc_slr_ps);
 #else
 	debug("twtr_ps   = %u\n", outpdimm->twtr_ps);
 	debug("trfc_ps   = %u\n", outpdimm->trfc_ps);
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index a7eaed1..5158ea2 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2008, 2010-2014 Freescale Semiconductor, Inc.
+ * Copyright 2008, 2010-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP Semiconductor
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -1292,6 +1293,8 @@ done:
 	if (pdimm[0].n_ranks == 4)
 		popts->quad_rank_present = 1;
 
+	popts->package_3ds = pdimm->package_3ds;
+
 	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
 	if (popts->registered_dimm_en) {
 		popts->rcw_override = 1;
diff --git a/include/common_timing_params.h b/include/common_timing_params.h
index b97147d..0700107 100644
--- a/include/common_timing_params.h
+++ b/include/common_timing_params.h
@@ -26,6 +26,7 @@ typedef struct {
 	unsigned int trrds_ps;
 	unsigned int trrdl_ps;
 	unsigned int tccdl_ps;
+	unsigned int trfc_slr_ps;
 #else
 	unsigned int twtr_ps;	/* maximum = 63750 ps */
 	unsigned int trfc_ps;	/* maximum = 255 ns + 256 ns + .75 ns
diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h
index 12a1944..c6c819e 100644
--- a/include/fsl_ddr_dimm_params.h
+++ b/include/fsl_ddr_dimm_params.h
@@ -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
  */
@@ -18,12 +19,14 @@ typedef struct dimm_params_s {
 	char mpart[19];		/* guaranteed null terminated */
 
 	unsigned int n_ranks;
+	unsigned int die_density;
 	unsigned long long rank_density;
 	unsigned long long capacity;
 	unsigned int data_width;
 	unsigned int primary_sdram_width;
 	unsigned int ec_sdram_width;
 	unsigned int registered_dimm;
+	unsigned int package_3ds;	/* number of dies in 3DS DIMM */
 	unsigned int device_width;	/* x4, x8, x16 components */
 
 	/* SDRAM device parameters */
@@ -79,6 +82,7 @@ typedef struct dimm_params_s {
 	int trrds_ps;
 	int trrdl_ps;
 	int tccdl_ps;
+	int trfc_slr_ps;
 #else
 	int twr_ps;	/* maximum = 63750 ps */
 	int trfc_ps;	/* max = 255 ns + 256 ns + .75 ns
diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h
index de7ef9b..d4275e6 100644
--- a/include/fsl_ddr_sdram.h
+++ b/include/fsl_ddr_sdram.h
@@ -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
  */
@@ -366,6 +367,7 @@ typedef struct memctl_options_s {
 	unsigned int quad_rank_present;
 	unsigned int ap_en;	/* address parity enable for RDIMM/DDR4-UDIMM */
 	unsigned int x4_en;	/* enable x4 devices */
+	unsigned int package_3ds;
 
 	/* Global Timing Parameters */
 	unsigned int cas_latency_override;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 4/8] drivers/ddr/fsl: Add calculation of register control words
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 2/8] drivers/ddr/fsl: Fix workaround for A009803 York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 3/8] drivers/ddr/fsl: Add 3DS RDIMM support York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 5/8] drivers/ddr/fsl: Modify binding registers to save time on data init York Sun
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

DDR4 RDIMM has some information in SPD to be used to calculate the
control words for register chip. The rest can be found from JEDEC
spec DDR4RCD02.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
New patch to add RCW calculation.

Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/ctrl_regs.c        | 30 +++++++++++++++++++++++-------
 drivers/ddr/fsl/ddr4_dimm_params.c | 20 ++++++++++++++++++++
 drivers/ddr/fsl/options.c          |  2 ++
 include/ddr_spd.h                  |  8 +++++---
 include/fsl_ddr_dimm_params.h      |  2 +-
 5 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index bcab904..8b87271 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -724,10 +724,14 @@ 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) {
@@ -735,6 +739,16 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
 			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 | \
@@ -747,12 +761,14 @@ 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);
@@ -2561,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);
@@ -2582,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;
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index 0d3d137..5c8fc88 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -192,6 +192,26 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 		pdimm->registered_dimm = 1;
 		if (spd->mod_section.registered.reg_map & 0x1)
 			pdimm->mirrored_dimm = 1;
+		val = spd->mod_section.registered.ca_stren;
+		pdimm->rcw[3] = val >> 4;
+		pdimm->rcw[4] = ((val & 0x3) << 2) | ((val & 0xc) >> 2);
+		val = spd->mod_section.registered.clk_stren;
+		pdimm->rcw[5] = ((val & 0x3) << 2) | ((val & 0xc) >> 2);
+		/* Not all in SPD. For convience only. Boards may overwrite. */
+		pdimm->rcw[6] = 0xf;
+		/*
+		 * A17 only used for 16Gb and above devices.
+		 * C[2:0] only used for 3DS.
+		 */
+		pdimm->rcw[8] = pdimm->die_density >= 0x6 ? 0x0 : 0x8 |
+				(pdimm->package_3ds > 0x3 ? 0x0 :
+				 (pdimm->package_3ds > 0x1 ? 0x1 :
+				  (pdimm->package_3ds > 0 ? 0x2 : 0x3)));
+		if (pdimm->package_3ds || pdimm->n_ranks != 4)
+			pdimm->rcw[13] = 0xc;
+		else
+			pdimm->rcw[13] = 0xd;	/* Fix encoded by board */
+
 		break;
 
 	case DDR4_SPD_MODULETYPE_UDIMM:
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 5158ea2..536f143 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -1296,6 +1296,7 @@ done:
 	popts->package_3ds = pdimm->package_3ds;
 
 	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
+#if (CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4)
 	if (popts->registered_dimm_en) {
 		popts->rcw_override = 1;
 		popts->rcw_1 = 0x000a5a00;
@@ -1308,6 +1309,7 @@ done:
 		else
 			popts->rcw_2 = 0x00300000;
 	}
+#endif
 
 	fsl_ddr_board_options(popts, pdimm, ctrl_num);
 
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
index d71cd9a..20dc9ea 100644
--- a/include/ddr_spd.h
+++ b/include/ddr_spd.h
@@ -382,9 +382,11 @@ struct ddr4_spd_eeprom_s {
 			/* 135 Register Revision Number */
 			uint8_t reg_rev;
 			/* 136 Address mapping from register to DRAM */
-			uint8_t reg_map;
-			/* 137~253 Reserved */
-			uint8_t res_137[254-137];
+			u8 reg_map;
+			u8 ca_stren;
+			u8 clk_stren;
+			/* 139~253 Reserved */
+			u8 res_137[254 - 139];
 			/* 254~255 CRC */
 			uint8_t crc[2];
 		} registered;
diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h
index c6c819e..1f78ea2 100644
--- a/include/fsl_ddr_dimm_params.h
+++ b/include/fsl_ddr_dimm_params.h
@@ -106,7 +106,7 @@ typedef struct dimm_params_s {
 	int tqhs_ps;	/* byte 45, spd->tqhs */
 #endif
 
-	/* DDR3 RDIMM */
+	/* DDR3 & DDR4 RDIMM */
 	unsigned char rcw[16];	/* Register Control Word 0-15 */
 #ifdef CONFIG_SYS_FSL_DDR4
 	unsigned int dq_mapping[18];
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 5/8] drivers/ddr/fsl: Modify binding registers to save time on data init
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
                   ` (2 preceding siblings ...)
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 4/8] drivers/ddr/fsl: Add calculation of register control words York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 6/8] drivers/ddr/fsl: Cleanup unused variable York Sun
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

DDR controllers always use binding register to determine the memory
space to perform data initialization. In case of controller interleaving,
the space is doubled, resulting twice long wait. It wasn't too bad until
the memory capacity increases. To reduce the wait time, reduce the
binding space to half and restore it after data initialization.
Three-way interleaving is no longer used and is removed.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
New patch to reduce data init time by half.

Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/fsl_ddr_gen4.c | 54 +++++++++++++++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index 7df9178..755f11d 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -16,6 +16,8 @@
 #include <asm/arch/clock.h>
 #endif
 
+#define CTLR_INTLV_MASK	0x20000000
+
 #if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \
 	defined(CONFIG_SYS_FSL_ERRATUM_A009803)
 static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
@@ -54,6 +56,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 	u32 temp32;
 	u32 total_gb_size_per_controller;
 	int timeout;
+	int mod_bnds = 0;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_A008511
 	u32 mr6;
@@ -91,6 +94,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 		printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
 		return;
 	}
+	mod_bnds = regs->cs[0].config & CTLR_INTLV_MASK;
 
 	if (step == 2)
 		goto step2;
@@ -102,25 +106,48 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 		ddr_out32(&ddr->eor, regs->ddr_eor);
 
 	ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
-
 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
 		if (i == 0) {
-			ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
-			ddr_out32(&ddr->cs0_config, regs->cs[i].config);
+			if (mod_bnds) {
+				debug("modified bnds\n");
+				ddr_out32(&ddr->cs0_bnds,
+					  (regs->cs[i].bnds & 0xfffefffe) >> 1);
+				ddr_out32(&ddr->cs0_config,
+					  (regs->cs[i].config &
+					   ~CTLR_INTLV_MASK));
+			} else {
+				ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
+				ddr_out32(&ddr->cs0_config, regs->cs[i].config);
+			}
 			ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2);
 
 		} else if (i == 1) {
-			ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
+			if (mod_bnds) {
+				ddr_out32(&ddr->cs1_bnds,
+					  (regs->cs[i].bnds & 0xfffefffe) >> 1);
+			} else {
+				ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
+			}
 			ddr_out32(&ddr->cs1_config, regs->cs[i].config);
 			ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2);
 
 		} else if (i == 2) {
-			ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
+			if (mod_bnds) {
+				ddr_out32(&ddr->cs2_bnds,
+					  (regs->cs[i].bnds & 0xfffefffe) >> 1);
+			} else {
+				ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
+			}
 			ddr_out32(&ddr->cs2_config, regs->cs[i].config);
 			ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2);
 
 		} else if (i == 3) {
-			ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
+			if (mod_bnds) {
+				ddr_out32(&ddr->cs3_bnds,
+					  (regs->cs[i].bnds & 0xfffefffe) >> 1);
+			} else {
+				ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
+			}
 			ddr_out32(&ddr->cs3_config, regs->cs[i].config);
 			ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2);
 		}
@@ -417,13 +444,10 @@ step2:
 			((regs->cs[i].config >> 8) & 0x7) + 12 +
 			((regs->cs[i].config >> 4) & 0x3) + 0 +
 			((regs->cs[i].config >> 0) & 0x7) + 8 +
+			((regs->ddr_sdram_cfg_3 >> 4) & 0x3) +
 			3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
 			26);			/* minus 26 (count of 64M) */
 	}
-	if (fsl_ddr_get_intl3r() & 0x80000000)	/* 3-way interleaving */
-		total_gb_size_per_controller *= 3;
-	else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */
-		total_gb_size_per_controller <<= 1;
 	/*
 	 * total memory / bus width = transactions needed
 	 * transactions needed / data rate = seconds
@@ -449,6 +473,15 @@ step2:
 	if (timeout <= 0)
 		printf("Waiting for D_INIT timeout. Memory may not work.\n");
 
+	if (mod_bnds) {
+		debug("Reset to original bnds\n");
+		ddr_out32(&ddr->cs0_bnds, regs->cs[0].bnds);
+		ddr_out32(&ddr->cs1_bnds, regs->cs[1].bnds);
+		ddr_out32(&ddr->cs2_bnds, regs->cs[2].bnds);
+		ddr_out32(&ddr->cs3_bnds, regs->cs[3].bnds);
+		ddr_out32(&ddr->cs0_config, regs->cs[0].config);
+	}
+
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009663
 	ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
 #endif
@@ -468,7 +501,6 @@ step2:
 #define BIST_CR		0x80010000
 #define BIST_CR_EN	0x80000000
 #define BIST_CR_STAT	0x00000001
-#define CTLR_INTLV_MASK	0x20000000
 	/* Perform build-in test on memory. Three-way interleaving is not yet
 	 * supported by this code. */
 	if (env_get_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 6/8] drivers/ddr/fsl: Cleanup unused variable
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
                   ` (3 preceding siblings ...)
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 5/8] drivers/ddr/fsl: Modify binding registers to save time on data init York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 7/8] armv8: ls1046ardb: Add RDIMM support York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 8/8] armv8: ls2088ardb: Add 3DS " York Sun
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

Variable "row_density" is no longer used. Drop it from DIMM structure.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
New patch to cleanup unused variables.

Changes in v3: None
Changes in v2: None

 drivers/ddr/fsl/ddr1_dimm_params.c | 1 -
 drivers/ddr/fsl/ddr2_dimm_params.c | 1 -
 drivers/ddr/fsl/ddr3_dimm_params.c | 1 -
 drivers/ddr/fsl/ddr4_dimm_params.c | 1 -
 drivers/ddr/fsl/interactive.c      | 1 -
 include/fsl_ddr_dimm_params.h      | 1 -
 6 files changed, 6 deletions(-)

diff --git a/drivers/ddr/fsl/ddr1_dimm_params.c b/drivers/ddr/fsl/ddr1_dimm_params.c
index 369b325..c02725e 100644
--- a/drivers/ddr/fsl/ddr1_dimm_params.c
+++ b/drivers/ddr/fsl/ddr1_dimm_params.c
@@ -270,7 +270,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	pdimm->n_banks_per_sdram_device = spd->nbanks;
 	pdimm->edc_config = spd->config;
 	pdimm->burst_lengths_bitmask = spd->burstl;
-	pdimm->row_density = spd->bank_dens;
 
 	/*
 	 * Calculate the Maximum Data Rate based on the Minimum Cycle time.
diff --git a/drivers/ddr/fsl/ddr2_dimm_params.c b/drivers/ddr/fsl/ddr2_dimm_params.c
index af752cc..062c849 100644
--- a/drivers/ddr/fsl/ddr2_dimm_params.c
+++ b/drivers/ddr/fsl/ddr2_dimm_params.c
@@ -269,7 +269,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	pdimm->n_banks_per_sdram_device = spd->nbanks;
 	pdimm->edc_config = spd->config;
 	pdimm->burst_lengths_bitmask = spd->burstl;
-	pdimm->row_density = spd->rank_dens;
 
 	/*
 	 * Calculate the Maximum Data Rate based on the Minimum Cycle time.
diff --git a/drivers/ddr/fsl/ddr3_dimm_params.c b/drivers/ddr/fsl/ddr3_dimm_params.c
index 9944dbb..8a0587a 100644
--- a/drivers/ddr/fsl/ddr3_dimm_params.c
+++ b/drivers/ddr/fsl/ddr3_dimm_params.c
@@ -186,7 +186,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	 * BL8 -bit3, BC4 -bit2
 	 */
 	pdimm->burst_lengths_bitmask = 0x0c;
-	pdimm->row_density = __ilog2(pdimm->rank_density);
 
 	/* MTB - medium timebase
 	 * The unit in the SPD spec is ns,
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index 5c8fc88..4867fbc 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -264,7 +264,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
 	 * BL8 -bit3, BC4 -bit2
 	 */
 	pdimm->burst_lengths_bitmask = 0x0c;
-	pdimm->row_density = __ilog2(pdimm->rank_density);
 
 	/* MTB - medium timebase
 	 * The MTB in the SPD spec is 125ps,
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 78ca03b..1fa35c3 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -241,7 +241,6 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		DIMM_PARM(n_banks_per_sdram_device),
 #endif
 		DIMM_PARM(burst_lengths_bitmask),
-		DIMM_PARM(row_density),
 
 		DIMM_PARM(tckmin_x_ps),
 		DIMM_PARM(tckmin_x_minus_1_ps),
diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h
index 1f78ea2..1632a8f 100644
--- a/include/fsl_ddr_dimm_params.h
+++ b/include/fsl_ddr_dimm_params.h
@@ -40,7 +40,6 @@ typedef struct dimm_params_s {
 	unsigned int n_banks_per_sdram_device;
 #endif
 	unsigned int burst_lengths_bitmask;	/* BL=4 bit 2, BL=8 = bit 3 */
-	unsigned int row_density;
 
 	/* used in computing base address of DIMMs */
 	unsigned long long base_address;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 7/8] armv8: ls1046ardb: Add RDIMM support
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
                   ` (4 preceding siblings ...)
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 6/8] drivers/ddr/fsl: Cleanup unused variable York Sun
@ 2018-01-29 17:44 ` York Sun
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 8/8] armv8: ls2088ardb: Add 3DS " York Sun
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

This adds 2Rx8 RDIMM on LS1046ARDB board. Tested with RDIMM
MTA18ASF2G72PDZ and MTA9ASF1G72PZ.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
Adjust write leveling start to align with timing_cfg_7[PAR_LAT].
Add single rank RDIMM.
Remove RCW override in board file.
Modify cpo value slightly to fit both UDIMM and RDIMM.

Changes in v3:
Update register control words for different speeds.

Changes in v2:
Update timing table for lower speeds

 board/freescale/ls1046ardb/ddr.c |  9 +++++----
 board/freescale/ls1046ardb/ddr.h | 19 +++++++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/board/freescale/ls1046ardb/ddr.c b/board/freescale/ls1046ardb/ddr.c
index fb4f6ab..46ed7bd 100644
--- a/board/freescale/ls1046ardb/ddr.c
+++ b/board/freescale/ls1046ardb/ddr.c
@@ -29,7 +29,10 @@ void fsl_ddr_board_options(memctl_options_t *popts,
 	if (!pdimm->n_ranks)
 		return;
 
-	pbsp = udimms[0];
+	if (popts->registered_dimm_en)
+		pbsp = rdimms[0];
+	else
+		pbsp = udimms[0];
 
 	/* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
 	 * freqency and n_banks specified in board_specific_parameters table.
@@ -66,8 +69,6 @@ found:
 	      pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb);
 
 	popts->data_bus_width = 0;	/* 64-bit data bus */
-	popts->otf_burst_chop_en = 0;
-	popts->burst_length = DDR_BL8;
 	popts->bstopre = 0;		/* enable auto precharge */
 
 	/*
@@ -94,7 +95,7 @@ found:
 			  DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2;
 
 	/* optimize cpo for erratum A-009942 */
-	popts->cpo_sample = 0x70;
+	popts->cpo_sample = 0x61;
 }
 
 int fsl_initdram(void)
diff --git a/board/freescale/ls1046ardb/ddr.h b/board/freescale/ls1046ardb/ddr.h
index 9e440f6..04328f2 100644
--- a/board/freescale/ls1046ardb/ddr.h
+++ b/board/freescale/ls1046ardb/ddr.h
@@ -41,4 +41,23 @@ static const struct board_specific_parameters *udimms[] = {
 	udimm0,
 };
 
+static const struct board_specific_parameters rdimm0[] = {
+	/*
+	 * memory controller 0
+	 *   num|  hi| rank|  clk| wrlvl |   wrlvl   |  wrlvl
+	 * ranks| mhz| GB  |adjst| start |   ctl2    |  ctl3
+	 */
+	{2,  1666, 0, 0x8,     0x0D, 0x0C0B0A08, 0x0A0B0C08,},
+	{2,  1900, 0, 0x8,     0x0E, 0x0D0C0B09, 0x0B0C0D09,},
+	{2,  2300, 0, 0xa,     0x12, 0x100F0D0C, 0x0E0F100C,},
+	{1,  1666, 0, 0x8,     0x0D, 0x0C0B0A08, 0x0A0B0C08,},
+	{1,  1900, 0, 0x8,     0x0E, 0x0D0C0B09, 0x0B0C0D09,},
+	{1,  2300, 0, 0xa,     0x12, 0x100F0D0C, 0x0E0F100C,},
+	{}
+};
+
+static const struct board_specific_parameters *rdimms[] = {
+	rdimm0,
+};
+
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v4 8/8] armv8: ls2088ardb: Add 3DS RDIMM support
  2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
                   ` (5 preceding siblings ...)
  2018-01-29 17:44 ` [U-Boot] [PATCH v4 7/8] armv8: ls1046ardb: Add RDIMM support York Sun
@ 2018-01-29 17:44 ` York Sun
  6 siblings, 0 replies; 8+ messages in thread
From: York Sun @ 2018-01-29 17:44 UTC (permalink / raw)
  To: u-boot

Tested with MTA72ASS8G72PSZ-2S6G1. This is 3DS RDIMM module with x4
DDR chips. LS2088ARDB needs to be modified to connect all DQS signals.
Some of them are grounded by default for x8 chips. Tested with RDIMM
MTA18ASF2G72PDZ on main memory controllers. DP-DDR doesn't support
RDIMM. Dropped related timing table.

Signed-off-by: York Sun <york.sun@nxp.com>

---

Changes in v4:
New patch to add 3DS for LS2088ARDB and drop RDIMM on DP-DDR.

Changes in v3: None
Changes in v2: None

 board/freescale/ls2080ardb/ddr.c |  2 ++
 board/freescale/ls2080ardb/ddr.h | 23 ++++-------------------
 2 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c
index 01f7d82..b13a974 100644
--- a/board/freescale/ls2080ardb/ddr.c
+++ b/board/freescale/ls2080ardb/ddr.c
@@ -85,6 +85,8 @@ found:
 		pbsp->wrlvl_ctl_3);
 #ifdef CONFIG_SYS_FSL_HAS_DP_DDR
 	if (ctrl_num == CONFIG_DP_DDR_CTRL) {
+		if (popts->registered_dimm_en)
+			printf("WARN: RDIMM not supported.\n");
 		/* force DDR bus width to 32 bits */
 		popts->data_bus_width = 1;
 		popts->otf_burst_chop_en = 0;
diff --git a/board/freescale/ls2080ardb/ddr.h b/board/freescale/ls2080ardb/ddr.h
index 8d5a490..53c16f5 100644
--- a/board/freescale/ls2080ardb/ddr.h
+++ b/board/freescale/ls2080ardb/ddr.h
@@ -55,24 +55,9 @@ static const struct board_specific_parameters rdimm0[] = {
 	 *   num|  hi| rank|  clk| wrlvl |   wrlvl   |  wrlvl
 	 * ranks| mhz| GB  |adjst| start |   ctl2    |  ctl3
 	 */
-	{2,  1350, 0, 8,     6, 0x0708090B, 0x0C0D0E09,},
-	{2,  1666, 0, 8,     7, 0x08090A0C, 0x0D0F100B,},
-	{2,  1900, 0, 8,     7, 0x09090B0D, 0x0E10120B,},
-	{2,  2200, 0, 8,     8, 0x090A0C0F, 0x1012130C,},
-	{}
-};
-
-/* DP-DDR DIMM */
-static const struct board_specific_parameters rdimm2[] = {
-	/*
-	 * memory controller 2
-	 *   num|  hi| rank|  clk| wrlvl |   wrlvl   |  wrlvl
-	 * ranks| mhz| GB  |adjst| start |   ctl2    |  ctl3
-	 */
-	{2,  1350, 0, 8,     6, 0x0708090B, 0x0C0D0E09,},
-	{2,  1666, 0, 8,     7, 0x0B0A090C, 0x0D0F100B,},
-	{2,  1900, 0, 8,     7, 0x09090B0D, 0x0E10120B,},
-	{2,  2200, 0, 8,     8, 0x090A0C0F, 0x1012130C,},
+	{2,  1666, 0, 8,     0x0F, 0x0D0C0A09, 0x0B0C0E08,},
+	{2,  1900, 0, 8,     0x10, 0x0F0D0B0A, 0x0B0E0F09,},
+	{2,  2200, 0, 8,     0x13, 0x120F0E0B, 0x0D10110B,},
 	{}
 };
 
@@ -85,7 +70,7 @@ static const struct board_specific_parameters *udimms[] = {
 static const struct board_specific_parameters *rdimms[] = {
 	rdimm0,
 	rdimm0,
-	rdimm2,
+	udimm2,	/* DP-DDR doesn't support RDIMM */
 };
 
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-01-29 17:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-29 17:44 [U-Boot] [PATCH v4 1/8] drivers/ddr/fsl: Fix DDR4 RDIMM support York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 2/8] drivers/ddr/fsl: Fix workaround for A009803 York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 3/8] drivers/ddr/fsl: Add 3DS RDIMM support York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 4/8] drivers/ddr/fsl: Add calculation of register control words York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 5/8] drivers/ddr/fsl: Modify binding registers to save time on data init York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 6/8] drivers/ddr/fsl: Cleanup unused variable York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 7/8] armv8: ls1046ardb: Add RDIMM support York Sun
2018-01-29 17:44 ` [U-Boot] [PATCH v4 8/8] armv8: ls2088ardb: Add 3DS " York Sun

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.