]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
ARM: Introduce erratum workaround for 798870
authorNishanth Menon <nm@ti.com>
Mon, 9 Mar 2015 22:11:59 +0000 (17:11 -0500)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 1 Sep 2015 12:31:00 +0000 (14:31 +0200)
Add workaround for Cortex-A15 ARM erratum 798870 which says
"If back-to-back speculative cache line fills (fill A and fill B) are
issued from the L1 data cache of a CPU to the L2 cache, the second
request (fill B) is then cancelled, and the second request would have
detected a hazard against a recent write or eviction (write B) to the
same cache line as fill B then the L2 logic might deadlock."

Implementations for SoC families such as Exynos, OMAP5/DRA7 etc
will be widely different.

Every SoC has slightly different manner of setting up access to L2ACLR
and similar registers since the Secure Monitor handling of Secure
Monitor Call(smc) is diverse. Hence an weak function is introduced
which may be overriden to implement SoC specific accessor implementation.

Based on ARM errata Document revision 18.0 (22 Nov 2013)

Signed-off-by: Nishanth Menon <nm@ti.com>
Tested-by: Matt Porter <mporter@konsulko.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
README
arch/arm/cpu/armv7/Makefile
arch/arm/cpu/armv7/cp15.c [new file with mode: 0644]
arch/arm/cpu/armv7/start.S
arch/arm/include/asm/armv7.h

diff --git a/README b/README
index 15f1a5d5368e80d3394f6fb398b12967523e1871..beb063c7c72cd8875fd1d603330a6a90773565c4 100644 (file)
--- a/README
+++ b/README
@@ -690,6 +690,11 @@ The following options need to be configured:
                exists, unlike the similar options in the Linux kernel. Do not
                set these options unless they apply!
 
+               NOTE: The following can be machine specific errata. These
+               do have ability to provide rudimentary version and machine
+               specific checks, but expect no product checks.
+               CONFIG_ARM_ERRATA_798870
+
 - Tegra SoC options:
                CONFIG_TEGRA_SUPPORT_NON_SECURE
 
index 50d3495a0e48306b1e8f276bf0792f3a6d1de05e..0857f6c518947b383199c84b36981eef6a704901 100644 (file)
@@ -9,7 +9,7 @@ extra-y := start.o
 
 obj-y  += cache_v7.o
 
-obj-y  += cpu.o
+obj-y  += cpu.o cp15.o
 obj-y  += syslib.o
 
 ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_SOC_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),)
diff --git a/arch/arm/cpu/armv7/cp15.c b/arch/arm/cpu/armv7/cp15.c
new file mode 100644 (file)
index 0000000..8ac81c9
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2015 Texas Insturments
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/*
+ * CP15 specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/armv7.h>
+#include <linux/compiler.h>
+
+void __weak v7_arch_cp15_set_l2aux_ctrl(u32 l2actlr, u32 cpu_midr,
+                                    u32 cpu_rev_comb, u32 cpu_variant,
+                                    u32 cpu_rev)
+{
+       asm volatile ("mcr p15, 1, %0, c15, c0, 0\n\t" : : "r"(l2actlr));
+}
index 9b49ece2d650e199a1ed3415ed2ae47794f20fab..89637e26395d86944bc06a1a2cf3a9a8217d4620 100644 (file)
@@ -166,7 +166,30 @@ ENTRY(cpu_init_cp15)
        mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
 #endif
 
-       mov     pc, lr                  @ back to my caller
+       mov     r5, lr                  @ Store my Caller
+       mrc     p15, 0, r1, c0, c0, 0   @ r1 has Read Main ID Register (MIDR)
+       mov     r3, r1, lsr #20         @ get variant field
+       and     r3, r3, #0xf            @ r3 has CPU variant
+       and     r4, r1, #0xf            @ r4 has CPU revision
+       mov     r2, r3, lsl #4          @ shift variant field for combined value
+       orr     r2, r4, r2              @ r2 has combined CPU variant + revision
+
+#ifdef CONFIG_ARM_ERRATA_798870
+       cmp     r2, #0x30               @ Applies to lower than R3p0
+       bge     skip_errata_798870      @ skip if not affected rev
+       cmp     r2, #0x20               @ Applies to including and above R2p0
+       blt     skip_errata_798870      @ skip if not affected rev
+
+       mrc     p15, 1, r0, c15, c0, 0  @ read l2 aux ctrl reg
+       orr     r0, r0, #1 << 7         @ Enable hazard-detect timeout
+       push    {r1-r5}                 @ Save the cpu info registers
+       bl      v7_arch_cp15_set_l2aux_ctrl
+       isb                             @ Recommended ISB after l2actlr update
+       pop     {r1-r5}                 @ Restore the cpu info - fall through
+skip_errata_798870:
+#endif
+
+       mov     pc, r5                  @ back to my caller
 ENDPROC(cpu_init_cp15)
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
index c3cc5088ead885fc609874c3008d7e58d4492764..cd4091208c4565f79b2ccad64443366a33cbe47a 100644 (file)
@@ -137,6 +137,9 @@ extern char __secure_end[];
 
 #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */
 
+void v7_arch_cp15_set_l2aux_ctrl(u32 l2auxctrl, u32 cpu_midr,
+                                u32 cpu_rev_comb, u32 cpu_variant,
+                                u32 cpu_rev);
 #endif /* ! __ASSEMBLY__ */
 
 #endif