diff options
Diffstat (limited to 'arch/arm/mach-sa1100/sleep.S')
| -rw-r--r-- | arch/arm/mach-sa1100/sleep.S | 122 |
1 files changed, 25 insertions, 97 deletions
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 80f31bad707..85863741ef8 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -20,62 +20,44 @@ #include <asm/assembler.h> #include <mach/hardware.h> - - .text - - - /* - * sa1100_cpu_suspend() + * sa1100_finish_suspend() * * Causes sa11x0 to enter sleep state * + * Must be aligned to a cacheline. */ + .balign 32 +ENTRY(sa1100_finish_suspend) + @ disable clock switching + mcr p15, 0, r1, c15, c2, 2 -ENTRY(sa1100_cpu_suspend) - - stmfd sp!, {r4 - r12, lr} @ save registers on stack - - @ get coprocessor registers - mrc p15, 0, r4, c3, c0, 0 @ domain ID - mrc p15, 0, r5, c2, c0, 0 @ translation table base addr - mrc p15, 0, r6, c13, c0, 0 @ PID - mrc p15, 0, r7, c1, c0, 0 @ control reg - - @ store them plus current virtual stack ptr on stack - mov r8, sp - stmfd sp!, {r4 - r8} - - @ preserve phys address of stack - mov r0, sp - bl sleep_phys_sp - ldr r1, =sleep_save_sp - str r0, [r1] + ldr r6, =MDREFR + ldr r4, [r6] + orr r4, r4, #MDREFR_K1DB2 + ldr r5, =PPCR - @ clean data cache and invalidate WB - bl v4wb_flush_kern_cache_all + @ Pre-load __loop_udelay into the I-cache + mov r0, #1 + bl __loop_udelay + mov r0, r0 - @ disable clock switching - mcr p15, 0, r1, c15, c2, 2 + @ The following must all exist in a single cache line to + @ avoid accessing memory until this sequence is complete, + @ otherwise we occasionally hang. - @ Adjust memory timing before lowering CPU clock - @ Clock speed adjustment without changing memory timing makes - @ CPU hang in some cases - ldr r0, =MDREFR - ldr r1, [r0] - orr r1, r1, #MDREFR_K1DB2 - str r1, [r0] + @ Adjust memory timing before lowering CPU clock + str r4, [r6] @ delay 90us and set CPU PLL to lowest speed @ fixes resume problem on high speed SA1110 mov r0, #90 - bl __udelay - ldr r0, =PPCR + bl __loop_udelay mov r1, #0 - str r1, [r0] + str r1, [r5] mov r0, #90 - bl __udelay + bl __loop_udelay /* * SA1110 SDRAM controller workaround. register values: @@ -112,12 +94,10 @@ ENTRY(sa1100_cpu_suspend) bic r5, r5, #FMsk(MSC_RT) bic r5, r5, #FMsk(MSC_RT)<<16 - ldr r6, =MDREFR - ldr r7, [r6] -bic r7, r7, #0x0000FF00 -bic r7, r7, #0x000000F0 -orr r8, r7, #MDREFR_SLFRSH + bic r7, r7, #0x0000FF00 + bic r7, r7, #0x000000F0 + orr r8, r7, #MDREFR_SLFRSH ldr r9, =MDCNFG ldr r10, [r9] @@ -161,55 +141,3 @@ sa1110_sdram_controller_fix: str r13, [r12] 20: b 20b @ loop waiting for sleep - -/* - * cpu_sa1100_resume() - * - * entry point from bootloader into kernel during resume - * - * Note: Yes, part of the following code is located into the .data section. - * This is to allow sleep_save_sp to be accessed with a relative load - * while we can't rely on any MMU translation. We could have put - * sleep_save_sp in the .text section as well, but some setups might - * insist on it to be truly read-only. - */ - - .data - .align 5 -ENTRY(sa1100_cpu_resume) - mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, r0 @ set SVC, irqs off - - ldr r0, sleep_save_sp @ stack phys addr - ldr r2, =resume_after_mmu @ its absolute virtual address - ldmfd r0, {r4 - r7, sp} @ CP regs + virt stack ptr - - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs - mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache - mcr p15, 0, r1, c9, c0, 0 @ invalidate RB - mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB - - mcr p15, 0, r4, c3, c0, 0 @ domain ID - mcr p15, 0, r5, c2, c0, 0 @ translation table base addr - mcr p15, 0, r6, c13, c0, 0 @ PID - b resume_turn_on_mmu @ cache align execution - - .align 5 -resume_turn_on_mmu: - mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc. - nop - mov pc, r2 @ jump to virtual addr - nop - nop - nop - -sleep_save_sp: - .word 0 @ preserve stack phys ptr here - - .text -resume_after_mmu: - mcr p15, 0, r1, c15, c1, 2 @ enable clock switching - ldmfd sp!, {r4 - r12, pc} @ return to caller - - |
