root/arch/arm/mach-pxa/sleep.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * Low-level PXA250/210 sleep/wakeUp support
   3  *
   4  * Initial SA1110 code:
   5  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
   6  *
   7  * Adapted for PXA by Nicolas Pitre:
   8  * Copyright (c) 2002 Monta Vista Software, Inc.
   9  *
  10  * This program is free software; you can redistribute it and/or
  11  * modify it under the terms of the GNU General Public License.
  12  */
  13 
  14 #include <linux/linkage.h>
  15 #include <asm/assembler.h>
  16 #include <mach/hardware.h>
  17 #include <mach/smemc.h>
  18 #include <mach/pxa2xx-regs.h>
  19 
  20 #define MDREFR_KDIV     0x200a4000      // all banks
  21 #define CCCR_SLEEP      0x00000107      // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
  22 
  23                 .text
  24 
  25 #ifdef CONFIG_PXA3xx
  26 /*
  27  * pxa3xx_finish_suspend() - forces CPU into sleep state (S2D3C4)
  28  */
  29 ENTRY(pxa3xx_finish_suspend)
  30         mov     r0, #0x06               @ S2D3C4 mode
  31         mcr     p14, 0, r0, c7, c0, 0   @ enter sleep
  32 
  33 20:     b       20b                     @ waiting for sleep
  34 #endif /* CONFIG_PXA3xx */
  35 
  36 #ifdef CONFIG_PXA27x
  37 /*
  38  * pxa27x_finish_suspend()
  39  *
  40  * Forces CPU into sleep state.
  41  *
  42  * r0 = value for PWRMODE M field for desired sleep state
  43  */
  44 ENTRY(pxa27x_finish_suspend)
  45         @ Put the processor to sleep
  46         @ (also workaround for sighting 28071)
  47 
  48         @ prepare value for sleep mode
  49         mov     r1, r0                          @ sleep mode
  50 
  51         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
  52         mov     r2, #UNCACHED_PHYS_0
  53 
  54         @ prepare SDRAM refresh settings
  55         ldr     r4, =MDREFR
  56         ldr     r5, [r4]
  57 
  58         @ enable SDRAM self-refresh mode
  59         orr     r5, r5, #MDREFR_SLFRSH
  60 
  61         @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
  62         ldr     r6, =MDREFR_KDIV
  63         orr     r5, r5, r6
  64 
  65         @ Intel PXA270 Specification Update notes problems sleeping
  66         @ with core operating above 91 MHz
  67         @ (see Errata 50, ...processor does not exit from sleep...)
  68 
  69         ldr     r6, =CCCR
  70         ldr     r8, [r6]                @ keep original value for resume
  71 
  72         ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
  73         mov     r0, #0x2                @ prepare value for CLKCFG
  74 
  75         @ align execution to a cache line
  76         b       pxa_cpu_do_suspend
  77 #endif
  78 
  79 #ifdef CONFIG_PXA25x
  80 /*
  81  * pxa25x_finish_suspend()
  82  *
  83  * Forces CPU into sleep state.
  84  *
  85  * r0 = value for PWRMODE M field for desired sleep state
  86  */
  87 
  88 ENTRY(pxa25x_finish_suspend)
  89         @ prepare value for sleep mode
  90         mov     r1, r0                          @ sleep mode
  91 
  92         @ prepare pointer to physical address 0 (virtual mapping in generic.c)
  93         mov     r2, #UNCACHED_PHYS_0
  94 
  95         @ prepare SDRAM refresh settings
  96         ldr     r4, =MDREFR
  97         ldr     r5, [r4]
  98 
  99         @ enable SDRAM self-refresh mode
 100         orr     r5, r5, #MDREFR_SLFRSH
 101 
 102         @ Intel PXA255 Specification Update notes problems
 103         @ about suspending with PXBus operating above 133MHz
 104         @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
 105         @
 106         @ We keep the change-down close to the actual suspend on SDRAM
 107         @ as possible to eliminate messing about with the refresh clock
 108         @ as the system will restore with the original speed settings
 109         @
 110         @ Ben Dooks, 13-Sep-2004
 111 
 112         ldr     r6, =CCCR
 113         ldr     r8, [r6]                @ keep original value for resume
 114 
 115         @ ensure x1 for run and turbo mode with memory clock
 116         bic     r7, r8, #CCCR_M_MASK | CCCR_N_MASK
 117         orr     r7, r7, #(1<<5) | (2<<7)
 118 
 119         @ check that the memory frequency is within limits
 120         and     r14, r7, #CCCR_L_MASK
 121         teq     r14, #1
 122         bicne   r7, r7, #CCCR_L_MASK
 123         orrne   r7, r7, #1                      @@ 99.53MHz
 124 
 125         @ get ready for the change
 126 
 127         @ note, turbo is not preserved over sleep so there is no
 128         @ point in preserving it here. we save it on the stack with the
 129         @ other CP registers instead.
 130         mov     r0, #0
 131         mcr     p14, 0, r0, c6, c0, 0
 132         orr     r0, r0, #2                      @ initiate change bit
 133         b       pxa_cpu_do_suspend
 134 #endif
 135 
 136         .ltorg
 137         .align  5
 138 pxa_cpu_do_suspend:
 139 
 140         @ All needed values are now in registers.
 141         @ These last instructions should be in cache
 142 
 143         @ initiate the frequency change...
 144         str     r7, [r6]
 145         mcr     p14, 0, r0, c6, c0, 0
 146 
 147         @ restore the original cpu speed value for resume
 148         str     r8, [r6]
 149 
 150         @ need 6 13-MHz cycles before changing PWRMODE
 151         @ just set frequency to 91-MHz... 6*91/13 = 42
 152 
 153         mov     r0, #42
 154 10:     subs    r0, r0, #1
 155         bne     10b
 156 
 157         @ Do not reorder...
 158         @ Intel PXA270 Specification Update notes problems performing
 159         @ external accesses after SDRAM is put in self-refresh mode
 160         @ (see Errata 38 ...hangs when entering self-refresh mode)
 161 
 162         @ force address lines low by reading at physical address 0
 163         ldr     r3, [r2]
 164 
 165         @ put SDRAM into self-refresh
 166         str     r5, [r4]
 167 
 168         @ enter sleep mode
 169         mcr     p14, 0, r1, c7, c0, 0           @ PWRMODE
 170 
 171 20:     b       20b                             @ loop waiting for sleep

/* [<][>][^][v][top][bottom][index][help] */