Commit c616a0df297e886f09bf88523bcd03a86bdf8704

Authored by Nishanth Menon
Committed by Tom Rini
1 parent fb1bf40838

ARM: Introduce erratum workaround for 798870

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>

Showing 5 changed files with 56 additions and 2 deletions Side-by-side Diff

... ... @@ -690,6 +690,11 @@
690 690 exists, unlike the similar options in the Linux kernel. Do not
691 691 set these options unless they apply!
692 692  
  693 + NOTE: The following can be machine specific errata. These
  694 + do have ability to provide rudimentary version and machine
  695 + specific checks, but expect no product checks.
  696 + CONFIG_ARM_ERRATA_798870
  697 +
693 698 - Tegra SoC options:
694 699 CONFIG_TEGRA_SUPPORT_NON_SECURE
695 700  
arch/arm/cpu/armv7/Makefile
... ... @@ -9,7 +9,7 @@
9 9  
10 10 obj-y += cache_v7.o
11 11  
12   -obj-y += cpu.o
  12 +obj-y += cpu.o cp15.o
13 13 obj-y += syslib.o
14 14  
15 15 ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),)
arch/arm/cpu/armv7/cp15.c
  1 +/*
  2 + * (C) Copyright 2015 Texas Insturments
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +/*
  8 + * CP15 specific code
  9 + */
  10 +
  11 +#include <common.h>
  12 +#include <command.h>
  13 +#include <asm/system.h>
  14 +#include <asm/cache.h>
  15 +#include <asm/armv7.h>
  16 +#include <linux/compiler.h>
  17 +
  18 +void __weak v7_arch_cp15_set_l2aux_ctrl(u32 l2actlr, u32 cpu_midr,
  19 + u32 cpu_rev_comb, u32 cpu_variant,
  20 + u32 cpu_rev)
  21 +{
  22 + asm volatile ("mcr p15, 1, %0, c15, c0, 0\n\t" : : "r"(l2actlr));
  23 +}
arch/arm/cpu/armv7/start.S
... ... @@ -166,7 +166,30 @@
166 166 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
167 167 #endif
168 168  
169   - mov pc, lr @ back to my caller
  169 + mov r5, lr @ Store my Caller
  170 + mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
  171 + mov r3, r1, lsr #20 @ get variant field
  172 + and r3, r3, #0xf @ r3 has CPU variant
  173 + and r4, r1, #0xf @ r4 has CPU revision
  174 + mov r2, r3, lsl #4 @ shift variant field for combined value
  175 + orr r2, r4, r2 @ r2 has combined CPU variant + revision
  176 +
  177 +#ifdef CONFIG_ARM_ERRATA_798870
  178 + cmp r2, #0x30 @ Applies to lower than R3p0
  179 + bge skip_errata_798870 @ skip if not affected rev
  180 + cmp r2, #0x20 @ Applies to including and above R2p0
  181 + blt skip_errata_798870 @ skip if not affected rev
  182 +
  183 + mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
  184 + orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
  185 + push {r1-r5} @ Save the cpu info registers
  186 + bl v7_arch_cp15_set_l2aux_ctrl
  187 + isb @ Recommended ISB after l2actlr update
  188 + pop {r1-r5} @ Restore the cpu info - fall through
  189 +skip_errata_798870:
  190 +#endif
  191 +
  192 + mov pc, r5 @ back to my caller
170 193 ENDPROC(cpu_init_cp15)
171 194  
172 195 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
arch/arm/include/asm/armv7.h
... ... @@ -137,6 +137,9 @@
137 137  
138 138 #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */
139 139  
  140 +void v7_arch_cp15_set_l2aux_ctrl(u32 l2auxctrl, u32 cpu_midr,
  141 + u32 cpu_rev_comb, u32 cpu_variant,
  142 + u32 cpu_rev);
140 143 #endif /* ! __ASSEMBLY__ */
141 144  
142 145 #endif