ARM: 7091/1: errata: D-cache line maintenance operation by MVA may not succeed
authorWill Deacon <will.deacon@arm.com>
Thu, 15 Sep 2011 10:45:15 +0000 (11:45 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 3 Oct 2011 18:41:06 +0000 (11:41 -0700)
commit f630c1bdfbf8fe423325beaf60027cfc7fd7c610 upstream.

This patch implements a workaround for erratum 764369 affecting
Cortex-A9 MPCore with two or more processors (all current revisions).
Under certain timing circumstances, a data cache line maintenance
operation by MVA targeting an Inner Shareable memory region may fail to
proceed up to either the Point of Coherency or to the Point of
Unification of the system. This workaround adds a DSB instruction before
the relevant cache maintenance functions and sets a specific bit in the
diagnostic control register of the SCU.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/arm/Kconfig
arch/arm/kernel/smp_scu.c
arch/arm/mm/cache-v7.S

index 9adc278..91c84cb 100644 (file)
@@ -1298,6 +1298,20 @@ source "drivers/pci/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
+config ARM_ERRATA_764369
+       bool "ARM errata: Data cache line maintenance operation by MVA may not succeed"
+       depends on CPU_V7 && SMP
+       help
+         This option enables the workaround for erratum 764369
+         affecting Cortex-A9 MPCore with two or more processors (all
+         current revisions). Under certain timing circumstances, a data
+         cache line maintenance operation by MVA targeting an Inner
+         Shareable memory region may fail to proceed up to either the
+         Point of Coherency or to the Point of Unification of the
+         system. This workaround adds a DSB instruction before the
+         relevant cache maintenance functions and sets a specific bit
+         in the diagnostic control register of the SCU.
+
 endmenu
 
 menu "Kernel Features"
index a1e757c..cb7dd40 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/smp_scu.h>
 #include <asm/cacheflush.h>
+#include <asm/cputype.h>
 
 #define SCU_CTRL               0x00
 #define SCU_CONFIG             0x04
@@ -36,6 +37,15 @@ void __init scu_enable(void __iomem *scu_base)
 {
        u32 scu_ctrl;
 
+#ifdef CONFIG_ARM_ERRATA_764369
+       /* Cortex-A9 only */
+       if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) {
+               scu_ctrl = __raw_readl(scu_base + 0x30);
+               if (!(scu_ctrl & 1))
+                       __raw_writel(scu_ctrl | 0x1, scu_base + 0x30);
+       }
+#endif
+
        scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
        /* already enabled? */
        if (scu_ctrl & 1)
index d32f02b..3593119 100644 (file)
@@ -174,6 +174,10 @@ ENTRY(v7_coherent_user_range)
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r12, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+       ALT_SMP(W(dsb))
+       ALT_UP(W(nop))
+#endif
 1:
  USER( mcr     p15, 0, r12, c7, c11, 1 )       @ clean D line to the point of unification
        add     r12, r12, r2
@@ -223,6 +227,10 @@ ENTRY(v7_flush_kern_dcache_area)
        add     r1, r0, r1
        sub     r3, r2, #1
        bic     r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+       ALT_SMP(W(dsb))
+       ALT_UP(W(nop))
+#endif
 1:
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line / unified line
        add     r0, r0, r2
@@ -247,6 +255,10 @@ v7_dma_inv_range:
        sub     r3, r2, #1
        tst     r0, r3
        bic     r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+       ALT_SMP(W(dsb))
+       ALT_UP(W(nop))
+#endif
        mcrne   p15, 0, r0, c7, c14, 1          @ clean & invalidate D / U line
 
        tst     r1, r3
@@ -270,6 +282,10 @@ v7_dma_clean_range:
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+       ALT_SMP(W(dsb))
+       ALT_UP(W(nop))
+#endif
 1:
        mcr     p15, 0, r0, c7, c10, 1          @ clean D / U line
        add     r0, r0, r2
@@ -288,6 +304,10 @@ ENTRY(v7_dma_flush_range)
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+       ALT_SMP(W(dsb))
+       ALT_UP(W(nop))
+#endif
 1:
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D / U line
        add     r0, r0, r2