From 9955b4ab0187e0e9faac57acc01ebe7714d0ec23 Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:47 -0800 Subject: driver/ddr/fsl: Add workaround for A008336 Erratum A008336 requires setting EDDRTQCR1[2] in DDRC DCSR space for 64-bit DDR controllers. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/ddr/fsl/fsl_ddr_gen4.c') diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 4eef047343..5c2579ed61 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -32,24 +32,39 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 temp_sdram_cfg; u32 total_gb_size_per_controller; int timeout; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 + u32 *eddrtqcr1; +#endif switch (ctrl_num) { case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; +#endif break; #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800; +#endif break; #endif #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800; +#endif break; #endif #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 + eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800; +#endif break; #endif default: @@ -60,6 +75,13 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, if (step == 2) goto step2; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#ifdef CONFIG_LS2085A + /* A008336 only applies to general DDR controllers */ + if ((ctrl_num == 0) || (ctrl_num == 1)) +#endif + ddr_out32(eddrtqcr1, 0x63b30002); +#endif if (regs->ddr_eor) ddr_out32(&ddr->eor, regs->ddr_eor); -- cgit v1.2.1 From 49fd1f3f265efc00d61effa995bd6a733bf273d8 Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:48 -0800 Subject: driver/ddr/fsl: Add workround for erratumn A008514 Erratum A008514 workround requires writing register eddrtqcr1 with value 0x63b20002. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/ddr/fsl/fsl_ddr_gen4.c') diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 5c2579ed61..9cca4a06dd 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -32,21 +32,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 temp_sdram_cfg; u32 total_gb_size_per_controller; int timeout; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008514) u32 *eddrtqcr1; #endif switch (ctrl_num) { case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008514) eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; #endif break; #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008514) eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800; #endif break; @@ -54,7 +57,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008514) eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800; #endif break; @@ -62,7 +66,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008514) eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800; #endif break; @@ -81,6 +86,13 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, if ((ctrl_num == 0) || (ctrl_num == 1)) #endif ddr_out32(eddrtqcr1, 0x63b30002); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A008514 +#ifdef CONFIG_LS2085A + /* A008514 only applies to DP-DDR controler */ + if (ctrl_num == 2) +#endif + ddr_out32(eddrtqcr1, 0x63b20002); #endif if (regs->ddr_eor) ddr_out32(&ddr->eor, regs->ddr_eor); -- cgit v1.2.1 From 03e664d8f4065010ccb6c75648192200a832fd8b Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:50 -0800 Subject: driver/ddr/fsl: Add support for multiple DDR clocks Controller number is passed for function calls to support individual DDR clock, depending on SoC implementation. It is backward compatible with exising platforms. Multiple clocks have been verifyed on LS2085A emulator. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ddr/fsl/fsl_ddr_gen4.c') diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 9cca4a06dd..d9fce7d2f3 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -287,7 +287,7 @@ step2: bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / - (get_ddr_freq(0) >> 20)) << 2; + (get_ddr_freq(ctrl_num) >> 20)) << 2; total_gb_size_per_controller >>= 4; /* shift down to gb size */ debug("total %d GB\n", total_gb_size_per_controller); debug("Need to wait up to %d * 10ms\n", timeout); -- cgit v1.2.1