ARM errata: Writing ACTLR.SMP when the L2 cache has been idle for an extended period...
authorBo Yan <byan@nvidia.com>
Mon, 25 Mar 2013 20:27:41 +0000 (13:27 -0700)
committerSimone Willett <swillett@nvidia.com>
Mon, 22 Apr 2013 22:08:13 +0000 (15:08 -0700)
This workaround is for ARM errata 799270 which is applicable to
Cortex-A15 up to revision R2P4. The workaround is to read from
a device register and create a data dependency between this read
and the modification of ACTLR.

Change-Id: I26813f17a8a9c6a90446ddeb943ef318e3c69770
Signed-off-by: Bo Yan <byan@nvidia.com>
Reviewed-on: http://git-master/r/212770
(cherry picked from commit 2340401e2dec7228bcc5d9074c310d0146454736)
Reviewed-on: http://git-master/r/221144
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Sang-Hun Lee <sanlee@nvidia.com>
Reviewed-by: Ankit Pashiney <apashiney@nvidia.com>
arch/arm/Kconfig
arch/arm/mm/proc-v7.S

index a3c66dd776e2de50617cbf8085a3fe039b9b1317..8ec3ec25820deec0216873857cf05c2bbe0d1a18 100644 (file)
@@ -1450,6 +1450,21 @@ config PL310_ERRATA_769419
          on systems with an outer cache, the store buffer is drained
          explicitly.
 
+config ARM_ERRATA_799270
+       bool "ARM errata: Writing ACTLR.SMP when the L2 cache has been idle for an extended period may not work correctly"
+       depends on CPU_V7 && SMP
+       help
+         This option enables the workaround for the 799270 Cortex-A15 (r2p0,
+         r2p1, r2p2, r2p3, r2p4) erratum. If the L2 cache logic clock is
+         stopped because of L2 inactivity, setting or clearing the ACTLR.SMP
+         bit might not be effective. The bit is modified in the ACTLR, meaning
+         a read of the register returns the updated value. However the logic
+         that uses that bit retains the previous value. The workaround is to
+         do a memory read to a memory location with Non-cacheable, Strongly-
+         ordered, or Device memory attributes. A dependency must be created
+         between the returning load data and the MCR instruction that sets the
+         ACTLR.SMP bit.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
index 2765d6f60080cde1bf7f97dc2af6088f7608233b..ba34bdf07ea841d263183302303f5020a67fb1a2 100644 (file)
@@ -278,14 +278,14 @@ ENTRY(cpu_v7_do_resume)
        mcr     p15, 0, r1, c2, c0, 0   @ TTB 0
        mcr     p15, 0, r7, c2, c0, 1   @ TTB 1
        mcr     p15, 0, r11, c2, c0, 2  @ TTB control register
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+       mrc     p15, 0, r4, c1, c0, 1   @ Read Auxiliary control register
+       teq     r4, r9                  @ Is it already set?
+#ifdef CONFIG_ARM_ERRATA_799270
        ldr     r4, =TEGRA_CLK_RESET_BOND_OUT
        ldr     r4, [r4]
-       tst     r4, #1
-       bne     .
+       and     r4, r4, #0
+       orr     r9, r9, r4
 #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
        mcr     p15, 0, r10, c1, c0, 2  @ Co-processor access control
        ldr     r4, =PRRR               @ PRRR
@@ -426,15 +426,16 @@ __v7_ca15mp_setup:
        orreq   r0, r0, #0x1000                 @ disable prefetch throttling
        mcreq   p15, 1, r0, c15, c0, 3
 
-       ldr     r0, =TEGRA_CLK_RESET_BOND_OUT
-       ldr     r0, [r0]
-       tst     r0, #1
-       bne     .
-
        ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
        ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
        tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
        orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
+#ifdef CONFIG_ARM_ERRATA_799270
+       ldr     r10, =TEGRA_CLK_RESET_BOND_OUT
+       ldr     r10, [r10]
+       and     r10, r10, #0
+       orr     r0, r0, r10
+#endif
        mcreq   p15, 0, r0, c1, c0, 1
 
        b       __v7_setup