1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 #include <linux/linkage.h>
  36 
  37 #include <asm/assembler.h>
  38 
  39 #include <mach/hardware.h>
  40 
  41 #include "iomap.h"
  42 #include "pm.h"
  43 
  44                 .text
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
  65         .align  3
  66 ENTRY(omap7xx_cpu_suspend)
  67 
  68         @ save registers on stack
  69         stmfd   sp!, {r0 - r12, lr}
  70 
  71         @ Drain write cache
  72         mov     r4, #0
  73         mcr     p15, 0, r0, c7, c10, 4
  74         nop
  75 
  76         @ load base address of Traffic Controller
  77         mov     r6, #TCMIF_ASM_BASE & 0xff000000
  78         orr     r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
  79         orr     r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
  80 
  81         @ prepare to put SDRAM into self-refresh manually
  82         ldr     r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
  83         orr     r9, r7, #SELF_REFRESH_MODE & 0xff000000
  84         orr     r9, r9, #SELF_REFRESH_MODE & 0x000000ff
  85         str     r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
  86 
  87         @ prepare to put EMIFS to Sleep
  88         ldr     r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
  89         orr     r9, r8, #IDLE_EMIFS_REQUEST & 0xff
  90         str     r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
  91 
  92         @ load base address of ARM_IDLECT1 and ARM_IDLECT2
  93         mov     r4, #CLKGEN_REG_ASM_BASE & 0xff000000
  94         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
  95         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
  96 
  97         @ turn off clock domains
  98         @ do not disable PERCK (0x04)
  99         mov     r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff
 100         orr     r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00
 101         strh    r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 102 
 103         @ request ARM idle
 104         mov     r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff
 105         orr     r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00
 106         strh    r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 107 
 108         @ disable instruction cache
 109         mrc     p15, 0, r9, c1, c0, 0
 110         bic     r2, r9, #0x1000
 111         mcr     p15, 0, r2, c1, c0, 0
 112         nop
 113 
 114 
 115 
 116 
 117 
 118         mov     r2, #0
 119         mcr     p15, 0, r2, c7, c0, 4           @ wait for interrupt
 120 
 121 
 122 
 123 
 124 
 125 
 126         @ re-enable Icache
 127         mcr     p15, 0, r9, c1, c0, 0
 128 
 129         @ reset the ARM_IDLECT1 and ARM_IDLECT2.
 130         strh    r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 131         strh    r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 132 
 133         @ Restore EMIFF controls
 134         str     r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 135         str     r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 136 
 137         @ restore regs and return
 138         ldmfd   sp!, {r0 - r12, pc}
 139 
 140 ENTRY(omap7xx_cpu_suspend_sz)
 141         .word   . - omap7xx_cpu_suspend
 142 #endif 
 143 
 144 #ifdef CONFIG_ARCH_OMAP15XX
 145         .align  3
 146 ENTRY(omap1510_cpu_suspend)
 147 
 148         @ save registers on stack
 149         stmfd   sp!, {r0 - r12, lr}
 150 
 151         @ load base address of Traffic Controller
 152         mov     r4, #TCMIF_ASM_BASE & 0xff000000
 153         orr     r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
 154         orr     r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
 155 
 156         @ work around errata of OMAP1510 PDE bit for TC shut down
 157         @ clear PDE bit
 158         ldr     r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 159         bic     r5, r5, #PDE_BIT & 0xff
 160         str     r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 161 
 162         @ set PWD_EN bit
 163         and     r5, r5, #PWD_EN_BIT & 0xff
 164         str     r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 165 
 166         @ prepare to put SDRAM into self-refresh manually
 167         ldr     r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 168         orr     r5, r5, #SELF_REFRESH_MODE & 0xff000000
 169         orr     r5, r5, #SELF_REFRESH_MODE & 0x000000ff
 170         str     r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 171 
 172         @ prepare to put EMIFS to Sleep
 173         ldr     r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 174         orr     r5, r5, #IDLE_EMIFS_REQUEST & 0xff
 175         str     r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 176 
 177         @ load base address of ARM_IDLECT1 and ARM_IDLECT2
 178         mov     r4, #CLKGEN_REG_ASM_BASE & 0xff000000
 179         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
 180         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
 181 
 182         @ turn off clock domains
 183         mov     r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
 184         orr     r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
 185         strh    r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 186 
 187         @ request ARM idle
 188         mov     r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
 189         orr     r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
 190         strh    r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 191 
 192         mov     r5, #IDLE_WAIT_CYCLES & 0xff
 193         orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
 194 l_1510_2:
 195         subs    r5, r5, #1
 196         bne     l_1510_2
 197 
 198 
 199 
 200 
 201         mov     r2, #0
 202         mcr     p15, 0, r2, c7, c0, 4           @ wait for interrupt
 203 
 204 
 205 
 206 
 207 
 208 
 209         strh    r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 210         strh    r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 211 
 212         @ restore regs and return
 213         ldmfd   sp!, {r0 - r12, pc}
 214 
 215 ENTRY(omap1510_cpu_suspend_sz)
 216         .word   . - omap1510_cpu_suspend
 217 #endif 
 218 
 219 #if defined(CONFIG_ARCH_OMAP16XX)
 220         .align  3
 221 ENTRY(omap1610_cpu_suspend)
 222 
 223         @ save registers on stack
 224         stmfd   sp!, {r0 - r12, lr}
 225 
 226         @ Drain write cache
 227         mov     r4, #0
 228         mcr     p15, 0, r0, c7, c10, 4
 229         nop
 230 
 231         @ Load base address of Traffic Controller
 232         mov     r6, #TCMIF_ASM_BASE & 0xff000000
 233         orr     r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
 234         orr     r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
 235 
 236         @ Prepare to put SDRAM into self-refresh manually
 237         ldr     r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 238         orr     r9, r7, #SELF_REFRESH_MODE & 0xff000000
 239         orr     r9, r9, #SELF_REFRESH_MODE & 0x000000ff
 240         str     r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 241 
 242         @ Prepare to put EMIFS to Sleep
 243         ldr     r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 244         orr     r9, r8, #IDLE_EMIFS_REQUEST & 0xff
 245         str     r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 246 
 247         @ Load base address of ARM_IDLECT1 and ARM_IDLECT2
 248         mov     r4, #CLKGEN_REG_ASM_BASE & 0xff000000
 249         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
 250         orr     r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
 251 
 252         @ Turn off clock domains
 253         @ Do not disable PERCK (0x04)
 254         mov     r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
 255         orr     r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
 256         strh    r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 257 
 258         @ Request ARM idle
 259         mov     r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
 260         orr     r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
 261         strh    r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 262 
 263 
 264 
 265 
 266 
 267         mov     r2, #0
 268         mcr     p15, 0, r2, c7, c0, 4           @ wait for interrupt
 269 
 270         @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
 271         @ according to this formula:
 272         @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
 273         @ Max DPLL_MULT = 18
 274         @ DPLL_DIV = 1
 275         @ ARMDIV = 1
 276         @ => 74 nop-instructions
 277         nop
 278         nop
 279         nop
 280         nop
 281         nop
 282         nop
 283         nop
 284         nop
 285         nop
 286         nop     @10
 287         nop
 288         nop
 289         nop
 290         nop
 291         nop
 292         nop
 293         nop
 294         nop
 295         nop
 296         nop     @20
 297         nop
 298         nop
 299         nop
 300         nop
 301         nop
 302         nop
 303         nop
 304         nop
 305         nop
 306         nop     @30
 307         nop
 308         nop
 309         nop
 310         nop
 311         nop
 312         nop
 313         nop
 314         nop
 315         nop
 316         nop     @40
 317         nop
 318         nop
 319         nop
 320         nop
 321         nop
 322         nop
 323         nop
 324         nop
 325         nop
 326         nop     @50
 327         nop
 328         nop
 329         nop
 330         nop
 331         nop
 332         nop
 333         nop
 334         nop
 335         nop
 336         nop     @60
 337         nop
 338         nop
 339         nop
 340         nop
 341         nop
 342         nop
 343         nop
 344         nop
 345         nop
 346         nop     @70
 347         nop
 348         nop
 349         nop
 350         nop     @74
 351 
 352 
 353 
 354 
 355 
 356 
 357         @ Restore the ARM_IDLECT1 and ARM_IDLECT2.
 358         strh    r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 359         strh    r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 360 
 361         @ Restore EMIFF controls
 362         str     r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 363         str     r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 364 
 365         @ Restore regs and return
 366         ldmfd   sp!, {r0 - r12, pc}
 367 
 368 ENTRY(omap1610_cpu_suspend_sz)
 369         .word   . - omap1610_cpu_suspend
 370 #endif