ARM errata: Writing ACTLR.SMP when the L2 cache has been idle for an extended period...
Bo Yan [Mon, 25 Mar 2013 20:27:41 +0000 (13:27 -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
Reviewed-by: Bobby Meeker <bmeeker@nvidia.com>

arch/arm/Kconfig
arch/arm/mm/proc-v7.S

index d39efbb..6a0c2e7 100644 (file)
@@ -1461,6 +1461,21 @@ config ARM_ERRATA_775420
         to deadlock. This workaround puts DSB before executing ISB if
         an abort may occur on cache maintenance.
 
+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 2765d6f..ba34bdf 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