Patchwork [U-Boot,08/10] Implement workaround for erratum DDRA003

login
register
mail settings
Submitter York Sun
Date Dec. 9, 2010, 2:55 a.m.
Message ID <1291863340-4354-8-git-send-email-yorksun@freescale.com>
Download mbox | patch
Permalink /patch/74841/
State Changes Requested
Delegated to: Kumar Gala
Headers show

Comments

York Sun - Dec. 9, 2010, 2:55 a.m.
Erratum DDRA003 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>
---
 arch/powerpc/cpu/mpc85xx/ddr-gen3.c |   53 ++++++++++++++++++++++++++++++++++-
 include/configs/P4080DS.h           |    1 +
 2 files changed, 53 insertions(+), 1 deletions(-)
Kumar Gala - Dec. 14, 2010, 6:47 a.m.
On Dec 8, 2010, at 8:55 PM, York Sun wrote:

> Erratum DDRA003 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>
> ---
> arch/powerpc/cpu/mpc85xx/ddr-gen3.c |   53 ++++++++++++++++++++++++++++++++++-
> include/configs/P4080DS.h           |    1 +
> 2 files changed, 53 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
> index 568f9f4..0815ba4 100644
> --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
> +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
> @@ -108,6 +108,55 @@ 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_P4080_ERRATUM_DDRA003

Name this:

#ifdef CONFIG_SYS_FSL_NMG_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, 0xc4080002);
> +			break;
> +		case 0x00100000:
> +			out_be32(&ddr->sdram_md_cntl, 0xc408000a);
> +			break;
> +		case 0x00200000:
> +			out_be32(&ddr->sdram_md_cntl, 0xc4080012);
> +			break;
> +		case 0x00300000:
> +			out_be32(&ddr->sdram_md_cntl, 0xc408001a);
> +			break;
> +		default:
> +			out_be32(&ddr->sdram_md_cntl, 0xc4080002);
> +			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,
> @@ -131,8 +180,10 @@ 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) {
> diff --git a/include/configs/P4080DS.h b/include/configs/P4080DS.h
> index d210016..c19bd39 100644
> --- a/include/configs/P4080DS.h
> +++ b/include/configs/P4080DS.h
> @@ -45,6 +45,7 @@
> #define CONFIG_SYS_P4080_ERRATUM_CPC9
> #define CONFIG_SYS_P4080_ERRATUM_DDR1
> #define CONFIG_SYS_P4080_ERRATUM_DDR7
> +#define CONFIG_SYS_P4080_ERRATUM_DDRA003
> #define CONFIG_SYS_P4080_ERRATUM_ESDHC1
> #define CONFIG_SYS_P4080_ERRATUM_ESDHC9
> #define CONFIG_SYS_P4080_ERRATUM_ESDHC11
> -- 
> 1.7.0.4

You need to update arch/powerpc/cpu/mpc85xx/cmd_errata.c

- k

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index 568f9f4..0815ba4 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -108,6 +108,55 @@  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_P4080_ERRATUM_DDRA003
+	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, 0xc4080002);
+			break;
+		case 0x00100000:
+			out_be32(&ddr->sdram_md_cntl, 0xc408000a);
+			break;
+		case 0x00200000:
+			out_be32(&ddr->sdram_md_cntl, 0xc4080012);
+			break;
+		case 0x00300000:
+			out_be32(&ddr->sdram_md_cntl, 0xc408001a);
+			break;
+		default:
+			out_be32(&ddr->sdram_md_cntl, 0xc4080002);
+			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,
@@ -131,8 +180,10 @@  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) {
diff --git a/include/configs/P4080DS.h b/include/configs/P4080DS.h
index d210016..c19bd39 100644
--- a/include/configs/P4080DS.h
+++ b/include/configs/P4080DS.h
@@ -45,6 +45,7 @@ 
 #define CONFIG_SYS_P4080_ERRATUM_CPC9
 #define CONFIG_SYS_P4080_ERRATUM_DDR1
 #define CONFIG_SYS_P4080_ERRATUM_DDR7
+#define CONFIG_SYS_P4080_ERRATUM_DDRA003
 #define CONFIG_SYS_P4080_ERRATUM_ESDHC1
 #define CONFIG_SYS_P4080_ERRATUM_ESDHC9
 #define CONFIG_SYS_P4080_ERRATUM_ESDHC11