]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/arm/mach-omap2/sleep34xx.S
OMAP: PM: DMA context save/restore for off-mode support
[mirror_ubuntu-bionic-kernel.git] / arch / arm / mach-omap2 / sleep34xx.S
CommitLineData
8bd22949
KH
1/*
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>
ce491cf8 30#include <plat/control.h>
8bd22949
KH
31
32#include "prm.h"
33#include "sdrc.h"
34
35#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
36 OMAP3430_PM_PREPWSTST)
37#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
38 OMAP3430_PM_PREPWSTST)
61255ab9 39#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
8bd22949
KH
40#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
41 * available */
61255ab9
RN
42#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
43 + SCRATCHPAD_MEM_OFFS)
8bd22949
KH
44#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
45
46 .text
47/* Function call to get the restore pointer for resume from OFF */
48ENTRY(get_restore_pointer)
49 stmfd sp!, {lr} @ save registers on stack
50 adr r0, restore
51 ldmfd sp!, {pc} @ restore regs and return
52ENTRY(get_restore_pointer_sz)
53 .word . - get_restore_pointer_sz
54/*
55 * Forces OMAP into idle state
56 *
57 * omap34xx_suspend() - This bit of code just executes the WFI
58 * for normal idles.
59 *
60 * Note: This code get's copied to internal SRAM at boot. When the OMAP
61 * wakes up it continues execution at the point it went to sleep.
62 */
63ENTRY(omap34xx_cpu_suspend)
64 stmfd sp!, {r0-r12, lr} @ save registers on stack
65loop:
66 /*b loop*/ @Enable to debug by stepping through code
67 /* r0 contains restore pointer in sdram */
68 /* r1 contains information about saving context */
69 ldr r4, sdrc_power @ read the SDRC_POWER register
70 ldr r5, [r4] @ read the contents of SDRC_POWER
71 orr r5, r5, #0x40 @ enable self refresh on idle req
72 str r5, [r4] @ write back to SDRC_POWER register
73
74 cmp r1, #0x0
75 /* If context save is required, do that and execute wfi */
76 bne save_context_wfi
77 /* Data memory barrier and Data sync barrier */
78 mov r1, #0
79 mcr p15, 0, r1, c7, c10, 4
80 mcr p15, 0, r1, c7, c10, 5
81
82 wfi @ wait for interrupt
83
84 nop
85 nop
86 nop
87 nop
88 nop
89 nop
90 nop
91 nop
92 nop
93 nop
94 bl i_dll_wait
95
96 ldmfd sp!, {r0-r12, pc} @ restore regs and return
97restore:
61255ab9 98 /* b restore*/ @ Enable to debug restore code
8bd22949
KH
99 /* Check what was the reason for mpu reset and store the reason in r9*/
100 /* 1 - Only L1 and logic lost */
101 /* 2 - Only L2 lost - In this case, we wont be here */
102 /* 3 - Both L1 and L2 lost */
103 ldr r1, pm_pwstctrl_mpu
104 ldr r2, [r1]
105 and r2, r2, #0x3
106 cmp r2, #0x0 @ Check if target power state was OFF or RET
107 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
108 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
109 bne logic_l1_restore
110 /* Execute smi to invalidate L2 cache */
111 mov r12, #0x1 @ set up to invalide L2
112smi: .word 0xE1600070 @ Call SMI monitor (smieq)
113logic_l1_restore:
114 mov r1, #0
115 /* Invalidate all instruction caches to PoU
116 * and flush branch target cache */
117 mcr p15, 0, r1, c7, c5, 0
118
119 ldr r4, scratchpad_base
120 ldr r3, [r4,#0xBC]
121 ldmia r3!, {r4-r6}
122 mov sp, r4
123 msr spsr_cxsf, r5
124 mov lr, r6
125
126 ldmia r3!, {r4-r9}
127 /* Coprocessor access Control Register */
128 mcr p15, 0, r4, c1, c0, 2
129
130 /* TTBR0 */
131 MCR p15, 0, r5, c2, c0, 0
132 /* TTBR1 */
133 MCR p15, 0, r6, c2, c0, 1
134 /* Translation table base control register */
135 MCR p15, 0, r7, c2, c0, 2
136 /*domain access Control Register */
137 MCR p15, 0, r8, c3, c0, 0
138 /* data fault status Register */
139 MCR p15, 0, r9, c5, c0, 0
140
141 ldmia r3!,{r4-r8}
142 /* instruction fault status Register */
143 MCR p15, 0, r4, c5, c0, 1
144 /*Data Auxiliary Fault Status Register */
145 MCR p15, 0, r5, c5, c1, 0
146 /*Instruction Auxiliary Fault Status Register*/
147 MCR p15, 0, r6, c5, c1, 1
148 /*Data Fault Address Register */
149 MCR p15, 0, r7, c6, c0, 0
150 /*Instruction Fault Address Register*/
151 MCR p15, 0, r8, c6, c0, 2
152 ldmia r3!,{r4-r7}
153
154 /* user r/w thread and process ID */
155 MCR p15, 0, r4, c13, c0, 2
156 /* user ro thread and process ID */
157 MCR p15, 0, r5, c13, c0, 3
158 /*Privileged only thread and process ID */
159 MCR p15, 0, r6, c13, c0, 4
160 /* cache size selection */
161 MCR p15, 2, r7, c0, c0, 0
162 ldmia r3!,{r4-r8}
163 /* Data TLB lockdown registers */
164 MCR p15, 0, r4, c10, c0, 0
165 /* Instruction TLB lockdown registers */
166 MCR p15, 0, r5, c10, c0, 1
167 /* Secure or Nonsecure Vector Base Address */
168 MCR p15, 0, r6, c12, c0, 0
169 /* FCSE PID */
170 MCR p15, 0, r7, c13, c0, 0
171 /* Context PID */
172 MCR p15, 0, r8, c13, c0, 1
173
174 ldmia r3!,{r4-r5}
175 /* primary memory remap register */
176 MCR p15, 0, r4, c10, c2, 0
177 /*normal memory remap register */
178 MCR p15, 0, r5, c10, c2, 1
179
180 /* Restore cpsr */
181 ldmia r3!,{r4} /*load CPSR from SDRAM*/
182 msr cpsr, r4 /*store cpsr */
183
184 /* Enabling MMU here */
185 mrc p15, 0, r7, c2, c0, 2 /* Read TTBRControl */
186 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1*/
187 and r7, #0x7
188 cmp r7, #0x0
189 beq usettbr0
190ttbr_error:
191 /* More work needs to be done to support N[0:2] value other than 0
192 * So looping here so that the error can be detected
193 */
194 b ttbr_error
195usettbr0:
196 mrc p15, 0, r2, c2, c0, 0
197 ldr r5, ttbrbit_mask
198 and r2, r5
199 mov r4, pc
200 ldr r5, table_index_mask
201 and r4, r5 /* r4 = 31 to 20 bits of pc */
202 /* Extract the value to be written to table entry */
203 ldr r1, table_entry
204 add r1, r1, r4 /* r1 has value to be written to table entry*/
205 /* Getting the address of table entry to modify */
206 lsr r4, #18
207 add r2, r4 /* r2 has the location which needs to be modified */
208 /* Storing previous entry of location being modified */
209 ldr r5, scratchpad_base
210 ldr r4, [r2]
211 str r4, [r5, #0xC0]
212 /* Modify the table entry */
213 str r1, [r2]
214 /* Storing address of entry being modified
215 * - will be restored after enabling MMU */
216 ldr r5, scratchpad_base
217 str r2, [r5, #0xC4]
218
219 mov r0, #0
220 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
221 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
222 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
223 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
224 /* Restore control register but dont enable caches here*/
225 /* Caches will be enabled after restoring MMU table entry */
226 ldmia r3!, {r4}
227 /* Store previous value of control register in scratchpad */
228 str r4, [r5, #0xC8]
229 ldr r2, cache_pred_disable_mask
230 and r4, r2
231 mcr p15, 0, r4, c1, c0, 0
232
233 ldmfd sp!, {r0-r12, pc} @ restore regs and return
234save_context_wfi:
235 /*b save_context_wfi*/ @ enable to debug save code
236 mov r8, r0 /* Store SDRAM address in r8 */
237 /* Check what that target sleep state is:stored in r1*/
238 /* 1 - Only L1 and logic lost */
239 /* 2 - Only L2 lost */
240 /* 3 - Both L1 and L2 lost */
241 cmp r1, #0x2 /* Only L2 lost */
242 beq clean_l2
243 cmp r1, #0x1 /* L2 retained */
244 /* r9 stores whether to clean L2 or not*/
245 moveq r9, #0x0 /* Dont Clean L2 */
246 movne r9, #0x1 /* Clean L2 */
247l1_logic_lost:
248 /* Store sp and spsr to SDRAM */
249 mov r4, sp
250 mrs r5, spsr
251 mov r6, lr
252 stmia r8!, {r4-r6}
253 /* Save all ARM registers */
254 /* Coprocessor access control register */
255 mrc p15, 0, r6, c1, c0, 2
256 stmia r8!, {r6}
257 /* TTBR0, TTBR1 and Translation table base control */
258 mrc p15, 0, r4, c2, c0, 0
259 mrc p15, 0, r5, c2, c0, 1
260 mrc p15, 0, r6, c2, c0, 2
261 stmia r8!, {r4-r6}
262 /* Domain access control register, data fault status register,
263 and instruction fault status register */
264 mrc p15, 0, r4, c3, c0, 0
265 mrc p15, 0, r5, c5, c0, 0
266 mrc p15, 0, r6, c5, c0, 1
267 stmia r8!, {r4-r6}
268 /* Data aux fault status register, instruction aux fault status,
269 datat fault address register and instruction fault address register*/
270 mrc p15, 0, r4, c5, c1, 0
271 mrc p15, 0, r5, c5, c1, 1
272 mrc p15, 0, r6, c6, c0, 0
273 mrc p15, 0, r7, c6, c0, 2
274 stmia r8!, {r4-r7}
275 /* user r/w thread and process ID, user r/o thread and process ID,
276 priv only thread and process ID, cache size selection */
277 mrc p15, 0, r4, c13, c0, 2
278 mrc p15, 0, r5, c13, c0, 3
279 mrc p15, 0, r6, c13, c0, 4
280 mrc p15, 2, r7, c0, c0, 0
281 stmia r8!, {r4-r7}
282 /* Data TLB lockdown, instruction TLB lockdown registers */
283 mrc p15, 0, r5, c10, c0, 0
284 mrc p15, 0, r6, c10, c0, 1
285 stmia r8!, {r5-r6}
286 /* Secure or non secure vector base address, FCSE PID, Context PID*/
287 mrc p15, 0, r4, c12, c0, 0
288 mrc p15, 0, r5, c13, c0, 0
289 mrc p15, 0, r6, c13, c0, 1
290 stmia r8!, {r4-r6}
291 /* Primary remap, normal remap registers */
292 mrc p15, 0, r4, c10, c2, 0
293 mrc p15, 0, r5, c10, c2, 1
294 stmia r8!,{r4-r5}
295
296 /* Store current cpsr*/
297 mrs r2, cpsr
298 stmia r8!, {r2}
299
300 mrc p15, 0, r4, c1, c0, 0
301 /* save control register */
302 stmia r8!, {r4}
303clean_caches:
304 /* Clean Data or unified cache to POU*/
305 /* How to invalidate only L1 cache???? - #FIX_ME# */
306 /* mcr p15, 0, r11, c7, c11, 1 */
307 cmp r9, #1 /* Check whether L2 inval is required or not*/
308 bne skip_l2_inval
309clean_l2:
310 /* read clidr */
311 mrc p15, 1, r0, c0, c0, 1
312 /* extract loc from clidr */
313 ands r3, r0, #0x7000000
314 /* left align loc bit field */
315 mov r3, r3, lsr #23
316 /* if loc is 0, then no need to clean */
317 beq finished
318 /* start clean at cache level 0 */
319 mov r10, #0
320loop1:
321 /* work out 3x current cache level */
322 add r2, r10, r10, lsr #1
323 /* extract cache type bits from clidr*/
324 mov r1, r0, lsr r2
325 /* mask of the bits for current cache only */
326 and r1, r1, #7
327 /* see what cache we have at this level */
328 cmp r1, #2
329 /* skip if no cache, or just i-cache */
330 blt skip
331 /* select current cache level in cssr */
332 mcr p15, 2, r10, c0, c0, 0
333 /* isb to sych the new cssr&csidr */
334 isb
335 /* read the new csidr */
336 mrc p15, 1, r1, c0, c0, 0
337 /* extract the length of the cache lines */
338 and r2, r1, #7
339 /* add 4 (line length offset) */
340 add r2, r2, #4
341 ldr r4, assoc_mask
342 /* find maximum number on the way size */
343 ands r4, r4, r1, lsr #3
344 /* find bit position of way size increment */
345 clz r5, r4
346 ldr r7, numset_mask
347 /* extract max number of the index size*/
348 ands r7, r7, r1, lsr #13
349loop2:
350 mov r9, r4
351 /* create working copy of max way size*/
352loop3:
353 /* factor way and cache number into r11 */
354 orr r11, r10, r9, lsl r5
355 /* factor index number into r11 */
356 orr r11, r11, r7, lsl r2
357 /*clean & invalidate by set/way */
358 mcr p15, 0, r11, c7, c10, 2
359 /* decrement the way*/
360 subs r9, r9, #1
361 bge loop3
362 /*decrement the index */
363 subs r7, r7, #1
364 bge loop2
365skip:
366 add r10, r10, #2
367 /* increment cache number */
368 cmp r3, r10
369 bgt loop1
370finished:
371 /*swith back to cache level 0 */
372 mov r10, #0
373 /* select current cache level in cssr */
374 mcr p15, 2, r10, c0, c0, 0
375 isb
376skip_l2_inval:
377 /* Data memory barrier and Data sync barrier */
378 mov r1, #0
379 mcr p15, 0, r1, c7, c10, 4
380 mcr p15, 0, r1, c7, c10, 5
381
382 wfi @ wait for interrupt
383 nop
384 nop
385 nop
386 nop
387 nop
388 nop
389 nop
390 nop
391 nop
392 nop
393 bl i_dll_wait
394 /* restore regs and return */
395 ldmfd sp!, {r0-r12, pc}
396
397i_dll_wait:
398 ldr r4, clk_stabilize_delay
399
400i_dll_delay:
401 subs r4, r4, #0x1
402 bne i_dll_delay
403 ldr r4, sdrc_power
404 ldr r5, [r4]
405 bic r5, r5, #0x40
406 str r5, [r4]
407 bx lr
408pm_prepwstst_core:
409 .word PM_PREPWSTST_CORE_V
410pm_prepwstst_mpu:
411 .word PM_PREPWSTST_MPU_V
412pm_pwstctrl_mpu:
413 .word PM_PWSTCTRL_MPU_P
414scratchpad_base:
415 .word SCRATCHPAD_BASE_P
416sdrc_power:
417 .word SDRC_POWER_V
8bd22949
KH
418clk_stabilize_delay:
419 .word 0x000001FF
420assoc_mask:
421 .word 0x3ff
422numset_mask:
423 .word 0x7fff
424ttbrbit_mask:
425 .word 0xFFFFC000
426table_index_mask:
427 .word 0xFFF00000
428table_entry:
429 .word 0x00000C02
430cache_pred_disable_mask:
431 .word 0xFFFFE7FB
432ENTRY(omap34xx_cpu_suspend_sz)
433 .word . - omap34xx_cpu_suspend