|
@@ -18,12 +18,13 @@
|
|
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
unsigned int ctrl_num)
|
|
unsigned int ctrl_num)
|
|
{
|
|
{
|
|
- unsigned int i;
|
|
|
|
|
|
+ unsigned int i, bus_width;
|
|
volatile ccsr_ddr_t *ddr;
|
|
volatile ccsr_ddr_t *ddr;
|
|
u32 temp_sdram_cfg;
|
|
u32 temp_sdram_cfg;
|
|
|
|
+ u32 total_gb_size_per_controller;
|
|
|
|
+ int timeout, timeout_save;
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR;
|
|
volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR;
|
|
- u32 total_gb_size_per_controller;
|
|
|
|
unsigned int csn_bnds_backup = 0, cs_sa, cs_ea, *csn_bnds_t;
|
|
unsigned int csn_bnds_backup = 0, cs_sa, cs_ea, *csn_bnds_t;
|
|
int csn = -1;
|
|
int csn = -1;
|
|
#endif
|
|
#endif
|
|
@@ -52,8 +53,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- out_be32(&ddr->eor, regs->ddr_eor);
|
|
|
|
-
|
|
|
|
|
|
+ if (regs->ddr_eor)
|
|
|
|
+ out_be32(&ddr->eor, regs->ddr_eor);
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
debug("Workaround for ERRATUM_DDR111_DDR134\n");
|
|
debug("Workaround for ERRATUM_DDR111_DDR134\n");
|
|
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
|
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
|
@@ -275,9 +276,46 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
|
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
|
asm volatile("sync;isync");
|
|
asm volatile("sync;isync");
|
|
|
|
|
|
|
|
+ total_gb_size_per_controller = 0;
|
|
|
|
+ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
|
|
|
+ if (!(regs->cs[i].config & 0x80000000))
|
|
|
|
+ continue;
|
|
|
|
+ total_gb_size_per_controller += 1 << (
|
|
|
|
+ ((regs->cs[i].config >> 14) & 0x3) + 2 +
|
|
|
|
+ ((regs->cs[i].config >> 8) & 0x7) + 12 +
|
|
|
|
+ ((regs->cs[i].config >> 0) & 0x7) + 8 +
|
|
|
|
+ 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
|
|
|
|
+ * to add plenty of buffer, double the time
|
|
|
|
+ * For example, 2GB on 666MT/s 64-bit bus takes about 402ms
|
|
|
|
+ * Let's wait for 800ms
|
|
|
|
+ */
|
|
|
|
+ bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
|
|
|
|
+ >> SDRAM_CFG_DBW_SHIFT);
|
|
|
|
+ timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
|
|
|
|
+ (get_ddr_freq(0) >> 20)) << 1;
|
|
|
|
+ timeout_save = timeout;
|
|
|
|
+ total_gb_size_per_controller >>= 4; /* shift down to gb size */
|
|
|
|
+ debug("total %d GB\n", total_gb_size_per_controller);
|
|
|
|
+ debug("Need to wait up to %d * 10ms\n", timeout);
|
|
|
|
+
|
|
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
|
|
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
|
|
- while (in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT)
|
|
|
|
|
|
+ while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
|
|
|
|
+ (timeout >= 0)) {
|
|
udelay(10000); /* throttle polling rate */
|
|
udelay(10000); /* throttle polling rate */
|
|
|
|
+ timeout--;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (timeout <= 0)
|
|
|
|
+ printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
|
|
|
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
|
|
/* continue this workaround */
|
|
/* continue this workaround */
|
|
@@ -335,23 +373,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
while (in_be32(&ddr->debug[1]) & 0x400)
|
|
while (in_be32(&ddr->debug[1]) & 0x400)
|
|
udelay(10000); /* throttle polling rate */
|
|
udelay(10000); /* throttle polling rate */
|
|
|
|
|
|
- /* 7. Wait for 400ms/GB */
|
|
|
|
- total_gb_size_per_controller = 0;
|
|
|
|
- for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
|
|
|
- if (i == csn) {
|
|
|
|
- total_gb_size_per_controller +=
|
|
|
|
- ((csn_bnds_backup & 0xFFFF) >> 6)
|
|
|
|
- - (csn_bnds_backup >> 22) + 1;
|
|
|
|
- } else {
|
|
|
|
- total_gb_size_per_controller +=
|
|
|
|
- ((regs->cs[i].bnds & 0xFFFF) >> 6)
|
|
|
|
- - (regs->cs[i].bnds >> 22) + 1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (in_be32(&ddr->sdram_cfg) & 0x80000)
|
|
|
|
- total_gb_size_per_controller <<= 1;
|
|
|
|
- debug("Wait for %d ms\n", total_gb_size_per_controller * 400);
|
|
|
|
- udelay(total_gb_size_per_controller * 400000);
|
|
|
|
|
|
+ /* 7. Wait for state machine 2nd run, roughly 400ms/GB */
|
|
|
|
+ debug("Wait for %d * 10ms\n", timeout_save);
|
|
|
|
+ udelay(timeout_save * 10000);
|
|
|
|
|
|
/* 8. Set sdram_cfg_2[dinit] if options requires */
|
|
/* 8. Set sdram_cfg_2[dinit] if options requires */
|
|
setbits_be32(&ddr->sdram_cfg_2,
|
|
setbits_be32(&ddr->sdram_cfg_2,
|
|
@@ -359,8 +383,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
|
|
debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
|
|
|
|
|
|
/* 9. Poll until dinit is cleared */
|
|
/* 9. Poll until dinit is cleared */
|
|
- while (in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT)
|
|
|
|
- udelay(10000);
|
|
|
|
|
|
+ timeout = timeout_save;
|
|
|
|
+ debug("Need to wait up to %d * 10ms\n", timeout);
|
|
|
|
+ while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
|
|
|
|
+ (timeout >= 0)) {
|
|
|
|
+ udelay(10000); /* throttle polling rate */
|
|
|
|
+ timeout--;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (timeout <= 0)
|
|
|
|
+ printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
|
|
|
|
|
/* 10. Clear EEBACR[3] */
|
|
/* 10. Clear EEBACR[3] */
|
|
clrbits_be32(&ecm->eebacr, 10000000);
|
|
clrbits_be32(&ecm->eebacr, 10000000);
|