linux/arch/arm/mach-s3c64xx/sleep.S
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c64xx/sleep.S
   2 *
   3 * Copyright 2008 Openmoko, Inc.
   4 * Copyright 2008 Simtec Electronics
   5 *      Ben Dooks <ben@simtec.co.uk>
   6 *      http://armlinux.simtec.co.uk/
   7 *
   8 * S3C64XX CPU sleep code
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13*/
  14
  15#include <linux/linkage.h>
  16#include <asm/assembler.h>
  17#include <mach/map.h>
  18
  19#undef S3C64XX_VA_GPIO
  20#define S3C64XX_VA_GPIO (0x0)
  21
  22#include <mach/regs-gpio.h>
  23#include <mach/gpio-bank-n.h>
  24
  25#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
  26
  27        .text
  28
  29        /* s3c_cpu_save
  30         *
  31         * Save enough processor state to allow the restart of the pm.c
  32         * code after resume.
  33         *
  34         * entry:
  35         *      r0 = pointer to the save block
  36        */
  37
  38ENTRY(s3c_cpu_save)
  39        stmfd   sp!, { r4 - r12, lr }
  40
  41        mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
  42        mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
  43        mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
  44        mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
  45        mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
  46        mrc     p15, 0, r9, c1, c0, 0   @ Control register
  47        mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
  48        mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
  49
  50        stmia   r0, { r4 - r13 }        @ Save CP registers and SP
  51
  52        @@ save our state to ram
  53        bl      s3c_pm_cb_flushcache
  54
  55        @@ call final suspend code
  56        ldr     r0, =pm_cpu_sleep
  57        ldr     pc, [r0]
  58        
  59        @@ return to the caller, after the MMU is turned on.
  60        @@ restore the last bits of the stack and return.
  61resume_with_mmu:
  62        ldmfd   sp!, { r4 - r12, pc }   @ return, from sp from s3c_cpu_save
  63
  64        .data
  65
  66        /* the next bit is code, but it requires easy access to the
  67         * s3c_sleep_save_phys data before the MMU is switched on, so
  68         * we store the code that needs this variable in the .data where
  69         * the value can be written to (the .text segment is RO).
  70        */
  71
  72        .global s3c_sleep_save_phys
  73s3c_sleep_save_phys:
  74        .word   0
  75
  76        /* Sleep magic, the word before the resume entry point so that the
  77         * bootloader can check for a resumeable image. */
  78
  79        .word   0x2bedf00d
  80
  81        /* s3c_cpu_reusme
  82         *
  83         * This is the entry point, stored by whatever method the bootloader
  84         * requires to get the kernel runnign again. This code expects to be
  85         * entered with no caches live and the MMU disabled. It will then
  86         * restore the MMU and other basic CP registers saved and restart
  87         * the kernel C code to finish the resume code.
  88        */
  89
  90ENTRY(s3c_cpu_resume)
  91        msr     cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
  92        ldr     r2, =LL_UART            /* for debug */
  93
  94#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
  95        /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
  96         * as the uboot version supplied resets these to inputs during the
  97         * resume checks.
  98        */
  99
 100        ldr     r3, =S3C64XX_PA_GPIO
 101        ldr     r0, [ r3, #S3C64XX_GPNCON ]
 102        bic     r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
 103                          S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
 104        orr     r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
 105                          S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
 106        str     r0, [ r3, #S3C64XX_GPNCON ]
 107
 108        ldr     r0, [ r3, #S3C64XX_GPNDAT ]
 109        bic     r0, r0, #0xf << 12                      @ GPN12..15
 110        orr     r0, r0, #1 << 15                        @ GPN15
 111        str     r0, [ r3, #S3C64XX_GPNDAT ]
 112#endif
 113
 114        /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
 115         * are thoroughly cleaned just in case the bootloader didn't do it
 116         * for us. */
 117        mov     r0, #0
 118        mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
 119        mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
 120        mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
 121        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
 122        @@mcr   p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
 123        @@mcr   p15, 0, r0, c7, c7, 0           @ Invalidate I + D caches
 124
 125        ldr     r0, s3c_sleep_save_phys
 126        ldmia   r0, { r4 - r13 }
 127
 128        mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
 129        mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
 130        mcr     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
 131        mcr     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
 132        mcr     p15, 0, r8, c2, c0, 2   @ Translation Table Control
 133        mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
 134
 135        mov     r0, #0                  @ restore copro access controls
 136        mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
 137        mcr     p15, 0, r0, c7, c5, 4
 138
 139        ldr     r2, =resume_with_mmu
 140        mcr     p15, 0, r9, c1, c0, 0           /* turn mmu back on */
 141        nop
 142        mov     pc, r2                          /* jump back */
 143
 144        .end
 145