Workaround for erratum NMG_CPU_A011 can be enabled by hwconfig with syntax

fsl_cpu_a011:enable

This workaround is not enabled by default. Enabling this workaround may
degrade performance. P4080 erratum CPU22 shares the same workaround. So it
is always enabled for P4080.

Signed-off-by: York Sun <york...@freescale.com>
---
 arch/powerpc/cpu/mpc85xx/cmd_errata.c |    6 +++++-
 arch/powerpc/cpu/mpc85xx/cpu_init.c   |   24 +++++++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/release.S    |   15 +++++++++++++++
 3 files changed, 43 insertions(+), 2 deletions(-)

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 4f03d25..10f142e 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,30 @@ 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
+        * NMG_CPU_A011 is activated by hwconfig with syntax:
+        * fsl_cpu_a011:enable
         */
-       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_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3);
+#else
+       char buffer[HWCONFIG_BUFFER_SIZE];
+       char *buf = NULL;
+
+       if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
+               buf = buffer;
+
+       if (hwconfig_arg_cmp_f("fsl_cpu_a011", "enable", buf) > 0) {
+               enable_cpu_a011_workaround =
+                       (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3);
+       }
+#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..b8d4a37 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   0
+
        /* Fill in the empty space.  The actual reset vector is
         * the last word of the page */
 __secondary_start_code_end:
-- 
1.7.0.4


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to