aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2011-09-15 06:45:15 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-09-17 07:47:17 -0400
commitf630c1bdfbf8fe423325beaf60027cfc7fd7c610 (patch)
tree9091179ae505fcb5aff937315c4f9c96602cba9a /arch
parent279b1e0fd90ef63c7acb34a5ca573f065a6fefb4 (diff)
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: 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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig14
-rw-r--r--arch/arm/kernel/smp_scu.c10
-rw-r--r--arch/arm/mm/cache-v7.S20
3 files changed, 44 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3269576dbfa8..3146ed3f6eca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1283,6 +1283,20 @@ config ARM_ERRATA_364296
1283 processor into full low interrupt latency mode. ARM11MPCore 1283 processor into full low interrupt latency mode. ARM11MPCore
1284 is not affected. 1284 is not affected.
1285 1285
1286config ARM_ERRATA_764369
1287 bool "ARM errata: Data cache line maintenance operation by MVA may not succeed"
1288 depends on CPU_V7 && SMP
1289 help
1290 This option enables the workaround for erratum 764369
1291 affecting Cortex-A9 MPCore with two or more processors (all
1292 current revisions). Under certain timing circumstances, a data
1293 cache line maintenance operation by MVA targeting an Inner
1294 Shareable memory region may fail to proceed up to either the
1295 Point of Coherency or to the Point of Unification of the
1296 system. This workaround adds a DSB instruction before the
1297 relevant cache maintenance functions and sets a specific bit
1298 in the diagnostic control register of the SCU.
1299
1286endmenu 1300endmenu
1287 1301
1288source "arch/arm/common/Kconfig" 1302source "arch/arm/common/Kconfig"
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 79ed5e7f204a..7fcddb75c877 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -13,6 +13,7 @@
13 13
14#include <asm/smp_scu.h> 14#include <asm/smp_scu.h>
15#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
16#include <asm/cputype.h>
16 17
17#define SCU_CTRL 0x00 18#define SCU_CTRL 0x00
18#define SCU_CONFIG 0x04 19#define SCU_CONFIG 0x04
@@ -37,6 +38,15 @@ void __init scu_enable(void __iomem *scu_base)
37{ 38{
38 u32 scu_ctrl; 39 u32 scu_ctrl;
39 40
41#ifdef CONFIG_ARM_ERRATA_764369
42 /* Cortex-A9 only */
43 if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) {
44 scu_ctrl = __raw_readl(scu_base + 0x30);
45 if (!(scu_ctrl & 1))
46 __raw_writel(scu_ctrl | 0x1, scu_base + 0x30);
47 }
48#endif
49
40 scu_ctrl = __raw_readl(scu_base + SCU_CTRL); 50 scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
41 /* already enabled? */ 51 /* already enabled? */
42 if (scu_ctrl & 1) 52 if (scu_ctrl & 1)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 3b24bfa3b828..07c4bc8ea0a4 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -174,6 +174,10 @@ ENTRY(v7_coherent_user_range)
174 dcache_line_size r2, r3 174 dcache_line_size r2, r3
175 sub r3, r2, #1 175 sub r3, r2, #1
176 bic r12, r0, r3 176 bic r12, r0, r3
177#ifdef CONFIG_ARM_ERRATA_764369
178 ALT_SMP(W(dsb))
179 ALT_UP(W(nop))
180#endif
1771: 1811:
178 USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification 182 USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification
179 add r12, r12, r2 183 add r12, r12, r2
@@ -223,6 +227,10 @@ ENTRY(v7_flush_kern_dcache_area)
223 add r1, r0, r1 227 add r1, r0, r1
224 sub r3, r2, #1 228 sub r3, r2, #1
225 bic r0, r0, r3 229 bic r0, r0, r3
230#ifdef CONFIG_ARM_ERRATA_764369
231 ALT_SMP(W(dsb))
232 ALT_UP(W(nop))
233#endif
2261: 2341:
227 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line 235 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line
228 add r0, r0, r2 236 add r0, r0, r2
@@ -247,6 +255,10 @@ v7_dma_inv_range:
247 sub r3, r2, #1 255 sub r3, r2, #1
248 tst r0, r3 256 tst r0, r3
249 bic r0, r0, r3 257 bic r0, r0, r3
258#ifdef CONFIG_ARM_ERRATA_764369
259 ALT_SMP(W(dsb))
260 ALT_UP(W(nop))
261#endif
250 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line 262 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
251 263
252 tst r1, r3 264 tst r1, r3
@@ -270,6 +282,10 @@ v7_dma_clean_range:
270 dcache_line_size r2, r3 282 dcache_line_size r2, r3
271 sub r3, r2, #1 283 sub r3, r2, #1
272 bic r0, r0, r3 284 bic r0, r0, r3
285#ifdef CONFIG_ARM_ERRATA_764369
286 ALT_SMP(W(dsb))
287 ALT_UP(W(nop))
288#endif
2731: 2891:
274 mcr p15, 0, r0, c7, c10, 1 @ clean D / U line 290 mcr p15, 0, r0, c7, c10, 1 @ clean D / U line
275 add r0, r0, r2 291 add r0, r0, r2
@@ -288,6 +304,10 @@ ENTRY(v7_dma_flush_range)
288 dcache_line_size r2, r3 304 dcache_line_size r2, r3
289 sub r3, r2, #1 305 sub r3, r2, #1
290 bic r0, r0, r3 306 bic r0, r0, r3
307#ifdef CONFIG_ARM_ERRATA_764369
308 ALT_SMP(W(dsb))
309 ALT_UP(W(nop))
310#endif
2911: 3111:
292 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line 312 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
293 add r0, r0, r2 313 add r0, r0, r2