diff options
Diffstat (limited to 'arch/arm/plat-omap/sleep.S')
-rw-r--r-- | arch/arm/plat-omap/sleep.S | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S index 279490ce772b..9f745836f6aa 100644 --- a/arch/arm/plat-omap/sleep.S +++ b/arch/arm/plat-omap/sleep.S | |||
@@ -66,7 +66,7 @@ ENTRY(omap1510_idle_loop_suspend) | |||
66 | @ get ARM_IDLECT2 into r2 | 66 | @ get ARM_IDLECT2 into r2 |
67 | ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 67 | ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
68 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff | 68 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff |
69 | orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 | 69 | orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 |
70 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 70 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
71 | 71 | ||
72 | @ request ARM idle | 72 | @ request ARM idle |
@@ -76,7 +76,7 @@ ENTRY(omap1510_idle_loop_suspend) | |||
76 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 76 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
77 | 77 | ||
78 | mov r5, #IDLE_WAIT_CYCLES & 0xff | 78 | mov r5, #IDLE_WAIT_CYCLES & 0xff |
79 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | 79 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 |
80 | l_1510: subs r5, r5, #1 | 80 | l_1510: subs r5, r5, #1 |
81 | bne l_1510 | 81 | bne l_1510 |
82 | /* | 82 | /* |
@@ -96,7 +96,7 @@ l_1510: subs r5, r5, #1 | |||
96 | strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 96 | strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
97 | strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 97 | strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
98 | 98 | ||
99 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 99 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
100 | 100 | ||
101 | ENTRY(omap1510_idle_loop_suspend_sz) | 101 | ENTRY(omap1510_idle_loop_suspend_sz) |
102 | .word . - omap1510_idle_loop_suspend | 102 | .word . - omap1510_idle_loop_suspend |
@@ -115,8 +115,8 @@ ENTRY(omap1610_idle_loop_suspend) | |||
115 | @ turn off clock domains | 115 | @ turn off clock domains |
116 | @ get ARM_IDLECT2 into r2 | 116 | @ get ARM_IDLECT2 into r2 |
117 | ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 117 | ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
118 | mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff | 118 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff |
119 | orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 | 119 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 |
120 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 120 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
121 | 121 | ||
122 | @ request ARM idle | 122 | @ request ARM idle |
@@ -126,7 +126,7 @@ ENTRY(omap1610_idle_loop_suspend) | |||
126 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 126 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
127 | 127 | ||
128 | mov r5, #IDLE_WAIT_CYCLES & 0xff | 128 | mov r5, #IDLE_WAIT_CYCLES & 0xff |
129 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | 129 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 |
130 | l_1610: subs r5, r5, #1 | 130 | l_1610: subs r5, r5, #1 |
131 | bne l_1610 | 131 | bne l_1610 |
132 | /* | 132 | /* |
@@ -146,7 +146,7 @@ l_1610: subs r5, r5, #1 | |||
146 | strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 146 | strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
147 | strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 147 | strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
148 | 148 | ||
149 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 149 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
150 | 150 | ||
151 | ENTRY(omap1610_idle_loop_suspend_sz) | 151 | ENTRY(omap1610_idle_loop_suspend_sz) |
152 | .word . - omap1610_idle_loop_suspend | 152 | .word . - omap1610_idle_loop_suspend |
@@ -208,7 +208,7 @@ ENTRY(omap1510_cpu_suspend) | |||
208 | 208 | ||
209 | @ turn off clock domains | 209 | @ turn off clock domains |
210 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff | 210 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff |
211 | orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 | 211 | orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 |
212 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 212 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
213 | 213 | ||
214 | @ request ARM idle | 214 | @ request ARM idle |
@@ -217,7 +217,7 @@ ENTRY(omap1510_cpu_suspend) | |||
217 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 217 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
218 | 218 | ||
219 | mov r5, #IDLE_WAIT_CYCLES & 0xff | 219 | mov r5, #IDLE_WAIT_CYCLES & 0xff |
220 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | 220 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 |
221 | l_1510_2: | 221 | l_1510_2: |
222 | subs r5, r5, #1 | 222 | subs r5, r5, #1 |
223 | bne l_1510_2 | 223 | bne l_1510_2 |
@@ -237,7 +237,7 @@ l_1510_2: | |||
237 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 237 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
238 | 238 | ||
239 | @ restore regs and return | 239 | @ restore regs and return |
240 | ldmfd sp!, {r0 - r12, pc} | 240 | ldmfd sp!, {r0 - r12, pc} |
241 | 241 | ||
242 | ENTRY(omap1510_cpu_suspend_sz) | 242 | ENTRY(omap1510_cpu_suspend_sz) |
243 | .word . - omap1510_cpu_suspend | 243 | .word . - omap1510_cpu_suspend |
@@ -249,21 +249,26 @@ ENTRY(omap1610_cpu_suspend) | |||
249 | @ save registers on stack | 249 | @ save registers on stack |
250 | stmfd sp!, {r0 - r12, lr} | 250 | stmfd sp!, {r0 - r12, lr} |
251 | 251 | ||
252 | @ Drain write cache | ||
253 | mov r4, #0 | ||
254 | mcr p15, 0, r0, c7, c10, 4 | ||
255 | nop | ||
256 | |||
252 | @ load base address of Traffic Controller | 257 | @ load base address of Traffic Controller |
253 | mov r4, #TCMIF_ASM_BASE & 0xff000000 | 258 | mov r6, #TCMIF_ASM_BASE & 0xff000000 |
254 | orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 | 259 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 |
255 | orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 | 260 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 |
256 | 261 | ||
257 | @ prepare to put SDRAM into self-refresh manually | 262 | @ prepare to put SDRAM into self-refresh manually |
258 | ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 263 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
259 | orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 | 264 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 |
260 | orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff | 265 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff |
261 | str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 266 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
262 | 267 | ||
263 | @ prepare to put EMIFS to Sleep | 268 | @ prepare to put EMIFS to Sleep |
264 | ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 269 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
265 | orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff | 270 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff |
266 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 271 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
267 | 272 | ||
268 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | 273 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 |
269 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | 274 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 |
@@ -271,26 +276,22 @@ ENTRY(omap1610_cpu_suspend) | |||
271 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | 276 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 |
272 | 277 | ||
273 | @ turn off clock domains | 278 | @ turn off clock domains |
274 | mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff | 279 | @ do not disable PERCK (0x04) |
275 | orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 | 280 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff |
276 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 281 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 |
277 | |||
278 | @ work around errata of OMAP1610/5912. Enable (!) peripheral | ||
279 | @ clock to let the chip go into deep sleep | ||
280 | ldrh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
281 | orr r5,r5, #EN_PERCK_BIT & 0xff | ||
282 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 282 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
283 | 283 | ||
284 | @ request ARM idle | 284 | @ request ARM idle |
285 | mov r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff | 285 | mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff |
286 | orr r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00 | 286 | orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 |
287 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 287 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
288 | 288 | ||
289 | mov r5, #IDLE_WAIT_CYCLES & 0xff | 289 | @ disable instruction cache |
290 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | 290 | mrc p15, 0, r9, c1, c0, 0 |
291 | l_1610_2: | 291 | bic r2, r9, #0x1000 |
292 | subs r5, r5, #1 | 292 | mcr p15, 0, r2, c1, c0, 0 |
293 | bne l_1610_2 | 293 | nop |
294 | |||
294 | /* | 295 | /* |
295 | * Let's wait for the next wake up event to wake us up. r0 can't be | 296 | * Let's wait for the next wake up event to wake us up. r0 can't be |
296 | * used here because r0 holds ARM_IDLECT1 | 297 | * used here because r0 holds ARM_IDLECT1 |
@@ -301,13 +302,21 @@ l_1610_2: | |||
301 | * omap1610_cpu_suspend()'s resume point. | 302 | * omap1610_cpu_suspend()'s resume point. |
302 | * | 303 | * |
303 | * It will just start executing here, so we'll restore stuff from the | 304 | * It will just start executing here, so we'll restore stuff from the |
304 | * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. | 305 | * stack. |
305 | */ | 306 | */ |
307 | @ re-enable Icache | ||
308 | mcr p15, 0, r9, c1, c0, 0 | ||
309 | |||
310 | @ reset the ARM_IDLECT1 and ARM_IDLECT2. | ||
306 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 311 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
307 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 312 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
308 | 313 | ||
314 | @ Restore EMIFF controls | ||
315 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | ||
316 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | ||
317 | |||
309 | @ restore regs and return | 318 | @ restore regs and return |
310 | ldmfd sp!, {r0 - r12, pc} | 319 | ldmfd sp!, {r0 - r12, pc} |
311 | 320 | ||
312 | ENTRY(omap1610_cpu_suspend_sz) | 321 | ENTRY(omap1610_cpu_suspend_sz) |
313 | .word . - omap1610_cpu_suspend | 322 | .word . - omap1610_cpu_suspend |