[U-Boot] [PATCH v4 5/8] drivers/ddr/fsl: Modify binding registers to save time on data init

York Sun york.sun at nxp.com
Mon Jan 29 17:44:37 UTC 2018


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 at 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



More information about the U-Boot mailing list