From 2e2f3d3792de5913897b6bb49ac13915b0b020d5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 Feb 2011 17:39:31 +0000 Subject: [PATCH] ARM: pm: convert samsung platforms to generic suspend/resume support Tested-by: Kukjin Kim Signed-off-by: Russell King --- arch/arm/mach-s3c64xx/sleep.S | 63 +------------- arch/arm/mach-s5pv210/sleep.S | 105 +----------------------- arch/arm/plat-s3c24xx/sleep.S | 57 +------------ arch/arm/plat-samsung/include/plat/pm.h | 12 +-- arch/arm/plat-samsung/pm.c | 16 +--- 5 files changed, 14 insertions(+), 239 deletions(-) diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index b2ef4431736..afe5a762f46 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S @@ -32,25 +32,13 @@ * code after resume. * * entry: - * r0 = pointer to the save block + * r1 = v:p offset */ ENTRY(s3c_cpu_save) stmfd sp!, { r4 - r12, lr } - - mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID - mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 - mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 - mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control - mrc p15, 0, r9, c1, c0, 0 @ Control register - mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register - mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls - - stmia r0, { r4 - r13 } @ Save CP registers and SP - - @@ save our state to ram - bl s3c_pm_cb_flushcache + ldr r3, =resume_with_mmu + bl cpu_suspend @@ call final suspend code ldr r0, =pm_cpu_sleep @@ -61,18 +49,6 @@ ENTRY(s3c_cpu_save) resume_with_mmu: ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save - .data - - /* the next bit is code, but it requires easy access to the - * s3c_sleep_save_phys data before the MMU is switched on, so - * we store the code that needs this variable in the .data where - * the value can be written to (the .text segment is RO). - */ - - .global s3c_sleep_save_phys -s3c_sleep_save_phys: - .word 0 - /* Sleep magic, the word before the resume entry point so that the * bootloader can check for a resumeable image. */ @@ -110,35 +86,4 @@ ENTRY(s3c_cpu_resume) orr r0, r0, #1 << 15 @ GPN15 str r0, [ r3, #S3C64XX_GPNDAT ] #endif - - /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches - * are thoroughly cleaned just in case the bootloader didn't do it - * for us. */ - mov r0, #0 - mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs - @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches - - ldr r0, s3c_sleep_save_phys - ldmia r0, { r4 - r13 } - - mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID - mcr p15, 0, r5, c3, c0, 0 @ Domain ID - mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 - mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 - mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control - mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register - - mov r0, #0 @ restore copro access controls - mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls - mcr p15, 0, r0, c7, c5, 4 - - ldr r2, =resume_with_mmu - mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */ - nop - mov pc, r2 /* jump back */ - - .end + b cpu_resume diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index d4d222b716b..a3d649466fb 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S @@ -35,50 +35,24 @@ /* s3c_cpu_save * * entry: - * r0 = save address (virtual addr of s3c_sleep_save_phys) + * r1 = v:p offset */ ENTRY(s3c_cpu_save) stmfd sp!, { r3 - r12, lr } - - mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID - mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 - mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 - mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control - mrc p15, 0, r9, c1, c0, 0 @ Control register - mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register - mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls - mrc p15, 0, r12, c10, c2, 0 @ Read PRRR - mrc p15, 0, r3, c10, c2, 1 @ READ NMRR - - stmia r0, { r3 - r13 } - - bl s3c_pm_cb_flushcache + ldr r3, =resume_with_mmu + bl cpu_suspend ldr r0, =pm_cpu_sleep ldr r0, [ r0 ] mov pc, r0 resume_with_mmu: - /* - * After MMU is turned on, restore the previous MMU table. - */ - ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET) - add r4, r4, r9 - str r12, [r4] - ldmfd sp!, { r3 - r12, pc } .ltorg - .data - - .global s3c_sleep_save_phys -s3c_sleep_save_phys: - .word 0 - /* sleep magic, to allow the bootloader to check for an valid * image to resume to. Must be the first word before the * s3c_cpu_resume entry. @@ -96,75 +70,4 @@ s3c_sleep_save_phys: */ ENTRY(s3c_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE - msr cpsr_c, r0 - - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs - mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache - - ldr r0, s3c_sleep_save_phys @ address of restore block - ldmia r0, { r3 - r13 } - - mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID - mcr p15, 0, r5, c3, c0, 0 @ Domain ID - - mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control - mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 - mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 - - mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register - - mov r0, #0 - mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB - - mov r0, #0 @ restore copro access - mcr p15, 0, r11, c1, c0, 2 @ Co-processor access - mcr p15, 0, r0, c7, c5, 4 - - mcr p15, 0, r12, c10, c2, 0 @ write PRRR - mcr p15, 0, r3, c10, c2, 1 @ write NMRR - - /* - * In Cortex-A8, when MMU is turned on, the pipeline is flushed. - * And there are no valid entries in the MMU table at this point. - * So before turning on the MMU, the MMU entry for the DRAM address - * range is added. After the MMU is turned on, the other entries - * in the MMU table will be restored. - */ - - /* r6 = Translation Table BASE0 */ - mov r4, r6 - mov r4, r4, LSR #14 - mov r4, r4, LSL #14 - - /* Load address for adding to MMU table list */ - ldr r11, =0xE010F000 @ INFORM0 reg. - ldr r10, [r11, #0] - mov r10, r10, LSR #18 - bic r10, r10, #0x3 - orr r4, r4, r10 - - /* Calculate MMU table entry */ - mov r10, r10, LSL #18 - ldr r5, =0x40E - orr r10, r10, r5 - - /* Back up originally data */ - ldr r12, [r4] - - /* Add calculated MMU table entry into MMU table list */ - str r10, [r4] - - ldr r2, =resume_with_mmu - mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc - - nop - nop - nop - nop - nop @ second-to-last before mmu - - mov pc, r2 @ go back to virtual address - - .ltorg + b cpu_resume diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index e73e3b6e88d..fd7032f84ae 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S @@ -44,23 +44,13 @@ /* s3c_cpu_save * * entry: - * r0 = save address (virtual addr of s3c_sleep_save_phys) + * r1 = v:p offset */ ENTRY(s3c_cpu_save) stmfd sp!, { r4 - r12, lr } - - @@ store co-processor registers - - mrc p15, 0, r4, c13, c0, 0 @ PID - mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ translation table base address - mrc p15, 0, r7, c1, c0, 0 @ control register - - stmia r0, { r4 - r13 } - - @@ write our state back to RAM - bl s3c_pm_cb_flushcache + ldr r3, =resume_with_mmu + bl cpu_suspend @@ jump to final code to send system to sleep ldr r0, =pm_cpu_sleep @@ -76,20 +66,6 @@ resume_with_mmu: .ltorg - @@ the next bits sit in the .data segment, even though they - @@ happen to be code... the s3c_sleep_save_phys needs to be - @@ accessed by the resume code before it can restore the MMU. - @@ This means that the variable has to be close enough for the - @@ code to read it... since the .text segment needs to be RO, - @@ the data segment can be the only place to put this code. - - .data - - .global s3c_sleep_save_phys -s3c_sleep_save_phys: - .word 0 - - /* sleep magic, to allow the bootloader to check for an valid * image to resume to. Must be the first word before the * s3c_cpu_resume entry. @@ -100,10 +76,6 @@ s3c_sleep_save_phys: /* s3c_cpu_resume * * resume code entry for bootloader to call - * - * we must put this code here in the data segment as we have no - * other way of restoring the stack pointer after sleep, and we - * must not write to the code segment (code is read-only) */ ENTRY(s3c_cpu_resume) @@ -134,25 +106,4 @@ ENTRY(s3c_cpu_resume) beq 1001b #endif /* CONFIG_DEBUG_RESUME */ - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs - mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches - - ldr r0, s3c_sleep_save_phys @ address of restore block - ldmia r0, { r4 - r13 } - - mcr p15, 0, r4, c13, c0, 0 @ PID - mcr p15, 0, r5, c3, c0, 0 @ Domain ID - mcr p15, 0, r6, c2, c0, 0 @ translation table base - -#ifdef CONFIG_DEBUG_RESUME - mov r3, #'R' - strb r3, [ r2, #S3C2410_UTXH ] -#endif - - ldr r2, =resume_with_mmu - mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc - nop @ second-to-last before mmu - mov pc, r2 @ go back to virtual address - - .ltorg + b cpu_resume diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index d9025e37767..4aa697dfe13 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -50,13 +50,11 @@ extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ /* from sleep.S */ -extern int s3c_cpu_save(unsigned long *saveblk); +extern int s3c_cpu_save(unsigned long *saveblk, long); extern void s3c_cpu_resume(void); extern void s3c2410_cpu_suspend(void); -extern unsigned long s3c_sleep_save_phys; - /* sleep save info */ /** @@ -179,13 +177,5 @@ extern void s3c_pm_restore_gpios(void); */ extern void s3c_pm_save_gpios(void); -/** - * s3c_pm_cb_flushcache - callback for assembly code - * - * Callback to issue flush_cache_all() as this call is - * not a directly callable object. - */ -extern void s3c_pm_cb_flushcache(void); - extern void s3c_pm_save_core(void); extern void s3c_pm_restore_core(void); diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 02d531fb3f8..d5b58d31903 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -241,8 +241,6 @@ void (*pm_cpu_sleep)(void); static int s3c_pm_enter(suspend_state_t state) { - static unsigned long regs_save[16]; - /* ensure the debug is initialised (if enabled) */ s3c_pm_debug_init(); @@ -266,12 +264,6 @@ static int s3c_pm_enter(suspend_state_t state) return -EINVAL; } - /* store the physical address of the register recovery block */ - - s3c_sleep_save_phys = virt_to_phys(regs_save); - - S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys); - /* save all necessary core registers not covered by the drivers */ s3c_pm_save_gpios(); @@ -305,7 +297,7 @@ static int s3c_pm_enter(suspend_state_t state) * we resume as it saves its own register state and restores it * during the resume. */ - s3c_cpu_save(regs_save); + s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET); /* restore the cpu state using the kernel's cpu init code. */ @@ -336,12 +328,6 @@ static int s3c_pm_enter(suspend_state_t state) return 0; } -/* callback from assembly code */ -void s3c_pm_cb_flushcache(void) -{ - flush_cache_all(); -} - static int s3c_pm_prepare(void) { /* prepare check area if configured */ -- 2.20.1