summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@grandegger.com>2009-02-11 17:38:26 (GMT)
committerAndy Fleming <afleming@freescale.com>2009-02-17 00:06:02 (GMT)
commitcf07a5baece0ecfc5284cfda8a4e68eaf92782f8 (patch)
tree9c6dc7f403a2f4db8fb19c86be7d979c6d80d31c /board
parent080408fdc71706adcb883d22125637c54f6010b1 (diff)
downloadu-boot-fsl-qoriq-cf07a5baece0ecfc5284cfda8a4e68eaf92782f8.tar.xz
MPC85xx: TQM8548: workaround for erratum DDR 19 and 20
This patch adds the workaround for erratum DDR20 according to MPC8548 Device Errata document, Rev. 1: "CKE signal may not function correctly after assertion of HRESET". Furthermore, the bug DDR19 is fixed in processor version 2.1 and the work-around must be removed. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Diffstat (limited to 'board')
-rw-r--r--board/tqc/tqm85xx/sdram.c116
1 files changed, 108 insertions, 8 deletions
diff --git a/board/tqc/tqm85xx/sdram.c b/board/tqc/tqm85xx/sdram.c
index 69015ec..2b3de44 100644
--- a/board/tqc/tqm85xx/sdram.c
+++ b/board/tqc/tqm85xx/sdram.c
@@ -1,3 +1,4 @@
+
/*
* (C) Copyright 2005
* Stefan Roese, DENX Software Engineering, sr@denx.de.
@@ -78,6 +79,7 @@ long int sdram_setup (int casl)
volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
#ifdef CONFIG_TQM8548
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
#else /* !CONFIG_TQM8548 */
unsigned long cfg_ddr_timing1;
unsigned long cfg_ddr_mode;
@@ -147,13 +149,12 @@ long int sdram_setup (int casl)
ddr->sdram_interval = (1040 << 16) | 0x100;
/*
- * workaround for erratum DD10 of MPC8458 family below rev. 2.0:
- * DDR IO receiver must be set to an acceptable bias point by modifying
- * a hidden register.
+ * Workaround for erratum DDR19 according to MPC8548 Device Errata
+ * document, Rev. 1: DDR IO receiver must be set to an acceptable
+ * bias point by modifying a hidden register.
*/
- if (SVR_REV (get_svr ()) < 0x20) {
+ if (SVR_REV (get_svr ()) < 0x21)
gur->ddrioovcr = 0x90000000; /* enable, VSEL 1.8V */
- }
/* DDR SDRAM CFG 2
* FRC_SR: normal mode
@@ -181,7 +182,104 @@ long int sdram_setup (int casl)
/* wait for clock stabilization */
asm ("sync;isync;msync");
- udelay(1000);
+ udelay (1000);
+
+#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
+ /*
+ * Workaround for erratum DDR20 according to MPC8548 Device Errata
+ * document, Rev. 1: "CKE signal may not function correctly after
+ * assertion of HRESET"
+ */
+
+ /* 1. Configure DDR register as is done in normal DDR configuration.
+ * Do not set DDR_SDRAM_CFG[MEM_EN].
+ *
+ * 2. Set reserved bit EEBACR[3] at offset 0x1000
+ */
+ ecm->eebacr |= 0x10000000;
+
+ /*
+ * 3. Before DDR_SDRAM_CFG[MEM_EN] is set, write DDR_SDRAM_CFG_2[D_INIT]
+ *
+ * DDR_SDRAM_CFG_2:
+ * FRC_SR: normal mode
+ * SR_IE: no self-refresh interrupt
+ * DLL_RST_DIS: don't care, leave at reset value
+ * DQS_CFG: differential DQS signals
+ * ODT_CFG: assert ODT to internal IOs only during reads to DRAM
+ * LVWx_CFG: don't care, leave at reset value
+ * NUM_PR: 1 refresh will be issued at a time
+ * DM_CFG: don't care, leave at reset value
+ * D_INIT: enable data initialization
+ */
+ ddr->sdram_cfg_2 |= 0x00000010;
+
+ /*
+ * 4. Before DDR_SDRAM_CFG[MEM_EN] set, write D3[21] to disable data
+ * training
+ */
+ ddr->debug_3 |= 0x00000400;
+
+ /*
+ * 5. Wait 200 micro-seconds
+ */
+ udelay (200);
+
+ /*
+ * 6. Set DDR_SDRAM_CFG[MEM_EN]
+ *
+ * BTW, initialize DDR_SDRAM_CFG:
+ * MEM_EN: enabled
+ * SREN: don't care, leave at reset value
+ * ECC_EN: no error report
+ * RD_EN: no registered DIMMs
+ * SDRAM_TYPE: DDR2
+ * DYN_PWR: no power management
+ * 32_BE: don't care, leave at reset value
+ * 8_BE: 4 beat burst
+ * NCAP: don't care, leave at reset value
+ * 2T_EN: 1T Timing
+ * BA_INTLV_CTL: no interleaving
+ * x32_EN: x16 organization
+ * PCHB8: MA[10] for auto-precharge
+ * HSE: half strength for single and 2-layer stacks
+ * (full strength for 3- and 4-layer stacks not
+ * yet considered)
+ * MEM_HALT: no halt
+ * BI: automatic initialization
+ */
+ ddr->sdram_cfg = 0x83000008;
+
+ /*
+ * 7. Poll DDR_SDRAM_CFG_2[D_INIT] until it is cleared by hardware
+ */
+ asm ("sync;isync;msync");
+ while (ddr->sdram_cfg_2 & 0x00000010)
+ asm ("eieio");
+
+ /*
+ * 8. Clear D3[21] to re-enable data training
+ */
+ ddr->debug_3 &= ~0x00000400;
+
+ /*
+ * 9. Set D2(21) to force data training to run
+ */
+ ddr->debug_2 |= 0x00000400;
+
+ /*
+ * 10. Poll on D2[21] until it is cleared by hardware
+ */
+ asm ("sync;isync;msync");
+ while (ddr->debug_2 & 0x00000400)
+ asm ("eieio");
+
+ /*
+ * 11. Clear reserved bit EEBACR[3] at offset 0x1000
+ */
+ ecm->eebacr &= ~0x10000000;
+
+#else /* !(CONFIG_TQM8548_AG || CONFIG_TQM8548_BE) */
/* DDR SDRAM CLK CNTL
* MEM_EN: enabled
@@ -203,9 +301,11 @@ long int sdram_setup (int casl)
* BI: automatic initialization
*/
ddr->sdram_cfg = 0x83000008;
- asm ("sync; isync; msync");
- udelay(1000);
+#endif /* CONFIG_TQM8548_AG || CONFIG_TQM8548_BE */
+
+ asm ("sync; isync; msync");
+ udelay (1000);
#else /* !CONFIG_TQM8548 */
switch (casl) {
case 20: