drivers/ddr/fsl: Modify binding registers to save time on data init
authorYork Sun <york.sun@nxp.com>
Mon, 29 Jan 2018 17:44:37 +0000 (09:44 -0800)
committerYork Sun <york.sun@nxp.com>
Tue, 30 Jan 2018 17:14:07 +0000 (09:14 -0800)
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>
drivers/ddr/fsl/fsl_ddr_gen4.c

index 7df917841593a7a052295bedd7b1cfea6ac896aa..c225c8e723e5a6d89f19f4e7fe3e2b16f9b3a5e1 100644 (file)
@@ -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,21 @@ 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);
+#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
+               ddr_out32(&ddr->cs1_bnds, regs->cs[1].bnds);
+#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
+               ddr_out32(&ddr->cs2_bnds, regs->cs[2].bnds);
+#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
+               ddr_out32(&ddr->cs3_bnds, regs->cs[3].bnds);
+#endif
+#endif
+#endif
+               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 +507,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) {