On Thu, Feb 17, 2011 at 2:41 AM, Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx> wrote: > Colin, > > On Tue, 2011-02-15 at 16:26 -0800, Colin Cross wrote: >> On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux >> <linux@xxxxxxxxxxxxxxxx> wrote: >> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote: >> >> > +ENDPROC(cpu_resume_turn_mmu_on) >> >> > +cpu_resume_after_mmu: >> >> > + str r5, [r2, r4, lsl #2] @ restore old mapping >> >> > +#ifdef MULTI_CACHE >> >> > + ldr r10, =cpu_cache >> >> > + ldr pc, [r10, #CACHE_FLUSH_KERN_ALL] >> >> > +#else >> >> > + b __cpuc_flush_kern_all >> >> > +#endif >> > >> > I think we can eliminate this cache flush by delaying the cache enable >> > as below. Could you see whether Tegra 2 survives this please? >> > Thanks. >> > >> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S >> > index bed1876..193be5f 100644 >> > --- a/arch/arm/kernel/sleep.S >> > +++ b/arch/arm/kernel/sleep.S >> > @@ -4,6 +4,7 @@ >> > #include <asm/assembler.h> >> > #include <asm/glue-cache.h> >> > #include <asm/glue-proc.h> >> > +#include <asm/system.h> >> > .text >> > >> > /* >> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu) >> > str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code >> > sub r2, r2, r1 >> > ldr r3, =cpu_resume_after_mmu >> > + bic r1, r0, #CR_C @ ensure D-cache is disabled >> > b cpu_resume_turn_mmu_on >> > ENDPROC(cpu_resume_mmu) >> > .ltorg >> > .align 5 >> > cpu_resume_turn_mmu_on: >> > - mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, caches, etc >> > - mrc p15, 0, r0, c0, c0, 0 @ read id reg >> > - mov r0, r0 >> > - mov r0, r0 >> > + mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc >> > + mrc p15, 0, r1, c0, c0, 0 @ read id reg >> > + mov r1, r1 >> > + mov r1, r1 >> > mov pc, r3 @ jump to virtual address >> > ENDPROC(cpu_resume_turn_mmu_on) >> > cpu_resume_after_mmu: >> > str r5, [r2, r4, lsl #2] @ restore old mapping >> > -#ifdef MULTI_CACHE >> > - ldr r10, =cpu_cache >> > - ldr pc, [r10, #CACHE_FLUSH_KERN_ALL] >> > -#else >> > - b __cpuc_flush_kern_all >> > -#endif >> > + mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache >> > + mov pc, lr >> > >> > /* >> > * Note: Yes, part of the following code is located into the .data section. >> > >> > >> >> Tested-by: Colin Cross <ccross@xxxxxxxxxxx> >> >> Works for Tegra 2 cpuidle and suspend. >> > > When calling suspend from cpuidle, do you flush the stack (ie CPU > context) from L2 using outer_cache functions ? This has to be done when > one CPU is shut down with L2 enabled for the MMU off resume path to work > properly. Tegra2 has the power rails of the two cpus tied together, so the cpu that suspends first only needs to go through cpu_resume if the other cpu has also suspended and flushed the entire L2 cache. On platforms that can power gate the cpus individually you will need to flush the stack and stack pointer in cpu_suspend. I have a patch that does the flushes in cpu_suspend, but it failed on the way back up because the page table modifications got lost behind the L2, and I haven't retried it since Russell fixed that. > I think that on resume you invalidate L1 in the reset vector before > jumping to cpu_resume, correct ? I manually invalidate the L1 Dcache, but not the Icache. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html