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>
30 #include <plat/control.h>
36 #define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
38 #define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
39 OMAP3430_PM_PREPWSTST)
40 #define PM_PREPWSTST_CORE_P 0x48306AE8
41 #define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
42 OMAP3430_PM_PREPWSTST)
43 #define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
44 #define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
45 #define SRAM_BASE_P 0x40200000
46 #define CONTROL_STAT 0x480022F0
47 #define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
49 #define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
50 + SCRATCHPAD_MEM_OFFS)
51 #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
52 #define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
53 #define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0)
54 #define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0)
55 #define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
56 #define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1)
57 #define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1)
58 #define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
59 #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
60 #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
63 /* Function to aquire the semaphore in scratchpad */
64 ENTRY(lock_scratchpad_sem)
65 stmfd sp!, {lr} @ save registers on stack
68 ldr r1, sdrc_scratchpad_sem
70 ldr r2, [r1] @ load the lock value
71 cmp r2, r0 @ is the lock free ?
72 beq wait_loop @ not free...
73 swp r2, r0, [r1] @ semaphore free so lock it and proceed
74 cmp r2, r0 @ did we succeed ?
75 beq wait_sem @ no - try again
76 ldmfd sp!, {pc} @ restore regs and return
78 .word SDRC_SCRATCHPAD_SEM_V
79 ENTRY(lock_scratchpad_sem_sz)
80 .word . - lock_scratchpad_sem
83 /* Function to release the scratchpad semaphore */
84 ENTRY(unlock_scratchpad_sem)
85 stmfd sp!, {lr} @ save registers on stack
86 ldr r3, sdrc_scratchpad_sem
89 ldmfd sp!, {pc} @ restore regs and return
90 ENTRY(unlock_scratchpad_sem_sz)
91 .word . - unlock_scratchpad_sem
94 /* Function call to get the restore pointer for resume from OFF */
95 ENTRY(get_restore_pointer)
96 stmfd sp!, {lr} @ save registers on stack
98 ldmfd sp!, {pc} @ restore regs and return
99 ENTRY(get_restore_pointer_sz)
100 .word . - get_restore_pointer
103 /* Function call to get the restore pointer for for ES3 to resume from OFF */
104 ENTRY(get_es3_restore_pointer)
105 stmfd sp!, {lr} @ save registers on stack
107 ldmfd sp!, {pc} @ restore regs and return
108 ENTRY(get_es3_restore_pointer_sz)
109 .word . - get_es3_restore_pointer
112 ldr r4, sdrc_syscfg @ get config addr
113 ldr r5, [r4] @ get value
114 tst r5, #0x100 @ is part access blocked
116 biceq r5, r5, #0x100 @ clear bit if set
117 str r5, [r4] @ write back change
118 ldr r4, sdrc_mr_0 @ get config addr
119 ldr r5, [r4] @ get value
120 str r5, [r4] @ write back change
121 ldr r4, sdrc_emr2_0 @ get config addr
122 ldr r5, [r4] @ get value
123 str r5, [r4] @ write back change
124 ldr r4, sdrc_manual_0 @ get config addr
125 mov r5, #0x2 @ autorefresh command
126 str r5, [r4] @ kick off refreshes
127 ldr r4, sdrc_mr_1 @ get config addr
128 ldr r5, [r4] @ get value
129 str r5, [r4] @ write back change
130 ldr r4, sdrc_emr2_1 @ get config addr
131 ldr r5, [r4] @ get value
132 str r5, [r4] @ write back change
133 ldr r4, sdrc_manual_1 @ get config addr
134 mov r5, #0x2 @ autorefresh command
135 str r5, [r4] @ kick off refreshes
138 .word SDRC_SYSCONFIG_P
144 .word SDRC_MANUAL_0_P
150 .word SDRC_MANUAL_1_P
151 ENTRY(es3_sdrc_fix_sz)
152 .word . - es3_sdrc_fix
154 /* Function to call rom code to save secure ram context */
155 ENTRY(save_secure_ram_context)
156 stmfd sp!, {r1-r12, lr} @ save registers on stack
157 save_secure_ram_debug:
158 /* b save_secure_ram_debug */ @ enable to debug save code
159 adr r3, api_params @ r3 points to parameters
160 str r0, [r3,#0x4] @ r0 has sdram address
163 ldr r12, sram_phy_addr_mask
165 mov r0, #25 @ set service ID for PPA
166 mov r12, r0 @ copy secure service ID in r12
167 mov r1, #0 @ set task id for ROM code in r1
168 mov r2, #4 @ set some flags in r2, r6
170 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
171 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
172 .word 0xE1600071 @ call SMI monitor (smi #1)
177 ldmfd sp!, {r1-r12, pc}
183 .word 0x4, 0x0, 0x0, 0x1, 0x1
184 ENTRY(save_secure_ram_context_sz)
185 .word . - save_secure_ram_context
188 * Forces OMAP into idle state
190 * omap34xx_suspend() - This bit of code just executes the WFI
193 * Note: This code get's copied to internal SRAM at boot. When the OMAP
194 * wakes up it continues execution at the point it went to sleep.
196 ENTRY(omap34xx_cpu_suspend)
197 stmfd sp!, {r0-r12, lr} @ save registers on stack
199 /*b loop*/ @Enable to debug by stepping through code
200 /* r0 contains restore pointer in sdram */
201 /* r1 contains information about saving context */
202 ldr r4, sdrc_power @ read the SDRC_POWER register
203 ldr r5, [r4] @ read the contents of SDRC_POWER
204 orr r5, r5, #0x40 @ enable self refresh on idle req
205 str r5, [r4] @ write back to SDRC_POWER register
208 /* If context save is required, do that and execute wfi */
210 /* Data memory barrier and Data sync barrier */
212 mcr p15, 0, r1, c7, c10, 4
213 mcr p15, 0, r1, c7, c10, 5
215 wfi @ wait for interrupt
229 ldmfd sp!, {r0-r12, pc} @ restore regs and return
231 /*b restore_es3*/ @ Enable to debug restore code
232 ldr r5, pm_prepwstst_core_p
235 cmp r4, #0x0 @ Check if previous power state of CORE is OFF
239 ldr r2, es3_sdrc_fix_sz
242 ldmia r0!, {r3} @ val = *src
243 stmia r1!, {r3} @ *dst = val
244 subs r2, r2, #0x1 @ num_words--
249 /* b restore*/ @ Enable to debug restore code
250 /* Check what was the reason for mpu reset and store the reason in r9*/
251 /* 1 - Only L1 and logic lost */
252 /* 2 - Only L2 lost - In this case, we wont be here */
253 /* 3 - Both L1 and L2 lost */
254 ldr r1, pm_pwstctrl_mpu
257 cmp r2, #0x0 @ Check if target power state was OFF or RET
258 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
259 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
266 mov r0, #40 @ set service ID for PPA
267 mov r12, r0 @ copy secure Service ID in r12
268 mov r1, #0 @ set task id for ROM code in r1
269 mov r2, #4 @ set some flags in r2, r6
271 adr r3, l2_inv_api_params @ r3 points to dummy parameters
272 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
273 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
274 .word 0xE1600071 @ call SMI monitor (smi #1)
275 /* Write to Aux control register to set some bits */
276 mov r0, #42 @ set service ID for PPA
277 mov r12, r0 @ copy secure Service ID in r12
278 mov r1, #0 @ set task id for ROM code in r1
279 mov r2, #4 @ set some flags in r2, r6
281 ldr r4, scratchpad_base
282 ldr r3, [r4, #0xBC] @ r3 points to parameters
283 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
284 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
285 .word 0xE1600071 @ call SMI monitor (smi #1)
291 /* Execute smi to invalidate L2 cache */
292 mov r12, #0x1 @ set up to invalide L2
293 smi: .word 0xE1600070 @ Call SMI monitor (smieq)
294 /* Write to Aux control register to set some bits */
295 ldr r4, scratchpad_base
299 .word 0xE1600070 @ Call SMI monitor (smieq)
302 /* Invalidate all instruction caches to PoU
303 * and flush branch target cache */
304 mcr p15, 0, r1, c7, c5, 0
306 ldr r4, scratchpad_base
315 /* Coprocessor access Control Register */
316 mcr p15, 0, r4, c1, c0, 2
319 MCR p15, 0, r5, c2, c0, 0
321 MCR p15, 0, r6, c2, c0, 1
322 /* Translation table base control register */
323 MCR p15, 0, r7, c2, c0, 2
324 /*domain access Control Register */
325 MCR p15, 0, r8, c3, c0, 0
326 /* data fault status Register */
327 MCR p15, 0, r9, c5, c0, 0
330 /* instruction fault status Register */
331 MCR p15, 0, r4, c5, c0, 1
332 /*Data Auxiliary Fault Status Register */
333 MCR p15, 0, r5, c5, c1, 0
334 /*Instruction Auxiliary Fault Status Register*/
335 MCR p15, 0, r6, c5, c1, 1
336 /*Data Fault Address Register */
337 MCR p15, 0, r7, c6, c0, 0
338 /*Instruction Fault Address Register*/
339 MCR p15, 0, r8, c6, c0, 2
342 /* user r/w thread and process ID */
343 MCR p15, 0, r4, c13, c0, 2
344 /* user ro thread and process ID */
345 MCR p15, 0, r5, c13, c0, 3
346 /*Privileged only thread and process ID */
347 MCR p15, 0, r6, c13, c0, 4
348 /* cache size selection */
349 MCR p15, 2, r7, c0, c0, 0
351 /* Data TLB lockdown registers */
352 MCR p15, 0, r4, c10, c0, 0
353 /* Instruction TLB lockdown registers */
354 MCR p15, 0, r5, c10, c0, 1
355 /* Secure or Nonsecure Vector Base Address */
356 MCR p15, 0, r6, c12, c0, 0
358 MCR p15, 0, r7, c13, c0, 0
360 MCR p15, 0, r8, c13, c0, 1
363 /* primary memory remap register */
364 MCR p15, 0, r4, c10, c2, 0
365 /*normal memory remap register */
366 MCR p15, 0, r5, c10, c2, 1
369 ldmia r3!,{r4} /*load CPSR from SDRAM*/
370 msr cpsr, r4 /*store cpsr */
372 /* Enabling MMU here */
373 mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
374 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
379 /* More work needs to be done to support N[0:2] value other than 0
380 * So looping here so that the error can be detected
384 mrc p15, 0, r2, c2, c0, 0
388 ldr r5, table_index_mask
389 and r4, r5 /* r4 = 31 to 20 bits of pc */
390 /* Extract the value to be written to table entry */
392 add r1, r1, r4 /* r1 has value to be written to table entry*/
393 /* Getting the address of table entry to modify */
395 add r2, r4 /* r2 has the location which needs to be modified */
396 /* Storing previous entry of location being modified */
397 ldr r5, scratchpad_base
400 /* Modify the table entry */
402 /* Storing address of entry being modified
403 * - will be restored after enabling MMU */
404 ldr r5, scratchpad_base
408 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
409 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
410 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
411 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
412 /* Restore control register but dont enable caches here*/
413 /* Caches will be enabled after restoring MMU table entry */
415 /* Store previous value of control register in scratchpad */
417 ldr r2, cache_pred_disable_mask
419 mcr p15, 0, r4, c1, c0, 0
421 ldmfd sp!, {r0-r12, pc} @ restore regs and return
423 /*b save_context_wfi*/ @ enable to debug save code
424 mov r8, r0 /* Store SDRAM address in r8 */
425 mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
426 mov r4, #0x1 @ Number of parameters for restore call
428 /* Check what that target sleep state is:stored in r1*/
429 /* 1 - Only L1 and logic lost */
430 /* 2 - Only L2 lost */
431 /* 3 - Both L1 and L2 lost */
432 cmp r1, #0x2 /* Only L2 lost */
434 cmp r1, #0x1 /* L2 retained */
435 /* r9 stores whether to clean L2 or not*/
436 moveq r9, #0x0 /* Dont Clean L2 */
437 movne r9, #0x1 /* Clean L2 */
439 /* Store sp and spsr to SDRAM */
444 /* Save all ARM registers */
445 /* Coprocessor access control register */
446 mrc p15, 0, r6, c1, c0, 2
448 /* TTBR0, TTBR1 and Translation table base control */
449 mrc p15, 0, r4, c2, c0, 0
450 mrc p15, 0, r5, c2, c0, 1
451 mrc p15, 0, r6, c2, c0, 2
453 /* Domain access control register, data fault status register,
454 and instruction fault status register */
455 mrc p15, 0, r4, c3, c0, 0
456 mrc p15, 0, r5, c5, c0, 0
457 mrc p15, 0, r6, c5, c0, 1
459 /* Data aux fault status register, instruction aux fault status,
460 datat fault address register and instruction fault address register*/
461 mrc p15, 0, r4, c5, c1, 0
462 mrc p15, 0, r5, c5, c1, 1
463 mrc p15, 0, r6, c6, c0, 0
464 mrc p15, 0, r7, c6, c0, 2
466 /* user r/w thread and process ID, user r/o thread and process ID,
467 priv only thread and process ID, cache size selection */
468 mrc p15, 0, r4, c13, c0, 2
469 mrc p15, 0, r5, c13, c0, 3
470 mrc p15, 0, r6, c13, c0, 4
471 mrc p15, 2, r7, c0, c0, 0
473 /* Data TLB lockdown, instruction TLB lockdown registers */
474 mrc p15, 0, r5, c10, c0, 0
475 mrc p15, 0, r6, c10, c0, 1
477 /* Secure or non secure vector base address, FCSE PID, Context PID*/
478 mrc p15, 0, r4, c12, c0, 0
479 mrc p15, 0, r5, c13, c0, 0
480 mrc p15, 0, r6, c13, c0, 1
482 /* Primary remap, normal remap registers */
483 mrc p15, 0, r4, c10, c2, 0
484 mrc p15, 0, r5, c10, c2, 1
487 /* Store current cpsr*/
491 mrc p15, 0, r4, c1, c0, 0
492 /* save control register */
495 /* Clean Data or unified cache to POU*/
496 /* How to invalidate only L1 cache???? - #FIX_ME# */
497 /* mcr p15, 0, r11, c7, c11, 1 */
498 cmp r9, #1 /* Check whether L2 inval is required or not*/
502 mrc p15, 1, r0, c0, c0, 1
503 /* extract loc from clidr */
504 ands r3, r0, #0x7000000
505 /* left align loc bit field */
507 /* if loc is 0, then no need to clean */
509 /* start clean at cache level 0 */
512 /* work out 3x current cache level */
513 add r2, r10, r10, lsr #1
514 /* extract cache type bits from clidr*/
516 /* mask of the bits for current cache only */
518 /* see what cache we have at this level */
520 /* skip if no cache, or just i-cache */
522 /* select current cache level in cssr */
523 mcr p15, 2, r10, c0, c0, 0
524 /* isb to sych the new cssr&csidr */
526 /* read the new csidr */
527 mrc p15, 1, r1, c0, c0, 0
528 /* extract the length of the cache lines */
530 /* add 4 (line length offset) */
533 /* find maximum number on the way size */
534 ands r4, r4, r1, lsr #3
535 /* find bit position of way size increment */
538 /* extract max number of the index size*/
539 ands r7, r7, r1, lsr #13
542 /* create working copy of max way size*/
544 /* factor way and cache number into r11 */
545 orr r11, r10, r9, lsl r5
546 /* factor index number into r11 */
547 orr r11, r11, r7, lsl r2
548 /*clean & invalidate by set/way */
549 mcr p15, 0, r11, c7, c10, 2
550 /* decrement the way*/
553 /*decrement the index */
558 /* increment cache number */
562 /*swith back to cache level 0 */
564 /* select current cache level in cssr */
565 mcr p15, 2, r10, c0, c0, 0
568 /* Data memory barrier and Data sync barrier */
570 mcr p15, 0, r1, c7, c10, 4
571 mcr p15, 0, r1, c7, c10, 5
573 wfi @ wait for interrupt
585 /* restore regs and return */
586 ldmfd sp!, {r0-r12, pc}
588 /* Make sure SDRC accesses are ok */
590 ldr r4, cm_idlest1_core
600 /* Is dll in lock mode? */
601 ldr r4, sdrc_dlla_ctrl
605 /* wait till dll locks */
606 ldr r4, sdrc_dlla_status
614 .word CM_IDLEST1_CORE_V
616 .word SDRC_DLLA_STATUS_V
618 .word SDRC_DLLA_CTRL_V
620 .word PM_PREPWSTST_CORE_V
622 .word PM_PREPWSTST_CORE_P
624 .word PM_PREPWSTST_MPU_V
626 .word PM_PWSTCTRL_MPU_P
628 .word SCRATCHPAD_BASE_P
630 .word SRAM_BASE_P + 0x8000
645 cache_pred_disable_mask:
649 ENTRY(omap34xx_cpu_suspend_sz)
650 .word . - omap34xx_cpu_suspend