Commit f630c1bd authored by Will Deacon's avatar Will Deacon Committed by Russell King

ARM: 7091/1: errata: D-cache line maintenance operation by MVA may not succeed

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.

Cc: <stable@kernel.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 279b1e0f
...@@ -1283,6 +1283,20 @@ config ARM_ERRATA_364296 ...@@ -1283,6 +1283,20 @@ config ARM_ERRATA_364296
processor into full low interrupt latency mode. ARM11MPCore processor into full low interrupt latency mode. ARM11MPCore
is not affected. is not affected.
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 endmenu
source "arch/arm/common/Kconfig" source "arch/arm/common/Kconfig"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cputype.h>
#define SCU_CTRL 0x00 #define SCU_CTRL 0x00
#define SCU_CONFIG 0x04 #define SCU_CONFIG 0x04
...@@ -37,6 +38,15 @@ void __init scu_enable(void __iomem *scu_base) ...@@ -37,6 +38,15 @@ void __init scu_enable(void __iomem *scu_base)
{ {
u32 scu_ctrl; 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); scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
/* already enabled? */ /* already enabled? */
if (scu_ctrl & 1) if (scu_ctrl & 1)
......
...@@ -174,6 +174,10 @@ ENTRY(v7_coherent_user_range) ...@@ -174,6 +174,10 @@ ENTRY(v7_coherent_user_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
bic r12, r0, r3 bic r12, r0, r3
#ifdef CONFIG_ARM_ERRATA_764369
ALT_SMP(W(dsb))
ALT_UP(W(nop))
#endif
1: 1:
USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification
add r12, r12, r2 add r12, r12, r2
...@@ -223,6 +227,10 @@ ENTRY(v7_flush_kern_dcache_area) ...@@ -223,6 +227,10 @@ ENTRY(v7_flush_kern_dcache_area)
add r1, r0, r1 add r1, r0, r1
sub r3, r2, #1 sub r3, r2, #1
bic r0, r0, r3 bic r0, r0, r3
#ifdef CONFIG_ARM_ERRATA_764369
ALT_SMP(W(dsb))
ALT_UP(W(nop))
#endif
1: 1:
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line
add r0, r0, r2 add r0, r0, r2
...@@ -247,6 +255,10 @@ v7_dma_inv_range: ...@@ -247,6 +255,10 @@ v7_dma_inv_range:
sub r3, r2, #1 sub r3, r2, #1
tst r0, r3 tst r0, r3
bic r0, 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 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
tst r1, r3 tst r1, r3
...@@ -270,6 +282,10 @@ v7_dma_clean_range: ...@@ -270,6 +282,10 @@ v7_dma_clean_range:
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
bic r0, r0, r3 bic r0, r0, r3
#ifdef CONFIG_ARM_ERRATA_764369
ALT_SMP(W(dsb))
ALT_UP(W(nop))
#endif
1: 1:
mcr p15, 0, r0, c7, c10, 1 @ clean D / U line mcr p15, 0, r0, c7, c10, 1 @ clean D / U line
add r0, r0, r2 add r0, r0, r2
...@@ -288,6 +304,10 @@ ENTRY(v7_dma_flush_range) ...@@ -288,6 +304,10 @@ ENTRY(v7_dma_flush_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
bic r0, r0, r3 bic r0, r0, r3
#ifdef CONFIG_ARM_ERRATA_764369
ALT_SMP(W(dsb))
ALT_UP(W(nop))
#endif
1: 1:
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
add r0, r0, r2 add r0, r0, r2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment