0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include <linux/linkage.h>
0036
0037 #include <asm/assembler.h>
0038
0039 #include "hardware.h"
0040
0041 #include "iomap.h"
0042 #include "pm.h"
0043
0044 .text
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
0065 .align 3
0066 ENTRY(omap7xx_cpu_suspend)
0067
0068 @ save registers on stack
0069 stmfd sp!, {r0 - r12, lr}
0070
0071 @ Drain write cache
0072 mov r4, #0
0073 mcr p15, 0, r0, c7, c10, 4
0074 nop
0075
0076 @ load base address of Traffic Controller
0077 mov r6, #TCMIF_ASM_BASE & 0xff000000
0078 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
0079 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
0080
0081 @ prepare to put SDRAM into self-refresh manually
0082 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0083 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
0084 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
0085 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0086
0087 @ prepare to put EMIFS to Sleep
0088 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0089 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
0090 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0091
0092 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
0093 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
0094 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
0095 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
0096
0097 @ turn off clock domains
0098 @ do not disable PERCK (0x04)
0099 mov r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff
0100 orr r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00
0101 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0102
0103 @ request ARM idle
0104 mov r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff
0105 orr r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00
0106 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0107
0108 @ disable instruction cache
0109 mrc p15, 0, r9, c1, c0, 0
0110 bic r2, r9, #0x1000
0111 mcr p15, 0, r2, c1, c0, 0
0112 nop
0113
0114
0115
0116
0117
0118 mov r2, #0
0119 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
0120
0121
0122
0123
0124
0125
0126 @ re-enable Icache
0127 mcr p15, 0, r9, c1, c0, 0
0128
0129 @ reset the ARM_IDLECT1 and ARM_IDLECT2.
0130 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0131 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0132
0133 @ Restore EMIFF controls
0134 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0135 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0136
0137 @ restore regs and return
0138 ldmfd sp!, {r0 - r12, pc}
0139
0140 ENTRY(omap7xx_cpu_suspend_sz)
0141 .word . - omap7xx_cpu_suspend
0142 #endif
0143
0144 #ifdef CONFIG_ARCH_OMAP15XX
0145 .align 3
0146 ENTRY(omap1510_cpu_suspend)
0147
0148 @ save registers on stack
0149 stmfd sp!, {r0 - r12, lr}
0150
0151 @ load base address of Traffic Controller
0152 mov r4, #TCMIF_ASM_BASE & 0xff000000
0153 orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
0154 orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
0155
0156 @ work around errata of OMAP1510 PDE bit for TC shut down
0157 @ clear PDE bit
0158 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0159 bic r5, r5, #PDE_BIT & 0xff
0160 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0161
0162 @ set PWD_EN bit
0163 and r5, r5, #PWD_EN_BIT & 0xff
0164 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0165
0166 @ prepare to put SDRAM into self-refresh manually
0167 ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0168 orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
0169 orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
0170 str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0171
0172 @ prepare to put EMIFS to Sleep
0173 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0174 orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
0175 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0176
0177 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
0178 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
0179 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
0180 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
0181
0182 @ turn off clock domains
0183 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
0184 orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
0185 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0186
0187 @ request ARM idle
0188 mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
0189 orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
0190 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0191
0192 mov r5, #IDLE_WAIT_CYCLES & 0xff
0193 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
0194 l_1510_2:
0195 subs r5, r5, #1
0196 bne l_1510_2
0197
0198
0199
0200
0201 mov r2, #0
0202 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
0203
0204
0205
0206
0207
0208
0209 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0210 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0211
0212 @ restore regs and return
0213 ldmfd sp!, {r0 - r12, pc}
0214
0215 ENTRY(omap1510_cpu_suspend_sz)
0216 .word . - omap1510_cpu_suspend
0217 #endif
0218
0219 #if defined(CONFIG_ARCH_OMAP16XX)
0220 .align 3
0221 ENTRY(omap1610_cpu_suspend)
0222
0223 @ save registers on stack
0224 stmfd sp!, {r0 - r12, lr}
0225
0226 @ Drain write cache
0227 mov r4, #0
0228 mcr p15, 0, r0, c7, c10, 4
0229 nop
0230
0231 @ Load base address of Traffic Controller
0232 mov r6, #TCMIF_ASM_BASE & 0xff000000
0233 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
0234 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
0235
0236 @ Prepare to put SDRAM into self-refresh manually
0237 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0238 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
0239 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
0240 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0241
0242 @ Prepare to put EMIFS to Sleep
0243 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0244 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
0245 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0246
0247 @ Load base address of ARM_IDLECT1 and ARM_IDLECT2
0248 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
0249 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
0250 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
0251
0252 @ Turn off clock domains
0253 @ Do not disable PERCK (0x04)
0254 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
0255 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
0256 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0257
0258 @ Request ARM idle
0259 mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
0260 orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
0261 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0262
0263
0264
0265
0266
0267 mov r2, #0
0268 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
0269
0270 @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
0271 @ according to this formula:
0272 @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
0273 @ Max DPLL_MULT = 18
0274 @ DPLL_DIV = 1
0275 @ ARMDIV = 1
0276 @ => 74 nop-instructions
0277 nop
0278 nop
0279 nop
0280 nop
0281 nop
0282 nop
0283 nop
0284 nop
0285 nop
0286 nop @10
0287 nop
0288 nop
0289 nop
0290 nop
0291 nop
0292 nop
0293 nop
0294 nop
0295 nop
0296 nop @20
0297 nop
0298 nop
0299 nop
0300 nop
0301 nop
0302 nop
0303 nop
0304 nop
0305 nop
0306 nop @30
0307 nop
0308 nop
0309 nop
0310 nop
0311 nop
0312 nop
0313 nop
0314 nop
0315 nop
0316 nop @40
0317 nop
0318 nop
0319 nop
0320 nop
0321 nop
0322 nop
0323 nop
0324 nop
0325 nop
0326 nop @50
0327 nop
0328 nop
0329 nop
0330 nop
0331 nop
0332 nop
0333 nop
0334 nop
0335 nop
0336 nop @60
0337 nop
0338 nop
0339 nop
0340 nop
0341 nop
0342 nop
0343 nop
0344 nop
0345 nop
0346 nop @70
0347 nop
0348 nop
0349 nop
0350 nop @74
0351
0352
0353
0354
0355
0356
0357 @ Restore the ARM_IDLECT1 and ARM_IDLECT2.
0358 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
0359 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
0360
0361 @ Restore EMIFF controls
0362 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
0363 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
0364
0365 @ Restore regs and return
0366 ldmfd sp!, {r0 - r12, pc}
0367
0368 ENTRY(omap1610_cpu_suspend_sz)
0369 .word . - omap1610_cpu_suspend
0370 #endif