diff options
author | Scott Williams <scwilliams@nvidia.com> | 2010-07-30 14:32:58 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-08-03 09:43:36 -0700 |
commit | 6db49fce8ae4093b5b3ee3f652ca6630930b9df5 (patch) | |
tree | 1e57233e55b49e90865bab87998f3ccc895c1efa | |
parent | f8118de93735b6b957437c548e2f025b25237ffc (diff) |
[arm/tegra] Workaround for ARM erratum 742230
Description summary
Under rare circumstances, a DMB instruction between 2 write
operations may not ensure the correct visibility ordering
of the 2 writes.
Implication summary
This erratum is more likely to be exhibited by code taking/releasing
a semaphore. The implication of the erratum is that an external agent
may observe the release of the semaphore before the new payload is
visible, meaning that it can access an out-of-date value for the
payload data.
Workaround summary
A software workaround is available, which consists in setting bit [4]
in the undocumented Diagnostic register. This bit (“Disable DMB-lite”)
causes the DMB to behave as a DSB, ensuring the correct ordering of
the 2 writes.
Requires Cortex-A9 MPCore config with 2 or more CPUs
Present in r1p0 / r1p1 / r1p2 and r2p0 / r2p1 / r2p2
Bug 716466
Change-Id: Idabd534c383d157cdcdbb6e1d79e7bab77e0a36e
Reviewed-on: http://git-master/r/4614
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Tested-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cortex-a9.S | 9 |
3 files changed, 17 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index cfc54a2261b1..89b0424d239f 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -10,6 +10,7 @@ config ARCH_TEGRA_2x_SOC select CPU_V7 select ARM_GIC select ARCH_REQUIRE_GPIOLIB + select ARM_ERRATA_742230 help Support for NVIDIA Tegra AP20 and T20 processors, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller @@ -41,6 +42,10 @@ config MACH_VENTANA config TEGRA_ODM_KIT bool +config ARM_ERRATA_742230 + bool + depends on CPU_V7 + choice prompt "Low-level debug console UART" default TEGRA_DEBUG_UART_NONE diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index d6bee1d29bdf..a1bc52ddce0d 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -77,8 +77,13 @@ void __init tegra_init_cache(void) void __init tegra_common_init(void) { #ifdef CONFIG_CPU_V7 - /* enable dynamic clock gating */ unsigned int reg; +#ifdef CONFIG_ARM_ERRATA_742230 + asm volatile ("mrc p15, 0, %0, c15, c0, 1" : "=r" (reg) : : "cc"); + reg |= 1<<4; + asm volatile ("mcr p15, 0, %0, c15, c0, 1" : : "r" (reg) : "cc"); +#endif + /* enable dynamic clock gating */ asm volatile ("mrc p15, 0, %0, c15, c0, 0" : "=r" (reg) : : "cc"); reg |= 1; asm volatile ("mcr p15, 0, %0, c15, c0, 0" : : "r" (reg) : "cc"); diff --git a/arch/arm/mach-tegra/cortex-a9.S b/arch/arm/mach-tegra/cortex-a9.S index 9a3893f94d68..9edabaa60c7d 100644 --- a/arch/arm/mach-tegra/cortex-a9.S +++ b/arch/arm/mach-tegra/cortex-a9.S @@ -612,6 +612,11 @@ ENDPROC(__invalidate_l1) */ ENTRY(__invalidate_cpu_state) clrex +#ifdef CONFIG_ARM_ERRATA_742230 + mrc p15, 0, r0, c15, c0, 1 + orr r0, r0, #(1<<4) + mcr p15, 0, r0, c15, c0, 1 +#endif mov r0, #0 mcr p15, 0, r0, c1, c0, 1 @ disable SMP, prefetch, broadcast isb @@ -633,9 +638,7 @@ ENTRY(__invalidate_cpu_state) mov r0, #0x1800 mcr p15, 0, r0, c1, c0, 0 @ enable branch prediction, i-cache isb - mov r10, lr @ preserve lr of caller - bl __invalidate_l1 @ invalidate data cache - bx r10 @ return + b __invalidate_l1 @ invalidate data cache ENDPROC(__invalidate_cpu_state) /* |