[PATCH] arm: Add Arm Erratum 773769 for Large data RAM latency.

From: Vivek Gautam
Date: Wed Jan 08 2014 - 08:29:40 EST


The erratum-773769 occurs on Arm Coretex-A15 (rev r2p0),
when L2 Data Ram latency is set to 4 cycles or more; or
when ACP is in use, or with L2 Data RAM slice configured.
Therefore, the effective latency as calculated in Table 7-2 of
Cotex-A15 (rev r2p0) trm should be 3 cycles or less.

On Exynos5250 based systems the effective data ram latency
is 4 cycles, since we have DATA_RAM_SETUP bit enabled (L2CTRL[5]=1b'1)
and DATA_RAM_LATENCY bits set to 0x2 (L2CTLR[2:0]=3b'010) therefore,
the effective L2 data RAM latency becomes 4 cycles.
So erratum '773769' occurs causing a corrupted L2 Cache.

This patch gives a workaround to the mentioned erratum, using below
mentioned algo:
----------------------------------------------------------------
if data RAM setup = 1
then check if effective latency i.e (latency + setup + 1) > 3
if 'true'
then clear data RAM setup
goto branch 'a'
if data RAM setup = 0
a: then check if data RAM latency > 0x10
if true then force data RAM latency = 0x10
----------------------------------------------------------------
so that the effective data RAM latency reduces to 3 cycles or less
and hence prevent hitting the erratum.

NOTE: The Exynos5250 based products have already been shipped, which
makes it impossible to add the change in bootloader, so we are
adding the required change in kernel.

Signed-off-by: Vivek Gautam <gautam.vivek@xxxxxxxxxxx>
Cc: Doug Anderson <dianders@xxxxxxxxxxxx>
Cc: Olof Johansson <olofj@xxxxxxxxxxxx>
Cc: David Garbett <david.garbett@xxxxxxx>
---
arch/arm/Kconfig | 15 ++++++++
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mm/proc-v7.S | 79 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c59fa19..2e6f36c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1250,6 +1250,21 @@ config ARM_ERRATA_751472
operation is received by a CPU before the ICIALLUIS has completed,
potentially leading to corrupted entries in the cache or TLB.

+config ARM_ERRATA_773769
+ bool "ARM errata: Large data RAM latencies can lead to rare data corruption"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the erratum 773769, which affects
+ Cortex-A15 (rev r2p0).
+ In systems with L2 Data RAM latency programmed to 4 or more cycles,
+ or with ACP in use, or with a L2 Data RAM slice configured, it is
+ possible that a rare collision between non-cacheable stores and
+ L1 data cache evictions which can lead to data corruption in L2 cache
+ or memory.
+ This workaround is to configure an effective Data RAM latency of 3 or
+ less. Also note that, if a Data RAM slice is configured in A15 then
+ there is no workaround.
+
config PL310_ERRATA_753970
bool "PL310 errata: cache sync operation may be faulty"
depends on CACHE_PL310
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 4c414af..29f505f 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -82,6 +82,7 @@ config SOC_EXYNOS5250
default y
depends on ARCH_EXYNOS5
select ARCH_HAS_BANDGAP
+ select ARM_ERRATA_773769
select PINCTRL_EXYNOS
select PM_GENERIC_DOMAINS if PM
select S5P_PM if PM
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index bd17819..0674c4c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -141,6 +141,49 @@ ENTRY(cpu_v7_do_resume)
mcr p15, 0, r4, c10, c2, 0 @ write PRRR
mcr p15, 0, r5, c10, c2, 1 @ write NMRR
#endif /* CONFIG_MMU */
+
+#ifdef CONFIG_ARM_ERRATA_773769
+ /* get the arm rev id */
+ mrc p15, 0, r3, c0, c0, 0 @ read main ID register
+ and r4, r3, #0xff000000 @ ARM?
+ teq r4, #0x41000000
+ bne 8f
+ and r5, r3, #0x00f00000 @ variant
+ and r7, r3, #0x0000000f @ revision
+ orr r7, r7, r5, lsr #20-4 @ combine variant and revision
+ ubfx r3, r3, #4, #12 @ primary part number
+
+ ldr r4, =0x00000c0f @ Cortex-A15 primary part number
+ teq r3, r4
+ bne 8f
+
+ ALT_SMP(cmp r7, #0x21) @ present prior to r2p1
+ ALT_UP_B(8f)
+ mrclt p15, 0, r3, c1, c0, 0 @ read system control register
+ andlt r3, r3, #0x4 @ mask for C bit
+ cmplt r3, #0x0 @ check if cache is on/off
+ bne 8f @ Do nothing when cache is on
+
+ mrceq p15, 1, r5, c9, c0, 2 @ read L2 control register
+ andeq r3, r5, #(1 << 5) @ mask for data RAM setup
+ lsreq r3, r3, #0x5
+ cmpeq r3, #0x1 @ check if data RAM setup = 1
+ bne 9f
+ and r4, r5, #0x7 @ mask for data RAM latency
+ add r4, r4, r3
+ add r4, r4, #0x1 @ effective latency
+ cmp r4, #0x3
+ bicgt r5, r5, #(1 << 5) @ clear data RAM setup bit
+
+9: and r4, r5, #0x7 @ mask for data RAM latency
+ cmp r4, #0x2 @ check if data RAM latency > 2
+ ble 10f
+ bic r5, r5, #0x7 @ clear data RAM latency bits
+ orr r5, r5, #0x2 @ force data RAM latency = 2
+10: mcr p15, 1, r5, c9, c0, 2 @ set L2 control register
+8:
+#endif
+
mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register
teq r4, r9 @ Is it already set?
mcrne p15, 0, r9, c1, c0, 1 @ No, so write it
@@ -349,6 +392,42 @@ __v7_setup:
mcrle p15, 0, r10, c1, c0, 1 @ write aux control register
#endif

+#ifdef CONFIG_ARM_ERRATA_773769
+ ALT_SMP(cmp r6, #0x21) @ present prior to r2p1
+ ALT_UP_B(5f)
+ mrclt p15, 0, r3, c1, c0, 0 @ read system control register
+ andlt r3, r3, #0x4 @ mask for C bit
+ cmplt r3, #0x0 @ check if cache is on/off
+ bne 5f @ Do nothing when cache is on
+ /*
+ * if data RAM setup = 1
+ * then check if effective latency i.e (latency + setup + 1) > 3
+ * if true then clear data RAM setup
+ * goto branch 'a'
+ * if data RAM setup = 0
+ * a: then check if data RAM latency > 0x10
+ * if true then force data RAM latency = 0x10
+ */
+ mrceq p15, 1, r5, c9, c0, 2 @ read L2 control register
+ andeq r3, r5, #(1 << 5) @ mask for data RAM setup
+ lsreq r3, r3, #0x5
+ cmpeq r3, #0x1 @ check if data RAM setup = 1
+ bne 6f
+ and r10, r5, #0x7 @ mask for data RAM latency
+ add r10, r10, r3
+ add r10, r10, #0x1 @ effective latency
+ cmp r10, #0x3
+ bicgt r5, r5, #(1 << 5) @ clear data RAM setup bit
+
+6: and r10, r5, #0x7 @ mask for data RAM latency
+ cmp r10, #0x2 @ check if data RAM latency > 2
+ ble 7f
+ bic r5, r5, #0x7 @ clear data RAM latency bits
+ orr r5, r5, #0x2 @ force data RAM latency = 2
+7: mcr p15, 1, r5, c9, c0, 2 @ set L2 control register
+5:
+#endif
+
4: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
dsb
--
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/