blob: 50887c75a3b8763967a55c18dab525d2a68996c8 [file] [log] [blame]
Kevin Hilman8bd22942009-05-28 10:56:16 -07001/*
2 * linux/arch/arm/mach-omap2/sleep.S
3 *
4 * (C) Copyright 2007
5 * Texas Instruments
6 * Karthik Dasu <karthik-dp@ti.com>
7 *
8 * (C) Copyright 2004
9 * Texas Instruments, <www.ti.com>
10 * Richard Woodruff <r-woodruff2@ti.com>
11 *
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.
16 *
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.
21 *
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,
25 * MA 02111-1307 USA
26 */
27#include <linux/linkage.h>
28#include <asm/assembler.h>
29#include <mach/io.h>
Kevin Hilman8bd22942009-05-28 10:56:16 -070030
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +020031#include "cm.h"
Kevin Hilman8bd22942009-05-28 10:56:16 -070032#include "prm.h"
33#include "sdrc.h"
Paul Walmsley4814ced2010-10-08 11:40:20 -060034#include "control.h"
Kevin Hilman8bd22942009-05-28 10:56:16 -070035
Rajendra Nayaka89b6f02009-05-28 18:13:06 +053036#define SDRC_SCRATCHPAD_SEM_V 0xfa00291c
37
Kevin Hilman8bd22942009-05-28 10:56:16 -070038#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
39 OMAP3430_PM_PREPWSTST)
Tero Kristo0795a752008-10-13 17:58:50 +030040#define PM_PREPWSTST_CORE_P 0x48306AE8
Kevin Hilman8bd22942009-05-28 10:56:16 -070041#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
42 OMAP3430_PM_PREPWSTST)
Abhijit Pagare37903002010-01-26 20:12:51 -070043#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +020044#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -060045#define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST)
Tero Kristo27d59a42008-10-13 13:15:00 +030046#define SRAM_BASE_P 0x40200000
47#define CONTROL_STAT 0x480022F0
Nishanth Menon458e9992010-12-20 14:05:06 -060048#define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE\
49 + OMAP36XX_CONTROL_MEM_RTA_CTRL)
Kevin Hilman8bd22942009-05-28 10:56:16 -070050#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
51 * available */
Rajendra Nayak61255ab2008-09-26 17:49:56 +053052#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
53 + SCRATCHPAD_MEM_OFFS)
Kevin Hilman8bd22942009-05-28 10:56:16 -070054#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
Tero Kristo0795a752008-10-13 17:58:50 +030055#define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
56#define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0)
57#define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0)
58#define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
59#define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1)
60#define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1)
61#define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +020062#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
63#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
Kevin Hilman8bd22942009-05-28 10:56:16 -070064
Rajendra Nayaka89b6f02009-05-28 18:13:06 +053065 .text
Uwe Kleine-König46cd09a2010-06-11 12:16:57 +020066/* Function to acquire the semaphore in scratchpad */
Rajendra Nayaka89b6f02009-05-28 18:13:06 +053067ENTRY(lock_scratchpad_sem)
68 stmfd sp!, {lr} @ save registers on stack
69wait_sem:
70 mov r0,#1
71 ldr r1, sdrc_scratchpad_sem
72wait_loop:
73 ldr r2, [r1] @ load the lock value
74 cmp r2, r0 @ is the lock free ?
75 beq wait_loop @ not free...
76 swp r2, r0, [r1] @ semaphore free so lock it and proceed
77 cmp r2, r0 @ did we succeed ?
78 beq wait_sem @ no - try again
79 ldmfd sp!, {pc} @ restore regs and return
80sdrc_scratchpad_sem:
81 .word SDRC_SCRATCHPAD_SEM_V
82ENTRY(lock_scratchpad_sem_sz)
83 .word . - lock_scratchpad_sem
84
85 .text
86/* Function to release the scratchpad semaphore */
87ENTRY(unlock_scratchpad_sem)
88 stmfd sp!, {lr} @ save registers on stack
89 ldr r3, sdrc_scratchpad_sem
90 mov r2,#0
91 str r2,[r3]
92 ldmfd sp!, {pc} @ restore regs and return
93ENTRY(unlock_scratchpad_sem_sz)
94 .word . - unlock_scratchpad_sem
95
Kevin Hilman8bd22942009-05-28 10:56:16 -070096 .text
97/* Function call to get the restore pointer for resume from OFF */
98ENTRY(get_restore_pointer)
99 stmfd sp!, {lr} @ save registers on stack
100 adr r0, restore
101 ldmfd sp!, {pc} @ restore regs and return
102ENTRY(get_restore_pointer_sz)
Tero Kristo0795a752008-10-13 17:58:50 +0300103 .word . - get_restore_pointer
Nishanth Menon458e9992010-12-20 14:05:06 -0600104 .text
105/* Function call to get the restore pointer for 3630 resume from OFF */
106ENTRY(get_omap3630_restore_pointer)
107 stmfd sp!, {lr} @ save registers on stack
108 adr r0, restore_3630
109 ldmfd sp!, {pc} @ restore regs and return
110ENTRY(get_omap3630_restore_pointer_sz)
111 .word . - get_omap3630_restore_pointer
Tero Kristo0795a752008-10-13 17:58:50 +0300112
113 .text
Peter 'p2' De Schrijverc4236d22010-12-20 14:05:07 -0600114/*
115 * L2 cache needs to be toggled for stable OFF mode functionality on 3630.
116 * This function sets up a fflag that will allow for this toggling to take
117 * place on 3630. Hopefully some version in the future maynot need this
118 */
119ENTRY(enable_omap3630_toggle_l2_on_restore)
120 stmfd sp!, {lr} @ save registers on stack
121 /* Setup so that we will disable and enable l2 */
122 mov r1, #0x1
123 str r1, l2dis_3630
124 ldmfd sp!, {pc} @ restore regs and return
125
126 .text
Tero Kristo0795a752008-10-13 17:58:50 +0300127/* Function call to get the restore pointer for for ES3 to resume from OFF */
128ENTRY(get_es3_restore_pointer)
129 stmfd sp!, {lr} @ save registers on stack
130 adr r0, restore_es3
131 ldmfd sp!, {pc} @ restore regs and return
132ENTRY(get_es3_restore_pointer_sz)
133 .word . - get_es3_restore_pointer
134
135ENTRY(es3_sdrc_fix)
136 ldr r4, sdrc_syscfg @ get config addr
137 ldr r5, [r4] @ get value
138 tst r5, #0x100 @ is part access blocked
139 it eq
140 biceq r5, r5, #0x100 @ clear bit if set
141 str r5, [r4] @ write back change
142 ldr r4, sdrc_mr_0 @ get config addr
143 ldr r5, [r4] @ get value
144 str r5, [r4] @ write back change
145 ldr r4, sdrc_emr2_0 @ get config addr
146 ldr r5, [r4] @ get value
147 str r5, [r4] @ write back change
148 ldr r4, sdrc_manual_0 @ get config addr
149 mov r5, #0x2 @ autorefresh command
150 str r5, [r4] @ kick off refreshes
151 ldr r4, sdrc_mr_1 @ get config addr
152 ldr r5, [r4] @ get value
153 str r5, [r4] @ write back change
154 ldr r4, sdrc_emr2_1 @ get config addr
155 ldr r5, [r4] @ get value
156 str r5, [r4] @ write back change
157 ldr r4, sdrc_manual_1 @ get config addr
158 mov r5, #0x2 @ autorefresh command
159 str r5, [r4] @ kick off refreshes
160 bx lr
161sdrc_syscfg:
162 .word SDRC_SYSCONFIG_P
163sdrc_mr_0:
164 .word SDRC_MR_0_P
165sdrc_emr2_0:
166 .word SDRC_EMR2_0_P
167sdrc_manual_0:
168 .word SDRC_MANUAL_0_P
169sdrc_mr_1:
170 .word SDRC_MR_1_P
171sdrc_emr2_1:
172 .word SDRC_EMR2_1_P
173sdrc_manual_1:
174 .word SDRC_MANUAL_1_P
175ENTRY(es3_sdrc_fix_sz)
176 .word . - es3_sdrc_fix
Tero Kristo27d59a42008-10-13 13:15:00 +0300177
178/* Function to call rom code to save secure ram context */
179ENTRY(save_secure_ram_context)
180 stmfd sp!, {r1-r12, lr} @ save registers on stack
181save_secure_ram_debug:
182 /* b save_secure_ram_debug */ @ enable to debug save code
183 adr r3, api_params @ r3 points to parameters
184 str r0, [r3,#0x4] @ r0 has sdram address
185 ldr r12, high_mask
186 and r3, r3, r12
187 ldr r12, sram_phy_addr_mask
188 orr r3, r3, r12
189 mov r0, #25 @ set service ID for PPA
190 mov r12, r0 @ copy secure service ID in r12
191 mov r1, #0 @ set task id for ROM code in r1
Kalle Jokiniemiba50ea72009-03-26 15:59:00 +0200192 mov r2, #4 @ set some flags in r2, r6
Tero Kristo27d59a42008-10-13 13:15:00 +0300193 mov r6, #0xff
194 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
195 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
196 .word 0xE1600071 @ call SMI monitor (smi #1)
197 nop
198 nop
199 nop
200 nop
201 ldmfd sp!, {r1-r12, pc}
202sram_phy_addr_mask:
203 .word SRAM_BASE_P
204high_mask:
205 .word 0xffff
206api_params:
207 .word 0x4, 0x0, 0x0, 0x1, 0x1
208ENTRY(save_secure_ram_context_sz)
209 .word . - save_secure_ram_context
210
Kevin Hilman8bd22942009-05-28 10:56:16 -0700211/*
212 * Forces OMAP into idle state
213 *
214 * omap34xx_suspend() - This bit of code just executes the WFI
215 * for normal idles.
216 *
217 * Note: This code get's copied to internal SRAM at boot. When the OMAP
218 * wakes up it continues execution at the point it went to sleep.
219 */
220ENTRY(omap34xx_cpu_suspend)
221 stmfd sp!, {r0-r12, lr} @ save registers on stack
222loop:
223 /*b loop*/ @Enable to debug by stepping through code
224 /* r0 contains restore pointer in sdram */
225 /* r1 contains information about saving context */
226 ldr r4, sdrc_power @ read the SDRC_POWER register
227 ldr r5, [r4] @ read the contents of SDRC_POWER
228 orr r5, r5, #0x40 @ enable self refresh on idle req
229 str r5, [r4] @ write back to SDRC_POWER register
230
231 cmp r1, #0x0
232 /* If context save is required, do that and execute wfi */
233 bne save_context_wfi
234 /* Data memory barrier and Data sync barrier */
235 mov r1, #0
236 mcr p15, 0, r1, c7, c10, 4
237 mcr p15, 0, r1, c7, c10, 5
238
239 wfi @ wait for interrupt
240
241 nop
242 nop
243 nop
244 nop
245 nop
246 nop
247 nop
248 nop
249 nop
250 nop
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200251 bl wait_sdrc_ok
Kevin Hilman8bd22942009-05-28 10:56:16 -0700252
253 ldmfd sp!, {r0-r12, pc} @ restore regs and return
Tero Kristo0795a752008-10-13 17:58:50 +0300254restore_es3:
255 /*b restore_es3*/ @ Enable to debug restore code
256 ldr r5, pm_prepwstst_core_p
257 ldr r4, [r5]
258 and r4, r4, #0x3
259 cmp r4, #0x0 @ Check if previous power state of CORE is OFF
260 bne restore
261 adr r0, es3_sdrc_fix
262 ldr r1, sram_base
263 ldr r2, es3_sdrc_fix_sz
264 mov r2, r2, ror #2
265copy_to_sram:
266 ldmia r0!, {r3} @ val = *src
267 stmia r1!, {r3} @ *dst = val
268 subs r2, r2, #0x1 @ num_words--
269 bne copy_to_sram
270 ldr r1, sram_base
271 blx r1
Nishanth Menon458e9992010-12-20 14:05:06 -0600272 b restore
273
274restore_3630:
275 /*b restore_es3630*/ @ Enable to debug restore code
276 ldr r1, pm_prepwstst_core_p
277 ldr r2, [r1]
278 and r2, r2, #0x3
279 cmp r2, #0x0 @ Check if previous power state of CORE is OFF
280 bne restore
281 /* Disable RTA before giving control */
282 ldr r1, control_mem_rta
283 mov r2, #OMAP36XX_RTA_DISABLE
284 str r2, [r1]
285 /* Fall thru for the remaining logic */
Kevin Hilman8bd22942009-05-28 10:56:16 -0700286restore:
Rajendra Nayak61255ab2008-09-26 17:49:56 +0530287 /* b restore*/ @ Enable to debug restore code
Kevin Hilman8bd22942009-05-28 10:56:16 -0700288 /* Check what was the reason for mpu reset and store the reason in r9*/
289 /* 1 - Only L1 and logic lost */
290 /* 2 - Only L2 lost - In this case, we wont be here */
291 /* 3 - Both L1 and L2 lost */
292 ldr r1, pm_pwstctrl_mpu
293 ldr r2, [r1]
294 and r2, r2, #0x3
295 cmp r2, #0x0 @ Check if target power state was OFF or RET
296 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
297 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
298 bne logic_l1_restore
Peter 'p2' De Schrijverc4236d22010-12-20 14:05:07 -0600299
300 ldr r0, l2dis_3630
301 cmp r0, #0x1 @ should we disable L2 on 3630?
302 bne skipl2dis
303 mrc p15, 0, r0, c1, c0, 1
304 bic r0, r0, #2 @ disable L2 cache
305 mcr p15, 0, r0, c1, c0, 1
306skipl2dis:
Tero Kristo27d59a42008-10-13 13:15:00 +0300307 ldr r0, control_stat
308 ldr r1, [r0]
309 and r1, #0x700
310 cmp r1, #0x300
311 beq l2_inv_gp
312 mov r0, #40 @ set service ID for PPA
313 mov r12, r0 @ copy secure Service ID in r12
314 mov r1, #0 @ set task id for ROM code in r1
315 mov r2, #4 @ set some flags in r2, r6
316 mov r6, #0xff
317 adr r3, l2_inv_api_params @ r3 points to dummy parameters
318 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
319 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
320 .word 0xE1600071 @ call SMI monitor (smi #1)
321 /* Write to Aux control register to set some bits */
322 mov r0, #42 @ set service ID for PPA
323 mov r12, r0 @ copy secure Service ID in r12
324 mov r1, #0 @ set task id for ROM code in r1
325 mov r2, #4 @ set some flags in r2, r6
326 mov r6, #0xff
Tero Kristoa087cad2009-11-12 12:07:20 +0200327 ldr r4, scratchpad_base
328 ldr r3, [r4, #0xBC] @ r3 points to parameters
Tero Kristo27d59a42008-10-13 13:15:00 +0300329 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
330 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
331 .word 0xE1600071 @ call SMI monitor (smi #1)
332
Tero Kristo79dcfdd2009-11-12 12:07:22 +0200333#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
334 /* Restore L2 aux control register */
335 @ set service ID for PPA
336 mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
337 mov r12, r0 @ copy service ID in r12
338 mov r1, #0 @ set task ID for ROM code in r1
339 mov r2, #4 @ set some flags in r2, r6
340 mov r6, #0xff
341 ldr r4, scratchpad_base
342 ldr r3, [r4, #0xBC]
343 adds r3, r3, #8 @ r3 points to parameters
344 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
345 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
346 .word 0xE1600071 @ call SMI monitor (smi #1)
347#endif
Tero Kristo27d59a42008-10-13 13:15:00 +0300348 b logic_l1_restore
349l2_inv_api_params:
350 .word 0x1, 0x00
Tero Kristo27d59a42008-10-13 13:15:00 +0300351l2_inv_gp:
Kevin Hilman8bd22942009-05-28 10:56:16 -0700352 /* Execute smi to invalidate L2 cache */
353 mov r12, #0x1 @ set up to invalide L2
Tero Kristo27d59a42008-10-13 13:15:00 +0300354smi: .word 0xE1600070 @ Call SMI monitor (smieq)
355 /* Write to Aux control register to set some bits */
Tero Kristoa087cad2009-11-12 12:07:20 +0200356 ldr r4, scratchpad_base
357 ldr r3, [r4,#0xBC]
358 ldr r0, [r3,#4]
Tero Kristo27d59a42008-10-13 13:15:00 +0300359 mov r12, #0x3
360 .word 0xE1600070 @ Call SMI monitor (smieq)
Tero Kristo79dcfdd2009-11-12 12:07:22 +0200361 ldr r4, scratchpad_base
362 ldr r3, [r4,#0xBC]
363 ldr r0, [r3,#12]
364 mov r12, #0x2
365 .word 0xE1600070 @ Call SMI monitor (smieq)
Kevin Hilman8bd22942009-05-28 10:56:16 -0700366logic_l1_restore:
Peter 'p2' De Schrijverc4236d22010-12-20 14:05:07 -0600367 ldr r1, l2dis_3630
368 cmp r1, #0x1 @ Do we need to re-enable L2 on 3630?
369 bne skipl2reen
370 mrc p15, 0, r1, c1, c0, 1
371 orr r1, r1, #2 @ re-enable L2 cache
372 mcr p15, 0, r1, c1, c0, 1
373skipl2reen:
Kevin Hilman8bd22942009-05-28 10:56:16 -0700374 mov r1, #0
375 /* Invalidate all instruction caches to PoU
376 * and flush branch target cache */
377 mcr p15, 0, r1, c7, c5, 0
378
379 ldr r4, scratchpad_base
380 ldr r3, [r4,#0xBC]
Tero Kristo79dcfdd2009-11-12 12:07:22 +0200381 adds r3, r3, #16
Kevin Hilman8bd22942009-05-28 10:56:16 -0700382 ldmia r3!, {r4-r6}
383 mov sp, r4
384 msr spsr_cxsf, r5
385 mov lr, r6
386
387 ldmia r3!, {r4-r9}
388 /* Coprocessor access Control Register */
389 mcr p15, 0, r4, c1, c0, 2
390
391 /* TTBR0 */
392 MCR p15, 0, r5, c2, c0, 0
393 /* TTBR1 */
394 MCR p15, 0, r6, c2, c0, 1
395 /* Translation table base control register */
396 MCR p15, 0, r7, c2, c0, 2
397 /*domain access Control Register */
398 MCR p15, 0, r8, c3, c0, 0
399 /* data fault status Register */
400 MCR p15, 0, r9, c5, c0, 0
401
402 ldmia r3!,{r4-r8}
403 /* instruction fault status Register */
404 MCR p15, 0, r4, c5, c0, 1
405 /*Data Auxiliary Fault Status Register */
406 MCR p15, 0, r5, c5, c1, 0
407 /*Instruction Auxiliary Fault Status Register*/
408 MCR p15, 0, r6, c5, c1, 1
409 /*Data Fault Address Register */
410 MCR p15, 0, r7, c6, c0, 0
411 /*Instruction Fault Address Register*/
412 MCR p15, 0, r8, c6, c0, 2
413 ldmia r3!,{r4-r7}
414
415 /* user r/w thread and process ID */
416 MCR p15, 0, r4, c13, c0, 2
417 /* user ro thread and process ID */
418 MCR p15, 0, r5, c13, c0, 3
419 /*Privileged only thread and process ID */
420 MCR p15, 0, r6, c13, c0, 4
421 /* cache size selection */
422 MCR p15, 2, r7, c0, c0, 0
423 ldmia r3!,{r4-r8}
424 /* Data TLB lockdown registers */
425 MCR p15, 0, r4, c10, c0, 0
426 /* Instruction TLB lockdown registers */
427 MCR p15, 0, r5, c10, c0, 1
428 /* Secure or Nonsecure Vector Base Address */
429 MCR p15, 0, r6, c12, c0, 0
430 /* FCSE PID */
431 MCR p15, 0, r7, c13, c0, 0
432 /* Context PID */
433 MCR p15, 0, r8, c13, c0, 1
434
435 ldmia r3!,{r4-r5}
436 /* primary memory remap register */
437 MCR p15, 0, r4, c10, c2, 0
438 /*normal memory remap register */
439 MCR p15, 0, r5, c10, c2, 1
440
441 /* Restore cpsr */
442 ldmia r3!,{r4} /*load CPSR from SDRAM*/
443 msr cpsr, r4 /*store cpsr */
444
445 /* Enabling MMU here */
446 mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
447 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
448 and r7, #0x7
449 cmp r7, #0x0
450 beq usettbr0
451ttbr_error:
452 /* More work needs to be done to support N[0:2] value other than 0
453 * So looping here so that the error can be detected
454 */
455 b ttbr_error
456usettbr0:
457 mrc p15, 0, r2, c2, c0, 0
458 ldr r5, ttbrbit_mask
459 and r2, r5
460 mov r4, pc
461 ldr r5, table_index_mask
462 and r4, r5 /* r4 = 31 to 20 bits of pc */
463 /* Extract the value to be written to table entry */
464 ldr r1, table_entry
465 add r1, r1, r4 /* r1 has value to be written to table entry*/
466 /* Getting the address of table entry to modify */
467 lsr r4, #18
468 add r2, r4 /* r2 has the location which needs to be modified */
469 /* Storing previous entry of location being modified */
470 ldr r5, scratchpad_base
471 ldr r4, [r2]
472 str r4, [r5, #0xC0]
473 /* Modify the table entry */
474 str r1, [r2]
475 /* Storing address of entry being modified
476 * - will be restored after enabling MMU */
477 ldr r5, scratchpad_base
478 str r2, [r5, #0xC4]
479
480 mov r0, #0
481 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
482 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
483 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
484 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
485 /* Restore control register but dont enable caches here*/
486 /* Caches will be enabled after restoring MMU table entry */
487 ldmia r3!, {r4}
488 /* Store previous value of control register in scratchpad */
489 str r4, [r5, #0xC8]
490 ldr r2, cache_pred_disable_mask
491 and r4, r2
492 mcr p15, 0, r4, c1, c0, 0
493
494 ldmfd sp!, {r0-r12, pc} @ restore regs and return
495save_context_wfi:
496 /*b save_context_wfi*/ @ enable to debug save code
497 mov r8, r0 /* Store SDRAM address in r8 */
Tero Kristoa087cad2009-11-12 12:07:20 +0200498 mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
499 mov r4, #0x1 @ Number of parameters for restore call
Tero Kristo79dcfdd2009-11-12 12:07:22 +0200500 stmia r8!, {r4-r5} @ Push parameters for restore call
501 mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
502 stmia r8!, {r4-r5} @ Push parameters for restore call
Kevin Hilman8bd22942009-05-28 10:56:16 -0700503 /* Check what that target sleep state is:stored in r1*/
504 /* 1 - Only L1 and logic lost */
505 /* 2 - Only L2 lost */
506 /* 3 - Both L1 and L2 lost */
507 cmp r1, #0x2 /* Only L2 lost */
508 beq clean_l2
509 cmp r1, #0x1 /* L2 retained */
510 /* r9 stores whether to clean L2 or not*/
511 moveq r9, #0x0 /* Dont Clean L2 */
512 movne r9, #0x1 /* Clean L2 */
513l1_logic_lost:
514 /* Store sp and spsr to SDRAM */
515 mov r4, sp
516 mrs r5, spsr
517 mov r6, lr
518 stmia r8!, {r4-r6}
519 /* Save all ARM registers */
520 /* Coprocessor access control register */
521 mrc p15, 0, r6, c1, c0, 2
522 stmia r8!, {r6}
523 /* TTBR0, TTBR1 and Translation table base control */
524 mrc p15, 0, r4, c2, c0, 0
525 mrc p15, 0, r5, c2, c0, 1
526 mrc p15, 0, r6, c2, c0, 2
527 stmia r8!, {r4-r6}
528 /* Domain access control register, data fault status register,
529 and instruction fault status register */
530 mrc p15, 0, r4, c3, c0, 0
531 mrc p15, 0, r5, c5, c0, 0
532 mrc p15, 0, r6, c5, c0, 1
533 stmia r8!, {r4-r6}
534 /* Data aux fault status register, instruction aux fault status,
535 datat fault address register and instruction fault address register*/
536 mrc p15, 0, r4, c5, c1, 0
537 mrc p15, 0, r5, c5, c1, 1
538 mrc p15, 0, r6, c6, c0, 0
539 mrc p15, 0, r7, c6, c0, 2
540 stmia r8!, {r4-r7}
541 /* user r/w thread and process ID, user r/o thread and process ID,
542 priv only thread and process ID, cache size selection */
543 mrc p15, 0, r4, c13, c0, 2
544 mrc p15, 0, r5, c13, c0, 3
545 mrc p15, 0, r6, c13, c0, 4
546 mrc p15, 2, r7, c0, c0, 0
547 stmia r8!, {r4-r7}
548 /* Data TLB lockdown, instruction TLB lockdown registers */
549 mrc p15, 0, r5, c10, c0, 0
550 mrc p15, 0, r6, c10, c0, 1
551 stmia r8!, {r5-r6}
552 /* Secure or non secure vector base address, FCSE PID, Context PID*/
553 mrc p15, 0, r4, c12, c0, 0
554 mrc p15, 0, r5, c13, c0, 0
555 mrc p15, 0, r6, c13, c0, 1
556 stmia r8!, {r4-r6}
557 /* Primary remap, normal remap registers */
558 mrc p15, 0, r4, c10, c2, 0
559 mrc p15, 0, r5, c10, c2, 1
560 stmia r8!,{r4-r5}
561
562 /* Store current cpsr*/
563 mrs r2, cpsr
564 stmia r8!, {r2}
565
566 mrc p15, 0, r4, c1, c0, 0
567 /* save control register */
568 stmia r8!, {r4}
569clean_caches:
570 /* Clean Data or unified cache to POU*/
571 /* How to invalidate only L1 cache???? - #FIX_ME# */
572 /* mcr p15, 0, r11, c7, c11, 1 */
573 cmp r9, #1 /* Check whether L2 inval is required or not*/
574 bne skip_l2_inval
575clean_l2:
Richard Woodruff0bd40532010-12-20 14:05:03 -0600576 /*
577 * Jump out to kernel flush routine
578 * - reuse that code is better
579 * - it executes in a cached space so is faster than refetch per-block
580 * - should be faster and will change with kernel
581 * - 'might' have to copy address, load and jump to it
582 * - lr is used since we are running in SRAM currently.
583 */
584 ldr r1, kernel_flush
585 mov lr, pc
586 bx r1
587
Kevin Hilman8bd22942009-05-28 10:56:16 -0700588skip_l2_inval:
589 /* Data memory barrier and Data sync barrier */
590 mov r1, #0
591 mcr p15, 0, r1, c7, c10, 4
592 mcr p15, 0, r1, c7, c10, 5
593
594 wfi @ wait for interrupt
595 nop
596 nop
597 nop
598 nop
599 nop
600 nop
601 nop
602 nop
603 nop
604 nop
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200605 bl wait_sdrc_ok
Kevin Hilman8bd22942009-05-28 10:56:16 -0700606 /* restore regs and return */
607 ldmfd sp!, {r0-r12, pc}
608
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200609/* Make sure SDRC accesses are ok */
610wait_sdrc_ok:
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600611
612/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this. */
613 ldr r4, cm_idlest_ckgen
614wait_dpll3_lock:
615 ldr r5, [r4]
616 tst r5, #1
617 beq wait_dpll3_lock
618
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200619 ldr r4, cm_idlest1_core
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600620wait_sdrc_ready:
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200621 ldr r5, [r4]
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600622 tst r5, #0x2
623 bne wait_sdrc_ready
624 /* allow DLL powerdown upon hw idle req */
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200625 ldr r4, sdrc_power
626 ldr r5, [r4]
627 bic r5, r5, #0x40
628 str r5, [r4]
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600629is_dll_in_lock_mode:
630
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200631 /* Is dll in lock mode? */
632 ldr r4, sdrc_dlla_ctrl
633 ldr r5, [r4]
634 tst r5, #0x4
635 bxne lr
636 /* wait till dll locks */
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600637wait_dll_lock_timed:
638 ldr r4, wait_dll_lock_counter
639 add r4, r4, #1
640 str r4, wait_dll_lock_counter
641 ldr r4, sdrc_dlla_status
642 mov r6, #8 /* Wait 20uS for lock */
643wait_dll_lock:
644 subs r6, r6, #0x1
645 beq kick_dll
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200646 ldr r5, [r4]
647 and r5, r5, #0x4
648 cmp r5, #0x4
649 bne wait_dll_lock
650 bx lr
Kevin Hilman8bd22942009-05-28 10:56:16 -0700651
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600652 /* disable/reenable DLL if not locked */
653kick_dll:
654 ldr r4, sdrc_dlla_ctrl
655 ldr r5, [r4]
656 mov r6, r5
657 bic r6, #(1<<3) /* disable dll */
658 str r6, [r4]
659 dsb
660 orr r6, r6, #(1<<3) /* enable dll */
661 str r6, [r4]
662 dsb
663 ldr r4, kick_counter
664 add r4, r4, #1
665 str r4, kick_counter
666 b wait_dll_lock_timed
667
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200668cm_idlest1_core:
669 .word CM_IDLEST1_CORE_V
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600670cm_idlest_ckgen:
671 .word CM_IDLEST_CKGEN_V
Peter 'p2' De Schrijver89139dc2009-01-16 18:53:48 +0200672sdrc_dlla_status:
673 .word SDRC_DLLA_STATUS_V
674sdrc_dlla_ctrl:
675 .word SDRC_DLLA_CTRL_V
Kevin Hilman8bd22942009-05-28 10:56:16 -0700676pm_prepwstst_core:
677 .word PM_PREPWSTST_CORE_V
Tero Kristo0795a752008-10-13 17:58:50 +0300678pm_prepwstst_core_p:
679 .word PM_PREPWSTST_CORE_P
Kevin Hilman8bd22942009-05-28 10:56:16 -0700680pm_prepwstst_mpu:
681 .word PM_PREPWSTST_MPU_V
682pm_pwstctrl_mpu:
683 .word PM_PWSTCTRL_MPU_P
684scratchpad_base:
685 .word SCRATCHPAD_BASE_P
Tero Kristo0795a752008-10-13 17:58:50 +0300686sram_base:
687 .word SRAM_BASE_P + 0x8000
Kevin Hilman8bd22942009-05-28 10:56:16 -0700688sdrc_power:
689 .word SDRC_POWER_V
Kevin Hilman8bd22942009-05-28 10:56:16 -0700690clk_stabilize_delay:
691 .word 0x000001FF
692assoc_mask:
693 .word 0x3ff
694numset_mask:
695 .word 0x7fff
696ttbrbit_mask:
697 .word 0xFFFFC000
698table_index_mask:
699 .word 0xFFF00000
700table_entry:
701 .word 0x00000C02
702cache_pred_disable_mask:
703 .word 0xFFFFE7FB
Tero Kristo27d59a42008-10-13 13:15:00 +0300704control_stat:
705 .word CONTROL_STAT
Nishanth Menon458e9992010-12-20 14:05:06 -0600706control_mem_rta:
707 .word CONTROL_MEM_RTA_CTRL
Richard Woodruff0bd40532010-12-20 14:05:03 -0600708kernel_flush:
709 .word v7_flush_dcache_all
Peter 'p2' De Schrijverc4236d22010-12-20 14:05:07 -0600710l2dis_3630:
711 .word 0
Peter 'p2' De Schrijver9d93b8a22010-12-20 14:05:04 -0600712 /*
713 * When exporting to userspace while the counters are in SRAM,
714 * these 2 words need to be at the end to facilitate retrival!
715 */
716kick_counter:
717 .word 0
718wait_dll_lock_counter:
719 .word 0
Kevin Hilman8bd22942009-05-28 10:56:16 -0700720ENTRY(omap34xx_cpu_suspend_sz)
721 .word . - omap34xx_cpu_suspend