[U-Boot] [PATCH 08/10] Implement workaround for erratum DDRA003
York Sun
yorksun at freescale.com
Thu Dec 9 03:55:38 CET 2010
Erratum DDRA003 requires workaround to correctly set RCW10 for registered DIMM.
Also adding polling after enabling DDR controller to ensure completion.
Signed-off-by: York Sun <yorksun at freescale.com>
---
arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 53 ++++++++++++++++++++++++++++++++++-
include/configs/P4080DS.h | 1 +
2 files changed, 53 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index 568f9f4..0815ba4 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -108,6 +108,55 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
temp_sdram_cfg = regs->ddr_sdram_cfg;
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
+#ifdef CONFIG_SYS_P4080_ERRATUM_DDRA003
+ if (regs->ddr_sdram_rcw_2 & 0x00f00000) {
+ out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff);
+ out_be32(&ddr->debug[2], 0x00000400);
+ out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl & 0x7fffffff);
+ out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl & 0x7fffffff);
+ out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2 & 0xffffffeb);
+ out_be32(&ddr->mtcr, 0);
+ out_be32(&ddr->debug[12], 0x00000015);
+ out_be32(&ddr->debug[21], 0x24000000);
+ out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval & 0xffff);
+ out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_BI | SDRAM_CFG_MEM_EN);
+
+ asm volatile("sync;isync");
+ while (!(in_be32(&ddr->debug[1]) & 0x2));
+
+ switch (regs->ddr_sdram_rcw_2 & 0x00f00000) {
+ case 0x00000000:
+ out_be32(&ddr->sdram_md_cntl, 0xc4080002);
+ break;
+ case 0x00100000:
+ out_be32(&ddr->sdram_md_cntl, 0xc408000a);
+ break;
+ case 0x00200000:
+ out_be32(&ddr->sdram_md_cntl, 0xc4080012);
+ break;
+ case 0x00300000:
+ out_be32(&ddr->sdram_md_cntl, 0xc408001a);
+ break;
+ default:
+ out_be32(&ddr->sdram_md_cntl, 0xc4080002);
+ printf("Unsupported RC10\n");
+ break;
+ }
+
+ while (in_be32(&ddr->sdram_md_cntl) & 0x80000000);
+ udelay(6);
+ out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
+ out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
+ out_be32(&ddr->debug[2], 0x0);
+ out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
+ out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
+ out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
+ out_be32(&ddr->debug[12], 0x0);
+ out_be32(&ddr->debug[21], 0x0);
+ out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
+
+ }
+#endif
/*
* For 8572 DDR1 erratum - DDR controller may enter illegal state
* when operatiing in 32-bit bus mode with 4-beat bursts,
@@ -131,8 +180,10 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
asm volatile("sync;isync");
/* Let the controller go */
- temp_sdram_cfg = in_be32(&ddr->sdram_cfg);
+ temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
+ asm volatile("sync;isync");
+ while (!(in_be32(&ddr->debug[1]) & 0x2));
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
while (in_be32(&ddr->sdram_cfg_2) & 0x10) {
diff --git a/include/configs/P4080DS.h b/include/configs/P4080DS.h
index d210016..c19bd39 100644
--- a/include/configs/P4080DS.h
+++ b/include/configs/P4080DS.h
@@ -45,6 +45,7 @@
#define CONFIG_SYS_P4080_ERRATUM_CPC9
#define CONFIG_SYS_P4080_ERRATUM_DDR1
#define CONFIG_SYS_P4080_ERRATUM_DDR7
+#define CONFIG_SYS_P4080_ERRATUM_DDRA003
#define CONFIG_SYS_P4080_ERRATUM_ESDHC1
#define CONFIG_SYS_P4080_ERRATUM_ESDHC9
#define CONFIG_SYS_P4080_ERRATUM_ESDHC11
--
1.7.0.4
More information about the U-Boot
mailing list