diff options
Diffstat (limited to 'board/tqc/tqm85xx/sdram.c')
| -rw-r--r-- | board/tqc/tqm85xx/sdram.c | 141 |
1 files changed, 127 insertions, 14 deletions
diff --git a/board/tqc/tqm85xx/sdram.c b/board/tqc/tqm85xx/sdram.c index 783b2809e..6d73a88ab 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. @@ -38,11 +39,20 @@ struct sdram_conf_s { typedef struct sdram_conf_s sdram_conf_t; #ifdef CONFIG_TQM8548 +#ifdef CONFIG_TQM8548_AG +sdram_conf_t ddr_cs_conf[] = { + {(1024 << 20), 0x80044202, 0x0002D000}, /* 1024MB, 14x10(4) */ + { (512 << 20), 0x80044102, 0x0001A000}, /* 512MB, 13x10(4) */ + { (256 << 20), 0x80040102, 0x00014000}, /* 256MB, 13x10(4) */ + { (128 << 20), 0x80040101, 0x0000C000}, /* 128MB, 13x9(4) */ +}; +#else /* !CONFIG_TQM8548_AG */ sdram_conf_t ddr_cs_conf[] = { {(512 << 20), 0x80044102, 0x0001A000}, /* 512MB, 13x10(4) */ {(256 << 20), 0x80040102, 0x00014000}, /* 256MB, 13x10(4) */ {(128 << 20), 0x80040101, 0x0000C000}, /* 128MB, 13x9(4) */ }; +#endif /* CONFIG_TQM8548_AG */ #else /* !CONFIG_TQM8548 */ sdram_conf_t ddr_cs_conf[] = { {(512 << 20), 0x80000202}, /* 512MB, 14x10(4) */ @@ -69,6 +79,9 @@ 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); +#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE) + volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); +#endif #else /* !CONFIG_TQM8548 */ unsigned long cfg_ddr_timing1; unsigned long cfg_ddr_mode; @@ -81,21 +94,23 @@ long int sdram_setup (int casl) ddr->sdram_cfg = 0; #ifdef CONFIG_TQM8548 + /* Timing and refresh settings for DDR2-533 and below */ + ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24; ddr->cs0_config = ddr_cs_conf[0].reg; - ddr->timing_cfg_3 = 0x00010000; + ddr->timing_cfg_3 = 0x00020000; /* TIMING CFG 1, 533MHz * PRETOACT: 4 Clocks * ACTTOPRE: 12 Clocks * ACTTORW: 4 Clocks * CASLAT: 4 Clocks - * REFREC: 34 Clocks + * REFREC: EXT_REFREC:REFREC 53 Clocks * WRREC: 4 Clocks * ACTTOACT: 3 Clocks * WRTORD: 2 Clocks */ - ddr->timing_cfg_1 = 0x4C47A432; + ddr->timing_cfg_1 = 0x4C47D432; /* TIMING CFG 2, 533MHz * ADD_LAT: 3 Clocks @@ -103,10 +118,10 @@ long int sdram_setup (int casl) * WR_LAT: 3 Clocks * RD_TO_PRE: 2 Clocks * WR_DATA_DELAY: 1/2 Clock - * CKE_PLS: 1 Clock - * FOUR_ACT: 13 Clocks + * CKE_PLS: 3 Clock + * FOUR_ACT: 14 Clocks */ - ddr->timing_cfg_2 = 0x3318484D; + ddr->timing_cfg_2 = 0x331848CE; /* DDR SDRAM Mode, 533MHz * MRS: Extended Mode Register @@ -136,13 +151,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 @@ -170,7 +184,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 @@ -192,9 +303,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: |