diff mbox

[U-Boot,v2] powerpc/mpc85xx: Make NMG_CPU_A011 workaround conditional

Message ID 1344485093-30572-1-git-send-email-yorksun@freescale.com
State Accepted, archived
Delegated to: Andy Fleming
Headers show

Commit Message

York Sun Aug. 9, 2012, 4:04 a.m. UTC
This erratum applies to the following SoCs:
P4080 rev 1.0, 2.0, fixed in rev 3.0
P2041 rev 1.0, 1.1, fixed in rev 2.0
P3041 rev 1.0, 1.1, fixed in rev 2.0.

Workaround for erratum NMG_CPU_A011 is enabled by default. This workaround
may degrade performance. P4080 erratum CPU22 shares the same workaround.
So it is always enabled for P4080. For other SoCs, it can be disabled by
hwconfig with syntax:

fsl_cpu_a011:disable

Signed-off-by: York Sun <yorksun@freescale.com>
---
Change since v1:
 Merged with patch "Change NMG_CPU_A011 workaround condition"
 Merged with patch "Enable workaround for erratum CPU_A011 for P3041"
 Added hwconfig variable length check

 arch/powerpc/cpu/mpc85xx/cmd_errata.c     |    6 ++++-
 arch/powerpc/cpu/mpc85xx/cpu_init.c       |   37 +++++++++++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/release.S        |   15 +++++++++++
 arch/powerpc/include/asm/config_mpc85xx.h |    1 +
 4 files changed, 56 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index 4e1a54a..858b3f8 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -27,6 +27,9 @@ 
 
 static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+	extern int enable_cpu_a011_workaround;
+#endif
 	__maybe_unused u32 svr = get_svr();
 
 #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
@@ -56,8 +59,9 @@  static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	/*
 	 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
 	 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1
+	 * The SVR has been checked by cpu_init_r().
 	 */
-	if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3)
+	if (enable_cpu_a011_workaround)
 		puts("Work-around for Erratum CPU-A011 enabled\n");
 #endif
 #if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index fc6c287..74863b4 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -38,6 +38,7 @@ 
 #include <asm/fsl_law.h>
 #include <asm/fsl_serdes.h>
 #include <asm/fsl_srio.h>
+#include <hwconfig.h>
 #include <linux/compiler.h>
 #include "mp.h"
 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
@@ -47,6 +48,8 @@ 
 
 #include "../../../../drivers/block/fsl_sata.h"
 
+#define HWCONFIG_BUFFER_SIZE 128
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_QE
@@ -311,11 +314,41 @@  int cpu_init_r(void)
 #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
 	defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
 	/*
+	 * CPU22 and NMG_CPU_A011 share the same workaround.
 	 * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0
 	 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
-	 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1
+	 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both
+	 * fixed in 2.0. NMG_CPU_A011 is activated by default and can
+	 * be disabled by hwconfig with syntax:
+	 *
+	 * fsl_cpu_a011:disable
 	 */
-	if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) {
+	extern int enable_cpu_a011_workaround;
+#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22
+	enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3);
+#else
+	char buffer[HWCONFIG_BUFFER_SIZE];
+	char *buf = NULL;
+	int n, res;
+
+	n = getenv_f("hwconfig", buffer, sizeof(buffer));
+	if (n > 0)
+		buf = buffer;
+
+	res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf);
+	if (res > 0)
+		enable_cpu_a011_workaround = 0;
+	else {
+		if (n >= HWCONFIG_BUFFER_SIZE) {
+			printf("fsl_cpu_a011 was not found. hwconfig variable "
+				"may be too long\n");
+		}
+		enable_cpu_a011_workaround =
+			(SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) ||
+			(SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2);
+	}
+#endif
+	if (enable_cpu_a011_workaround) {
 		flush_dcache();
 		mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS));
 		sync();
diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S
index 1860684..1555a9b 100644
--- a/arch/powerpc/cpu/mpc85xx/release.S
+++ b/arch/powerpc/cpu/mpc85xx/release.S
@@ -163,6 +163,12 @@  __secondary_start_page:
 	cmpw    r3,r5
 	bge     2f
 1:
+#ifdef	CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+	lis	r3,toreset(enable_cpu_a011_workaround)@ha
+	lwz	r3,toreset(enable_cpu_a011_workaround)@l(r3)
+	cmpwi	r3,0
+	beq	2f
+#endif
 	mfspr	r3,L1CSR2
 	oris	r3,r3,(L1CSR2_DCWS)@h
 	mtspr	L1CSR2,r3
@@ -346,6 +352,15 @@  __bootpg_addr:
 __spin_table:
 	.space CONFIG_MAX_CPUS*ENTRY_SIZE
 
+	/*
+	 * This variable is set by cpu_init_r() after parsing hwconfig
+	 * to enable workaround for erratum NMG_CPU_A011.
+	 */
+	.align L1_CACHE_SHIFT
+	.global enable_cpu_a011_workaround
+enable_cpu_a011_workaround:
+	.long	1
+
 	/* Fill in the empty space.  The actual reset vector is
 	 * the last word of the page */
 __secondary_start_code_end:
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index b6c44bb..7e61f71 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -399,6 +399,7 @@ 
 #define CONFIG_SYS_FSL_USB2_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2