2 * linux/arch/arm/mach-omap2/sleep.S
6 * Karthik Dasu <karthik-dp@ti.com>
9 * Texas Instruments, <www.ti.com>
10 * Richard Woodruff <r-woodruff2@ti.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include <linux/linkage.h>
28 #include <asm/assembler.h>
29 #include <asm/arch/io.h>
30 #include <asm/arch/pm.h>
31 #include <asm/arch/control.h>
36 #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
37 OMAP3430_PM_PREPWSTST)
38 #define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
39 OMAP3430_PM_PREPWSTST)
40 #define PM_PWSTCTRL_MPU_P OMAP34XX_PRM_REGADDR(MPU_MOD, PM_PWSTCTRL)
41 #define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
43 #define SCRATCHPAD_BASE_P OMAP343X_CTRL_REGADDR(\
44 OMAP343X_CONTROL_MEM_WKUP +\
46 #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
49 /* Function call to get the restore pointer for resume from OFF */
50 ENTRY(get_restore_pointer)
51 stmfd sp!, {lr} @ save registers on stack
53 ldmfd sp!, {pc} @ restore regs and return
54 ENTRY(get_restore_pointer_sz)
55 .word . - get_restore_pointer_sz
57 * Forces OMAP into idle state
59 * omap34xx_suspend() - This bit of code just executes the WFI
62 * Note: This code get's copied to internal SRAM at boot. When the OMAP
63 * wakes up it continues execution at the point it went to sleep.
65 ENTRY(omap34xx_cpu_suspend)
66 stmfd sp!, {r0-r12, lr} @ save registers on stack
68 /*b loop*/ @Enable to debug by stepping through code
69 /* r0 contains restore pointer in sdram */
70 /* r1 contains information about saving context */
71 ldr r4, sdrc_power @ read the SDRC_POWER register
72 ldr r5, [r4] @ read the contents of SDRC_POWER
73 orr r5, r5, #0x40 @ enable self refresh on idle req
74 str r5, [r4] @ write back to SDRC_POWER register
77 /* If context save is required, do that and execute wfi */
79 /* Data memory barrier and Data sync barrier */
81 mcr p15, 0, r1, c7, c10, 4
82 mcr p15, 0, r1, c7, c10, 5
84 wfi @ wait for interrupt
98 ldmfd sp!, {r0-r12, pc} @ restore regs and return
100 /* b restore*/ @ Enable to debug restore code
101 /* Check what was the reason for mpu reset and store the reason in r9*/
102 /* 1 - Only L1 and logic lost */
103 /* 2 - Only L2 lost - In this case, we wont be here */
104 /* 3 - Both L1 and L2 lost */
105 ldr r1, pm_pwstctrl_mpu
108 cmp r2, #0x0 @ Check if target power state was OFF or RET
109 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
110 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
112 /* Execute smi to invalidate L2 cache */
113 mov r12, #0x1 @ set up to invalide L2
114 smi: .word 0xE1600070 @ Call SMI monitor (smieq)
117 /* Invalidate all instruction caches to PoU
118 * and flush branch target cache */
119 mcr p15, 0, r1, c7, c5, 0
121 ldr r4, scratchpad_base
129 /* Coprocessor access Control Register */
130 mcr p15, 0, r4, c1, c0, 2
133 MCR p15, 0, r5, c2, c0, 0
135 MCR p15, 0, r6, c2, c0, 1
136 /* Translation table base control register */
137 MCR p15, 0, r7, c2, c0, 2
138 /*domain access Control Register */
139 MCR p15, 0, r8, c3, c0, 0
140 /* data fault status Register */
141 MCR p15, 0, r9, c5, c0, 0
144 /* instruction fault status Register */
145 MCR p15, 0, r4, c5, c0, 1
146 /*Data Auxiliary Fault Status Register */
147 MCR p15, 0, r5, c5, c1, 0
148 /*Instruction Auxiliary Fault Status Register*/
149 MCR p15, 0, r6, c5, c1, 1
150 /*Data Fault Address Register */
151 MCR p15, 0, r7, c6, c0, 0
152 /*Instruction Fault Address Register*/
153 MCR p15, 0, r8, c6, c0, 2
156 /* user r/w thread and process ID */
157 MCR p15, 0, r4, c13, c0, 2
158 /* user ro thread and process ID */
159 MCR p15, 0, r5, c13, c0, 3
160 /*Privileged only thread and process ID */
161 MCR p15, 0, r6, c13, c0, 4
162 /* cache size selection */
163 MCR p15, 2, r7, c0, c0, 0
165 /* Data TLB lockdown registers */
166 MCR p15, 0, r4, c10, c0, 0
167 /* Instruction TLB lockdown registers */
168 MCR p15, 0, r5, c10, c0, 1
169 /* Secure or Nonsecure Vector Base Address */
170 MCR p15, 0, r6, c12, c0, 0
172 MCR p15, 0, r7, c13, c0, 0
174 MCR p15, 0, r8, c13, c0, 1
177 /* primary memory remap register */
178 MCR p15, 0, r4, c10, c2, 0
179 /*normal memory remap register */
180 MCR p15, 0, r5, c10, c2, 1
182 /* Restore registers for other modes from SDRAM */
183 /* Save current mode */
191 /* load the SP and LR from SDRAM */
193 mov sp, r4 /*update the SP */
194 mov lr, r5 /*update the LR */
195 msr spsr, r6 /*update the SPSR*/
200 msr cpsr, r0 /*go into IRQ mode*/
201 ldmia r3!,{r4-r6} /*load the SP and LR from SDRAM*/
202 mov sp, r4 /*update the SP */
203 mov lr, r5 /*update the LR */
204 msr spsr, r6 /*update the SPSR */
209 msr cpsr, r0 /* go into ABORT mode */
210 ldmia r3!,{r4-r6} /*load the SP and LR from SDRAM */
211 mov sp, r4 /*update the SP */
212 mov lr, r5 /*update the LR */
213 msr spsr, r6 /*update the SPSR */
218 msr cpsr, r0 /*go into UNDEF mode */
219 ldmia r3!,{r4-r6} /*load the SP and LR from SDRAM */
220 mov sp, r4 /*update the SP*/
221 mov lr, r5 /*update the LR*/
222 msr spsr, r6 /*update the SPSR*/
224 /* SYSTEM (USER) mode */
227 msr cpsr, r0 /*go into USR mode */
228 ldmia r3!,{r4-r6} /*load the SP and LR from SDRAM*/
229 mov sp, r4 /*update the SP */
230 mov lr, r5 /*update the LR */
231 msr spsr, r6 /*update the SPSR */
232 msr cpsr, r7 /*back to original mode*/
235 ldmia r3!,{r4} /*load CPSR from SDRAM*/
236 msr cpsr, r4 /*store cpsr */
238 /* Enabling MMU here */
239 mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
240 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
245 /* More work needs to be done to support N[0:2] value other than 0
246 * So looping here so that the error can be detected
250 mrc p15, 0, r2, c2, c0, 0
254 ldr r5, table_index_mask
255 and r4, r5 /* r4 = 31 to 20 bits of pc */
256 /* Extract the value to be written to table entry */
258 add r1, r1, r4 /* r1 has value to be written to table entry*/
259 /* Getting the address of table entry to modify */
261 add r2, r4 /* r2 has the location which needs to be modified */
262 /* Storing previous entry of location being modified */
263 ldr r5, scratchpad_base
266 /* Modify the table entry */
268 /* Storing address of entry being modified
269 * - will be restored after enabling MMU */
270 ldr r5, scratchpad_base
274 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
275 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
276 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
277 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
278 /* Restore control register but dont enable caches here*/
279 /* Caches will be enabled after restoring MMU table entry */
281 /* Store previous value of control register in scratchpad */
283 ldr r2, cache_pred_disable_mask
285 mcr p15, 0, r4, c1, c0, 0
287 ldmfd sp!, {r0-r12, pc} @ restore regs and return
289 /*b save_context_wfi*/ @ enable to debug save code
290 mov r8, r0 /* Store SDRAM address in r8 */
291 /* Check what that target sleep state is:stored in r1*/
292 /* 1 - Only L1 and logic lost */
293 /* 2 - Only L2 lost */
294 /* 3 - Both L1 and L2 lost */
295 cmp r1, #0x2 /* Only L2 lost */
297 cmp r1, #0x1 /* L2 retained */
298 /* r9 stores whether to clean L2 or not*/
299 moveq r9, #0x0 /* Dont Clean L2 */
300 movne r9, #0x1 /* Clean L2 */
302 /* Store sp and spsr to SDRAM */
307 /* Save all ARM registers */
308 /* Coprocessor access control register */
309 mrc p15, 0, r6, c1, c0, 2
311 /* TTBR0, TTBR1 and Translation table base control */
312 mrc p15, 0, r4, c2, c0, 0
313 mrc p15, 0, r5, c2, c0, 1
314 mrc p15, 0, r6, c2, c0, 2
316 /* Domain access control register, data fault status register,
317 and instruction fault status register */
318 mrc p15, 0, r4, c3, c0, 0
319 mrc p15, 0, r5, c5, c0, 0
320 mrc p15, 0, r6, c5, c0, 1
322 /* Data aux fault status register, instruction aux fault status,
323 datat fault address register and instruction fault address register*/
324 mrc p15, 0, r4, c5, c1, 0
325 mrc p15, 0, r5, c5, c1, 1
326 mrc p15, 0, r6, c6, c0, 0
327 mrc p15, 0, r7, c6, c0, 2
329 /* user r/w thread and process ID, user r/o thread and process ID,
330 priv only thread and process ID, cache size selection */
331 mrc p15, 0, r4, c13, c0, 2
332 mrc p15, 0, r5, c13, c0, 3
333 mrc p15, 0, r6, c13, c0, 4
334 mrc p15, 2, r7, c0, c0, 0
336 /* Data TLB lockdown, instruction TLB lockdown registers */
337 mrc p15, 0, r5, c10, c0, 0
338 mrc p15, 0, r6, c10, c0, 1
340 /* Secure or non secure vector base address, FCSE PID, Context PID*/
341 mrc p15, 0, r4, c12, c0, 0
342 mrc p15, 0, r5, c13, c0, 0
343 mrc p15, 0, r6, c13, c0, 1
345 /* Primary remap, normal remap registers */
346 mrc p15, 0, r4, c10, c2, 0
347 mrc p15, 0, r5, c10, c2, 1
349 /* Store SP, LR, SPSR registers for SUP, FIQ, IRQ, ABORT and USER
352 /* move SDRAM address to r7 as r8 is banked in FIQ*/
355 /* Save current mode */
360 msr cpsr, r0 /* go to FIQ mode */
362 mov r4, r13 /* move SP into r4*/
394 /* System (USER mode) */
403 /* Back to original mode */
406 /* Store current cpsr*/
409 mrc p15, 0, r4, c1, c0, 0
410 /* save control register */
413 /* Clean Data or unified cache to POU*/
414 /* How to invalidate only L1 cache???? - #FIX_ME# */
415 /* mcr p15, 0, r11, c7, c11, 1 */
416 cmp r9, #1 /* Check whether L2 inval is required or not*/
420 mrc p15, 1, r0, c0, c0, 1
421 /* extract loc from clidr */
422 ands r3, r0, #0x7000000
423 /* left align loc bit field */
425 /* if loc is 0, then no need to clean */
427 /* start clean at cache level 0 */
430 /* work out 3x current cache level */
431 add r2, r10, r10, lsr #1
432 /* extract cache type bits from clidr*/
434 /* mask of the bits for current cache only */
436 /* see what cache we have at this level */
438 /* skip if no cache, or just i-cache */
440 /* select current cache level in cssr */
441 mcr p15, 2, r10, c0, c0, 0
442 /* isb to sych the new cssr&csidr */
444 /* read the new csidr */
445 mrc p15, 1, r1, c0, c0, 0
446 /* extract the length of the cache lines */
448 /* add 4 (line length offset) */
451 /* find maximum number on the way size */
452 ands r4, r4, r1, lsr #3
453 /* find bit position of way size increment */
456 /* extract max number of the index size*/
457 ands r7, r7, r1, lsr #13
460 /* create working copy of max way size*/
462 /* factor way and cache number into r11 */
463 orr r11, r10, r9, lsl r5
464 /* factor index number into r11 */
465 orr r11, r11, r7, lsl r2
466 /*clean & invalidate by set/way */
467 mcr p15, 0, r11, c7, c10, 2
468 /* decrement the way*/
471 /*decrement the index */
476 /* increment cache number */
480 /*swith back to cache level 0 */
482 /* select current cache level in cssr */
483 mcr p15, 2, r10, c0, c0, 0
486 /* Data memory barrier and Data sync barrier */
488 mcr p15, 0, r1, c7, c10, 4
489 mcr p15, 0, r1, c7, c10, 5
491 wfi @ wait for interrupt
503 /* restore regs and return */
504 ldmfd sp!, {r0-r12, pc}
507 ldr r4, clk_stabilize_delay
518 .word PM_PREPWSTST_CORE_V
520 .word PM_PREPWSTST_MPU_V
522 .word PM_PWSTCTRL_MPU_P
524 .word SCRATCHPAD_BASE_P
541 cache_pred_disable_mask:
543 ENTRY(omap34xx_cpu_suspend_sz)
544 .word . - omap34xx_cpu_suspend