diff options
| author | York Sun <yorksun@freescale.com> | 2011-01-10 12:03:01 +0000 | 
|---|---|---|
| committer | Kumar Gala <galak@kernel.crashing.org> | 2011-01-19 22:58:24 -0600 | 
| commit | fa8d23c0ee5c66d5cda902ac6ea5b1dfc68d9712 (patch) | |
| tree | 2e34ca5a60bcaa2468b8989aadee1268aadef831 /arch/powerpc/cpu/mpc85xx/ddr-gen3.c | |
| parent | e1fd16b6f5e80d932c73f5a36141adfb35126e83 (diff) | |
| download | olio-uboot-2014.01-fa8d23c0ee5c66d5cda902ac6ea5b1dfc68d9712.tar.xz olio-uboot-2014.01-fa8d23c0ee5c66d5cda902ac6ea5b1dfc68d9712.zip | |
mpc85xx: Implement workaround for erratum DDR-A003
Erratum DDR-A003 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@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/ddr-gen3.c')
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 81 | 
1 files changed, 80 insertions, 1 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 9bc36f321..fa7e09f39 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -97,6 +97,82 @@ 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_FSL_ERRATUM_DDR_A003 +	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, +				MD_CNTL_MD_EN		| +				MD_CNTL_CS_SEL_CS0_CS1	| +				0x04000000		| +				MD_CNTL_WRCW		| +				MD_CNTL_MD_VALUE(0x02)); +			break; +		case 0x00100000: +			out_be32(&ddr->sdram_md_cntl, +				MD_CNTL_MD_EN		| +				MD_CNTL_CS_SEL_CS0_CS1	| +				0x04000000		| +				MD_CNTL_WRCW		| +				MD_CNTL_MD_VALUE(0x0a)); +			break; +		case 0x00200000: +			out_be32(&ddr->sdram_md_cntl, +				MD_CNTL_MD_EN		| +				MD_CNTL_CS_SEL_CS0_CS1	| +				0x04000000		| +				MD_CNTL_WRCW		| +				MD_CNTL_MD_VALUE(0x12)); +			break; +		case 0x00300000: +			out_be32(&ddr->sdram_md_cntl, +				MD_CNTL_MD_EN		| +				MD_CNTL_CS_SEL_CS0_CS1	| +				0x04000000		| +				MD_CNTL_WRCW		| +				MD_CNTL_MD_VALUE(0x1a)); +			break; +		default: +			out_be32(&ddr->sdram_md_cntl, +				MD_CNTL_MD_EN		| +				MD_CNTL_CS_SEL_CS0_CS1	| +				0x04000000		| +				MD_CNTL_WRCW		| +				MD_CNTL_MD_VALUE(0x02)); +			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, @@ -120,8 +196,11 @@ 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) { |