From 0d3972cfcd6dff18d110d2ee01ad99e3623bfd45 Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Wed, 6 Jan 2016 11:26:51 +0800 Subject: fsl/ddr: Add workaround for ERRATUM_A009942 During the receive data training, the DDRC may complete on a non-optimal setting that could lead to data corruption or initialization failure. Workaround: before setting MEM_EN, set DEBUG_29 register with specific value for different data rates. Signed-off-by: Shengzhou Liu Reviewed-by: York Sun --- arch/arm/include/asm/arch-fsl-layerscape/config.h | 1 + drivers/ddr/fsl/fsl_ddr_gen4.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 49b113d..83a207c 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -118,6 +118,7 @@ #define CONFIG_SYS_FSL_ERRATUM_A008585 #define CONFIG_SYS_FSL_ERRATUM_A008751 #define CONFIG_SYS_FSL_ERRATUM_A009635 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #elif defined(CONFIG_LS1043A) #define CONFIG_MAX_CPUS 4 #define CONFIG_SYS_CACHELINE_SIZE 64 diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 3fca5c2..0d9dd0b 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -55,6 +55,10 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 vref_seq2[3] = {0xc0, 0xf0, 0x70}; /* for range 2 */ u32 *vref_seq = vref_seq1; #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A009942 + ulong ddr_freq; + u32 tmp; +#endif #ifdef CONFIG_FSL_DDR_BIST u32 mtcr, err_detect, err_sbe; u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config; @@ -227,6 +231,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->debug[25], 0x9000); } #endif + +#ifdef CONFIG_SYS_FSL_ERRATUM_A009942 + ddr_freq = get_ddr_freq(ctrl_num) / 1000000; + tmp = ddr_in32(&ddr->debug[28]); + if (ddr_freq <= 1333) + ddr_out32(&ddr->debug[28], tmp | 0x0080006a); + else if (ddr_freq <= 1600) + ddr_out32(&ddr->debug[28], tmp | 0x0070006f); + else if (ddr_freq <= 1867) + ddr_out32(&ddr->debug[28], tmp | 0x00700076); + else if (ddr_freq <= 2133) + ddr_out32(&ddr->debug[28], tmp | 0x0060007b); +#endif + /* * For RDIMMs, JEDEC spec requires clocks to be stable before reset is * deasserted. Clocks start when any chip select is enabled and clock -- cgit v1.1