summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2010-07-30 14:32:58 -0700
committerGary King <gking@nvidia.com>2010-08-03 09:43:36 -0700
commit6db49fce8ae4093b5b3ee3f652ca6630930b9df5 (patch)
tree1e57233e55b49e90865bab87998f3ccc895c1efa
parentf8118de93735b6b957437c548e2f025b25237ffc (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/Kconfig5
-rw-r--r--arch/arm/mach-tegra/common.c7
-rw-r--r--arch/arm/mach-tegra/cortex-a9.S9
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)
/*