Skip to contentSkip to conversation

Enable high speed and heavy load for DDR4 for LSCH3

PATCH New York Sun 3 participants 21 messages Nov 4, 2015 – Dec 15, 2015

lore
Share & tools
lore

York Sun

author
#0 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

This patch set revises the DDR driver to support higher speed for DDR4 under heavy load (two dual-rank DIMMs) for four-chipselect interleaving. Single quad-rank DIMM is not supported yet.

York Sun (7):
driver/ddr/fsl: Update DDR4 RTT values driver/ddr/fsl: Update DDR4 MR6 for Vref range driver/ddr/fsl: Update MR5 RTT park
driver/ddr/fsl: Update workaround for A008511 for vref range driver/ddr/fsl: Update timing config for heavy load armv8/ls2085aqds: Update DDR settings for four chip-select case armv8/ls2085ardb: Update DDR settings for four chip-select case

 board/freescale/ls2085aqds/ddr.c |   16 ++-
 board/freescale/ls2085ardb/ddr.c |   16 ++-
 drivers/ddr/fsl/ctrl_regs.c      |   48 +++++++-
 drivers/ddr/fsl/fsl_ddr_gen4.c   |   22 ++--
 drivers/ddr/fsl/options.c        |  237 +++++++++++++++++++++++++++++++++++++-
 include/fsl_ddr_sdram.h          |    9 ++
 6 files changed, 325 insertions(+), 23 deletions(-)
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 1/7 driver/ddr/fsl: Update DDR4 RTT values

DDR4 has different RTT value and code according to JEDEC spec. Update the macros and options .

---

 drivers/ddr/fsl/options.c |  237 ++++++++++++++++++++++++++++++++++++++++++++-
 include/fsl_ddr_sdram.h   |    9 ++
 2 files changed, 244 insertions(+), 2 deletions(-)
drivers/ddr/fsl/options.c +235 -2
index 3c09c64..791d644 100644
@@ -29,7 +29,240 @@ struct dynamic_odt {
 	unsigned int odt_rtt_wr;
 };
 
-#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
+#ifdef CONFIG_SYS_FSL_DDR4
+/* Quad rank is not verified yet due availability.
+ * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option
+ */
+static const struct dynamic_odt single_Q[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
+		DDR4_RTT_34_OHM,	/* unverified */
+		DDR4_RTT_120_OHM
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_NEVER,
+		DDR4_RTT_OFF,
+		DDR4_RTT_120_OHM
+	},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_120_OHM
+	},
+	{	/* cs3 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_NEVER,	/* tied high */
+		DDR4_RTT_OFF,
+		DDR4_RTT_120_OHM
+	}
+};
+
+static const struct dynamic_odt single_D[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_NEVER,
+		DDR4_RTT_OFF,
+		DDR4_RTT_OFF
+	},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+};
+
+static const struct dynamic_odt single_S[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+};
+
+static const struct dynamic_odt dual_DD[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_OTHER_DIMM,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs3 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_OTHER_DIMM,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_OFF
+	}
+};
+
+static const struct dynamic_odt dual_DS[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_OTHER_DIMM,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs2 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_120_OHM
+	},
+	{0, 0, 0, 0}
+};
+static const struct dynamic_odt dual_SD[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_120_OHM
+	},
+	{0, 0, 0, 0},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs3 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_OTHER_DIMM,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_OFF
+	}
+};
+
+static const struct dynamic_odt dual_SS[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_120_OHM
+	},
+	{0, 0, 0, 0},
+	{	/* cs2 */
+		FSL_DDR_ODT_OTHER_DIMM,
+		FSL_DDR_ODT_ALL,
+		DDR4_RTT_34_OHM,
+		DDR4_RTT_120_OHM
+	},
+	{0, 0, 0, 0}
+};
+
+static const struct dynamic_odt dual_D0[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_NEVER,
+		DDR4_RTT_OFF,
+		DDR4_RTT_OFF
+	},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+};
+
+static const struct dynamic_odt dual_0D[4] = {
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_SAME_DIMM,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs3 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_NEVER,
+		DDR4_RTT_OFF,
+		DDR4_RTT_OFF
+	}
+};
+
+static const struct dynamic_odt dual_S0[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+
+};
+
+static const struct dynamic_odt dual_0S[4] = {
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_40_OHM,
+		DDR4_RTT_OFF
+	},
+	{0, 0, 0, 0}
+
+};
+
+static const struct dynamic_odt odt_unknown[4] = {
+	{	/* cs0 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs1 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs2 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	},
+	{	/* cs3 */
+		FSL_DDR_ODT_NEVER,
+		FSL_DDR_ODT_CS,
+		DDR4_RTT_120_OHM,
+		DDR4_RTT_OFF
+	}
+};
+#elif defined(CONFIG_SYS_FSL_DDR3)
 static const struct dynamic_odt single_Q[4] = {
 	{	/* cs0 */
 		FSL_DDR_ODT_NEVER,
@@ -259,7 +492,7 @@ static const struct dynamic_odt odt_unknown[4] = {
 		DDR3_RTT_OFF
 	}
 };
-#else	/* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */
+#else	/* CONFIG_SYS_FSL_DDR3 */
 static const struct dynamic_odt single_Q[4] = {
 	{0, 0, 0, 0},
 	{0, 0, 0, 0},
include/fsl_ddr_sdram.h +9 -0
index c79fce0..4b022d4 100644
@@ -33,6 +33,15 @@
 #define DDR3_RTT_20_OHM		4 /* RTT_Nom = RZQ/12 */
 #define DDR3_RTT_30_OHM		5 /* RTT_Nom = RZQ/8 */
 
+#define DDR4_RTT_OFF		0
+#define DDR4_RTT_60_OHM		1	/* RZQ/4 */
+#define DDR4_RTT_120_OHM	2	/* RZQ/2 */
+#define DDR4_RTT_40_OHM		3	/* RZQ/6 */
+#define DDR4_RTT_240_OHM	4	/* RZQ/1 */
+#define DDR4_RTT_48_OHM		5	/* RZQ/5 */
+#define DDR4_RTT_80_OHM		6	/* RZQ/3 */
+#define DDR4_RTT_34_OHM		7	/* RZQ/7 */
+
 #define DDR2_RTT_OFF		0
 #define DDR2_RTT_75_OHM		1
 #define DDR2_RTT_150_OHM	2
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH 2/7 driver/ddr/fsl: Update DDR4 MR6 for Vref range

In reply to York Sun

MR6 bit 6 is set accrodingly for range 1 or 2, per JEDEC spec.

---

 drivers/ddr/fsl/ctrl_regs.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/ddr/fsl/ctrl_regs.c +3 -0
index 8543679..36bf647 100644
@@ -1186,6 +1186,9 @@ static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
 
 	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)
Signature · 1 line
1.7.9.5
author
#3 lore raw

PATCH 3/7 driver/ddr/fsl: Update MR5 RTT park

In reply to York Sun

For four chip-selects enabled case, RTT is parked on all of them.

---

 drivers/ddr/fsl/ctrl_regs.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/ddr/fsl/ctrl_regs.c +15 -4
index 36bf647..99714bf 100644
@@ -1117,10 +1117,18 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
 	unsigned short esdmode4 = 0;	/* Extended SDRAM mode 4 */
 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
 	int rtt_park = 0;
-
+	bool four_cs = false;
+
+#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 */
 	}
@@ -1130,7 +1138,10 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
 				 | ((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 */
@@ -1138,7 +1149,7 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
 			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;
 			}
Signature · 1 line
1.7.9.5
author
#4 lore raw

PATCH 4/7 driver/ddr/fsl: Update workaround for A008511 for vref range

In reply to York Sun

The workaround requires different setting for range 1 vs 2. Also adjust timeout value for waiting for controller to be idle.

---

 drivers/ddr/fsl/fsl_ddr_gen4.c |   22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)
drivers/ddr/fsl/fsl_ddr_gen4.c +15 -7
index 49e4688..70ce1b8 100644
@@ -54,6 +54,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 #endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_A008511
 	u32 temp32, mr6;
+	u32 vref_seq1[3] = {0x80, 0x96, 0x16};	/* for range 1 */
+	u32 vref_seq2[3] = {0xc0, 0xf0, 0x70};	/* for range 2 */
+	u32 *vref_seq = vref_seq1;
 #endif
 #ifdef CONFIG_FSL_DDR_BIST
 	u32 mtcr, err_detect, err_sbe;
@@ -307,16 +310,21 @@ step2:
 	/* This erraum only applies to verion 5.2.0 */
 	if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
 		/* Wait for idle */
-		timeout = 200;
+		timeout = 40;
 		while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
 		       (timeout > 0)) {
-			udelay(100);
+			udelay(1000);
 			timeout--;
 		}
 		if (timeout <= 0) {
 			printf("Controler %d timeout, debug_2 = %x\n",
 			       ctrl_num, ddr_in32(&ddr->debug[1]));
 		}
+
+		/* The vref setting sequence is different for range 2 */
+		if (regs->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
+			vref_seq = vref_seq2;
+
 		/* Set VREF */
 		for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
 			if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
@@ -327,17 +335,17 @@ step2:
 				 MD_CNTL_CS_SEL(i)			|
 				 MD_CNTL_MD_SEL(6)			|
 				 0x00200000;
-			temp32 = mr6 | 0xc0;
+			temp32 = mr6 | vref_seq[0];
 			set_wait_for_bits_clear(&ddr->sdram_md_cntl,
 						temp32, MD_CNTL_MD_EN);
 			udelay(1);
 			debug("MR6 = 0x%08x\n", temp32);
-			temp32 = mr6 | 0xf0;
+			temp32 = mr6 | vref_seq[1];
 			set_wait_for_bits_clear(&ddr->sdram_md_cntl,
 						temp32, MD_CNTL_MD_EN);
 			udelay(1);
 			debug("MR6 = 0x%08x\n", temp32);
-			temp32 = mr6 | 0x70;
+			temp32 = mr6 | vref_seq[2];
 			set_wait_for_bits_clear(&ddr->sdram_md_cntl,
 						temp32, MD_CNTL_MD_EN);
 			udelay(1);
@@ -347,10 +355,10 @@ step2:
 		ddr_out32(&ddr->debug[28], 0);		/* Enable deskew */
 		ddr_out32(&ddr->debug[1], 0x400);	/* restart deskew */
 		/* wait for idle */
-		timeout = 200;
+		timeout = 40;
 		while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
 		       (timeout > 0)) {
-			udelay(100);
+			udelay(1000);
 			timeout--;
 		}
 		if (timeout <= 0) {
Signature · 1 line
1.7.9.5
author
#5 lore raw

PATCH 5/7 driver/ddr/fsl: Update timing config for heavy load

In reply to York Sun

In case four chip-selects are all active, the turnaround times need to increase to avoid overlapping under heavy load.

---

 drivers/ddr/fsl/ctrl_regs.c |   26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)
drivers/ddr/fsl/ctrl_regs.c +24 -2
index 99714bf..0bfcd34 100644
@@ -317,7 +317,24 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
 
 	/* 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;
 	/*
@@ -1822,6 +1839,7 @@ static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
 	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)
@@ -1835,17 +1853,21 @@ static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
 		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);
Signature · 1 line
1.7.9.5
author
#6 lore raw

PATCH 6/7 armv8/ls2085aqds: Update DDR settings for four chip-select case

In reply to York Sun

When 4 chip-selects are used, vref should use range 1 and CDT uses 80 ohm, and 2T timing is enabled.

---

 board/freescale/ls2085aqds/ddr.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
board/freescale/ls2085aqds/ddr.c +12 -4
index 8d71ae1..d8562b1 100644
@@ -131,10 +131,18 @@ found:
 	popts->zq_en = 1;
 
 	if (ddr_freq < 2350) {
-		popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
-				  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
-		popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
-				  DDR_CDR2_VREF_RANGE_2;
+		if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) {
+			/* four chip-selects */
+			popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+					  DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+			popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm);
+			popts->twot_en = 1; /* enable 2T timing */
+		} else {
+			popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+					  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+			popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+					  DDR_CDR2_VREF_RANGE_2;
+		}
 	} else {
 		popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
 				  DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
Signature · 1 line
1.7.9.5
author
#7 lore raw

PATCH 7/7 armv8/ls2085ardb: Update DDR settings for four chip-select case

In reply to York Sun

When 4 chip-selects are used, vref should use range 1 and CDT uses 80 ohm, and 2T timing is enabled.

---

 board/freescale/ls2085ardb/ddr.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
board/freescale/ls2085ardb/ddr.c +12 -4
index 8d71ae1..e1d6aa1 100644
@@ -131,10 +131,18 @@ found:
 	popts->zq_en = 1;
 
 	if (ddr_freq < 2350) {
-		popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
-				  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
-		popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
-				  DDR_CDR2_VREF_RANGE_2;
+		if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) {
+			/* four chip-selects */
+			popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+					  DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+			popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm);
+			popts->twot_en = 1;	/* enable 2T timing */
+		} else {
+			popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+					  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+			popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+					  DDR_CDR2_VREF_RANGE_2;
+		}
 	} else {
 		popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
 				  DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
Signature · 1 line
1.7.9.5
#8 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

In reply to York Sun
Quoted 3 lines · York Sun

This patch set revises the DDR driver to support higher speed for DDR4 under heavy load (two dual-rank DIMMs) for four-chipselect interleaving. Single quad-rank DIMM is not supported yet.

Hi York

Seeing these patches reminds me about something I have been mening to ask, Is it possible init the ddr controller/ddr ram (using ECC also) but still retain (parts of) memory contents?

I am looking at keeping data at the end of memory when performing a warm start, but still init the controll/ddr ram (without D_INIT set). This way one could pick up any changes to DDR timing if needed. Before reboot, ddr ram is set to Self Refresh(SR).

Jocke

#9 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched. Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Regards,
Yuantian

Quoted 30 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, November 05, 2015 4:04 PM
To: Sun York-R58495 <[email protected]>; u-boot at lists.denx.de
Cc: curt at cumulusnetworks.com; Sharma Bhupesh-B45370 <[email protected]>; trini at konsulko.com; l.majewski at samsung.com; Tang Yuantian-B29983 <[email protected]>; Kushwaha Prabhakar-B32579 <[email protected]>; Liu Shengzhou-B36685 <[email protected]>; yamada.m at jp.panasonic.com
Subject: Re: [PATCH v1 0/7] Enable high speed and heavy load for DDR4 for LSCH3

Quoted 3 lines · York Sun

This patch set revises the DDR driver to support higher speed for DDR4 under heavy load (two dual-rank DIMMs) for four-chipselect interleaving. Single quad-rank DIMM is not supported yet.

Hi York

Seeing these patches reminds me about something I have been mening to ask, Is it possible init the ddr controller/ddr ram (using ECC also) but still retain (parts of) memory contents?

I am looking at keeping data at the end of memory when performing a warm start, but still init the controll/ddr ram (without D_INIT set). This way one could pick up any changes to DDR timing if needed. Before reboot, ddr ram is set to Self Refresh(SR).

Jocke

#10 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

Jocke

Quoted 34 lines

Regards,
Yuantian

Quoted 30 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, November 05, 2015 4:04 PM
To: Sun York-R58495 <[email protected]>; u-boot at lists.denx.de
Cc: curt at cumulusnetworks.com; Sharma Bhupesh-B45370 <[email protected]>; trini at konsulko.com; l.majewski at samsung.com; Tang Yuantian-B29983 <[email protected]>; Kushwaha Prabhakar-B32579 <[email protected]>; Liu Shengzhou-B36685 <[email protected]>; yamada.m at jp.panasonic.com
Subject: Re: [PATCH v1 0/7] Enable high speed and heavy load for DDR4 for LSCH3

Quoted 3 lines · York Sun

This patch set revises the DDR driver to support higher speed for DDR4 under heavy load (two dual-rank DIMMs) for four-chipselect interleaving. Single quad-rank DIMM is not supported yet.

Hi York

Seeing these patches reminds me about something I have been mening to ask, Is it possible init the ddr controller/ddr ram (using ECC also) but still retain (parts of) memory contents?

I am looking at keeping data at the end of memory when performing a warm start, but still init the controll/ddr ram (without D_INIT set). This way one could pick up any changes to DDR timing if needed. Before reboot, ddr ram is set to Self Refresh(SR).

Jocke

author
#11 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 10 lines · Joakim Tjernlund
Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

Quoted 8 lines
 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

Quoted 10 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

York

#12 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 17 lines · York Sun
Quoted 15 lines · Joakim Tjernlund
Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke

author
#13 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 44 lines · Joakim Tjernlund
Quoted 17 lines · York Sun
Quoted 15 lines · Joakim Tjernlund
Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

Quoted 5 lines

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke,

If your memory has been intialized, you can set [BI] bit to bypass re-initialization. It does different things than D_INIT. In short, D_INIT initialize the data, i.e. the content of DDR, while BI bypassing initializing DDR memory (or "chip" if that is easier to understand).

York

#14 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 51 lines · York Sun
Quoted 49 lines · Joakim Tjernlund
Quoted 18 lines · York Sun
Quoted 16 lines · Joakim Tjernlund
Quoted 7 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents
untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Quoted 8 lines
Quoted 1 line

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke,

If your memory has been intialized, you can set [BI] bit to bypass re-initialization. It does different things than D_INIT. In short, D_INIT initialize the data, i.e. the content of DDR, while BI bypassing initializing DDR memory (or "chip" if that is easier to understand).

Yes, that is what I want, reinit of chip, but not data contents.
I wrote why:
"just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust"

Jocke

author
#15 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 56 lines · Joakim Tjernlund
Quoted 55 lines · York Sun
Quoted 45 lines · Joakim Tjernlund
Quoted 18 lines · York Sun
Quoted 16 lines · Joakim Tjernlund
Quoted 7 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents
untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

Quoted 5 lines

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke,

Quoted 8 lines
Quoted 4 lines

If your memory has been intialized, you can set [BI] bit to bypass re-initialization. It does different things than D_INIT. In short, D_INIT initialize the data, i.e. the content of DDR, while BI bypassing initializing DDR memory (or "chip" if that is easier to understand).

Yes, that is what I want, reinit of chip, but not data contents.
I wrote why:
"just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust"

Jocke,

I am not 100% sure. I will take this question to our DDR designer.

York

#16 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 63 lines · York Sun
Quoted 61 lines · Joakim Tjernlund
Quoted 59 lines · York Sun
Quoted 45 lines · Joakim Tjernlund
Quoted 18 lines · York Sun
Quoted 16 lines · Joakim Tjernlund
Quoted 7 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents
untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
?289 if (is_warm_boot()) {
?289?????????????????/* enter self-refresh */ ?290?????????????????temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); ?291?????????????????temp_sdram_cfg |= SDRAM_CFG2_FRC_SR; ?292?????????????????ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);

Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

?293?????????????????/* do board specific memory setup */ ?294?????????????????board_mem_sleep_setup();
?295
?296?????????????????temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

Quoted 5 lines

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke,

If your memory has been intialized, you can set [BI] bit to bypass re-initialization. It does different things than D_INIT. In short, D_INIT initialize the data, i.e. the content of DDR, while BI bypassing initializing DDR memory (or "chip" if that is easier to understand).

Quoted 8 lines
Quoted 4 lines

Yes, that is what I want, reinit of chip, but not data contents.
I wrote why:
"just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust"

Jocke,

I am not 100% sure. I will take this question to our DDR designer.

I am really want to know ...

author
#17 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 69 lines · Joakim Tjernlund
Quoted 68 lines · York Sun
Quoted 65 lines · Joakim Tjernlund
Quoted 51 lines · York Sun
Quoted 49 lines · Joakim Tjernlund
Quoted 18 lines · York Sun
Quoted 16 lines · Joakim Tjernlund
Quoted 7 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for.
If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents
untouched.
Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP related code.

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 7 lines
Quoted 3 lines

Why do you need to force SR here? The DDR RAM must already be in SR at this point? I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

OK

Quoted 9 lines
Quoted 9 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have to force a cold start.

Quoted 6 lines
Quoted 2 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

yes, but what about SDRAM_CFG_BI? Why do you need to set that here?
I much rather just skip D_INIT and reconfigure DDR RAM, just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust.

Quoted 8 lines
Quoted 1 line

Our systems cannot be coldstarted just because you upgrade SW on them.

Jocke,

If your memory has been intialized, you can set [BI] bit to bypass re-initialization. It does different things than D_INIT. In short, D_INIT initialize the data, i.e. the content of DDR, while BI bypassing initializing DDR memory (or "chip" if that is easier to understand).

Yes, that is what I want, reinit of chip, but not data contents.
I wrote why:
"just in case one wants to correct some aspect of DDR config in later releases and feels a lot more robust"

Quoted 6 lines
Quoted 3 lines

Jocke,

I am not 100% sure. I will take this question to our DDR designer.

I am really want to know ...

I haven't heard anything back yet.

York

#18 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

In reply to York Sun
Quoted 34 lines

-----Original Message-----
From: York Sun [mailto:yorksun at freescale.com]
Sent: Friday, November 06, 2015 1:42 AM
To: Joakim Tjernlund <[email protected]>; Tang Yuantian- B29983 <[email protected]>; u-boot at lists.denx.de
Cc: Kushwaha Prabhakar-B32579 <[email protected]>; Sharma Bhupesh-B45370 <[email protected]>; trini at konsulko.com; Liu Shengzhou-B36685 <[email protected]>;
curt at cumulusnetworks.com; l.majewski at samsung.com; yamada.m at jp.panasonic.com
Subject: Re: [PATCH v1 0/7] Enable high speed and heavy load for DDR4 for LSCH3

Quoted 7 lines · Joakim Tjernlund
Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for. If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched. Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP

related code.

Quoted 8 lines

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
Quoted 9 lines
Quoted 1 line

Why do you need to force SR here? The DDR RAM must already be in SR at

this point?

Quoted 2 lines

I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

This is mandatory. the steps are: re-enter SR mode, enable DDR controller, exit SR mode. We do that to smooth the transition and avoid any glitch caused when controller takes over memory.

Regards,
Yuantian

Quoted 18 lines
Quoted 5 lines

293 /* do board specific memory setup */
294 board_mem_sleep_setup();
295
296 temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) |

SDRAM_CFG_BI);

Quoted 2 lines

SDRAM_CFG_BI skips a lot(all?) init of DDR RAM. What if you want to change some DDR RAM timing/config due to a bug? Then you would have

to force a cold start.

Quoted 3 lines

Do you use ECC? Seems to be some issues with ECC if you skip D_INIT

To perform a warm start, the data in DDR is preserved. So you don't need to init the data again for ECC. To preserve data, you cannot run D_INIT again, which will destroy the data for sure.

York

#19 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

Quoted 38 lines · Yuantian Tang
Quoted 38 lines

-----Original Message-----
From: York Sun [mailto:yorksun at freescale.com]
Sent: Friday, November 06, 2015 1:42 AM
To: Joakim Tjernlund <[email protected]>; Tang Yuantian- B29983 <[email protected]>; u-boot at lists.denx.de
Cc: Kushwaha Prabhakar-B32579 <[email protected]>; Sharma Bhupesh-B45370 <[email protected]>; trini at konsulko.com; Liu Shengzhou-B36685 <[email protected]>;
curt at cumulusnetworks.com; l.majewski at samsung.com; yamada.m at jp.panasonic.com
Subject: Re: [PATCH v1 0/7] Enable high speed and heavy load for DDR4 for LSCH3

Quoted 7 lines · Joakim Tjernlund
Quoted 6 lines · Yuantian Tang

Hi Jocke,

we achieved deep sleep mode that did exactly what you asked for. If waken up from deep sleep, soc will resume from uboot and re-initialized DDR controller with contents untouched. Please refer to drivers/ddr/fsl/fsl_ddr_gen4.c and look at DEEP_SLEEP

related code.

Quoted 9 lines

Looking at it now and it looks the same as for ddr3? Some questions though:
289 if (is_warm_boot()) {

 289                 /* enter self-refresh */
 290                 temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
 291                 temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
 292                 ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);

Why do you need to force SR here? The DDR RAM must already be in SR at

this point?

Quoted 2 lines

I come from CPU reset state so my DDR controller has HW default values so this does not feel safe.

Quoted 6 lines
Quoted 4 lines

This may be redundant. If the code runs to this line, it should come back from a deep sleep. The core is in reset state but the DDR controller is not. It should be in self-refresh mode. I will leave that to Yuantian to comment.

This is mandatory. the steps are: re-enter SR mode, enable DDR controller, exit SR mode. We do that to smooth the transition and avoid any glitch caused when controller takes over memory.

hmm, why not do this always? I can't hurt normal operation I think. It would be less special code for this type of operation.

Jocke

author
#20 lore raw

cover Enable high speed and heavy load for DDR4 for LSCH3

In reply to York Sun
Quoted 14 lines · York Sun

This patch set revises the DDR driver to support higher speed for DDR4 under heavy load (two dual-rank DIMMs) for four-chipselect interleaving. Single quad-rank DIMM is not supported yet.

York Sun (7):
driver/ddr/fsl: Update DDR4 RTT values driver/ddr/fsl: Update DDR4 MR6 for Vref range driver/ddr/fsl: Update MR5 RTT park
driver/ddr/fsl: Update workaround for A008511 for vref range driver/ddr/fsl: Update timing config for heavy load armv8/ls2085aqds: Update DDR settings for four chip-select case armv8/ls2085ardb: Update DDR settings for four chip-select case

Quoted 8 lines
 board/freescale/ls2085aqds/ddr.c |   16 ++-
 board/freescale/ls2085ardb/ddr.c |   16 ++-
 drivers/ddr/fsl/ctrl_regs.c      |   48 +++++++-
 drivers/ddr/fsl/fsl_ddr_gen4.c   |   22 ++--
 drivers/ddr/fsl/options.c        |  237 +++++++++++++++++++++++++++++++++++++-
 include/fsl_ddr_sdram.h          |    9 ++
 6 files changed, 325 insertions(+), 23 deletions(-)

Changed subject from ls2085a to ls2080a.
Applied to fsl-qoriq master. Awaiting upstream.

York