diff options
| author | Wolfgang Grandegger <wg@grandegger.com> | 2009-02-11 18:38:26 +0100 | 
|---|---|---|
| committer | Andy Fleming <afleming@freescale.com> | 2009-02-16 18:06:02 -0600 | 
| commit | cf07a5baece0ecfc5284cfda8a4e68eaf92782f8 (patch) | |
| tree | 9c6dc7f403a2f4db8fb19c86be7d979c6d80d31c | |
| parent | 080408fdc71706adcb883d22125637c54f6010b1 (diff) | |
| download | olio-uboot-2014.01-cf07a5baece0ecfc5284cfda8a4e68eaf92782f8.tar.xz olio-uboot-2014.01-cf07a5baece0ecfc5284cfda8a4e68eaf92782f8.zip | |
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>
| -rw-r--r-- | board/tqc/tqm85xx/sdram.c | 116 | 
1 files changed, 108 insertions, 8 deletions
| diff --git a/board/tqc/tqm85xx/sdram.c b/board/tqc/tqm85xx/sdram.c index 69015ec5b..2b3de4499 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: |