ARM: Tegra: Move cache disable to flush function
Antti P Miettinen [Wed, 19 Sep 2012 11:44:59 +0000 (14:44 +0300)]
During power gating we need to make sure that all state is
properly flushed to ungated part of the chip. To ensure
that data cache is completely cleaned after flush, the
cache needs to be disabled before flush. When data cache
is disabled we naturally cannot write to cacheable memory.
Therefore handle the disable inside the flush function.

Bug 1045096

Change-Id: I740ffdfd43c4b75bf58aaad4279092040a8c7405
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
Reviewed-on: http://git-master/r/133799
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

Rebase-Id: R4496004d2a32b2dfda731c77502a9489c0eb6b08

arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/sleep-t30.S
arch/arm/mach-tegra/sleep.S
arch/arm/mach-tegra/sleep.h

index f14ea9e..ba21668 100644 (file)
@@ -42,24 +42,8 @@ void tegra_cpu_die(unsigned int cpu)
        cpu = cpu_logical_map(cpu);
 
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
-       unsigned int r = 0;
-#endif
-
        /* Disable GIC CPU interface for this CPU. */
        tegra_gic_cpu_disable(false);
-
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
-       /* disable cache */
-       asm volatile(
-       "       mrc p15, 0, %0, c1, c0, 0\n"
-       "       bic %0, %0, #0x4         \n"
-       "       mcr p15, 0, %0, c1, c0, 0\n"
-       : "=r" (r)
-       : "r" (r)
-       : "cc"
-       );
-#endif
 #endif
 
        /* Flush the L1 data cache. */
index 8101994..f46ed71 100644 (file)
@@ -261,20 +261,8 @@ ENDPROC(tegra3_sleep_core_finish)
 ENTRY(tegra3_sleep_cpu_secondary_finish)
        mov     r6, lr
 
-       dsb
-
-       /* Disable the data cache */
-       mrc     p15, 0, r2, c1, c0, 0
-       bic     r2, r2, #CR_C
-       dsb
-       mcr     p15, 0, r2, c1, c0, 0
-       isb
-
-#ifdef MULTI_CACHE
 #ifdef CONFIG_HAVE_ARM_SCU
-       mov32   r10, cpu_cache
-       mov     lr, pc
-       ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
+       bl      tegra_flush_l1_cache
 #else
 
        cpu_id  r2
@@ -283,16 +271,11 @@ ENTRY(tegra3_sleep_cpu_secondary_finish)
        ldr     r10, [r10, r1]
        tst     r10, #FLOW_CTRL_CSR_ENABLE_EXT_MASK
        beq     flush_l1
-       mov32   r10, cpu_cache
-       mov     lr, pc
-       ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
+       bl      tegra_flush_cache
        b       no_l2_sync
 flush_l1:
        bl      tegra_flush_l1_cache
 #endif
-#else
-       bl      __cpuc_flush_kern_all
-#endif
 
 no_l2_sync:
        bl      tegra_cpu_exit_coherency
index 4acd46d..41ea7ff 100644 (file)
@@ -117,6 +117,30 @@ ENTRY(tegra_cpu_exit_coherency)
 ENDPROC(tegra_cpu_exit_coherency)
 
 /*
+ * tegra_flush_cache
+ *
+ * clean & invalidate inner cache
+ *
+ * Disable is needed before flush to prevent allocations during flush
+ * When cache is disabled, we cannot push to stack.
+ */
+ENTRY(tegra_flush_cache)
+       stmfd   sp!, {r4-r5, r7, r9-r11, lr}
+       dmb                                     @ ensure ordering
+
+       /* Disable the data cache */
+       mrc     p15, 0, r2, c1, c0, 0
+       bic     r2, r2, #CR_C
+       dsb
+       mcr     p15, 0, r2, c1, c0, 0
+
+       bl      v7_flush_dcache_all
+
+       ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
+       mov     pc, lr
+ENDPROC(tegra_flush_cache)
+
+/*
  * tegra_flush_l1_cache
  *
  * clean & invalidate the L1 cache
@@ -125,11 +149,21 @@ ENDPROC(tegra_cpu_exit_coherency)
  * may not be desired if all we need is to flush L1 only. Therefore this
  * function is implemented to flush the L1 cache only.
  *
+ * Disable is needed before flush to prevent allocations during flush
+ * When cache is disabled, we cannot push to stack.
+ *
  * Corrupted registers: r0-r7, r9-r11
  */
 ENTRY(tegra_flush_l1_cache)
        stmfd   sp!, {r4-r5, r7, r9-r11, lr}
        dmb                                     @ ensure ordering with previous memory accesses
+
+       /* Disable the data cache */
+       mrc     p15, 0, r2, c1, c0, 0
+       bic     r2, r2, #CR_C
+       dsb
+       mcr     p15, 0, r2, c1, c0, 0
+
        mov     r10, #0
 #ifdef CONFIG_PREEMPT
        save_and_disable_irqs_notrace r9
index 43afbd0..fe5a36d 100644 (file)
@@ -238,6 +238,7 @@ void tegra_cpu_wfi(void);
 int tegra_sleep_cpu_finish(unsigned long v2p);
 void tegra_resume(void);
 void tegra_flush_l1_cache(void);
+void tegra_flush_cache(void);
 
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 extern unsigned int tegra2_iram_start;