[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