Loading...
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * OMAP44xx sleep code.
4 *
5 * Copyright (C) 2011 Texas Instruments, Inc.
6 * Santosh Shilimkar <santosh.shilimkar@ti.com>
7 */
8
9#include <linux/linkage.h>
10#include <asm/assembler.h>
11#include <asm/smp_scu.h>
12#include <asm/page.h>
13#include <asm/hardware/cache-l2x0.h>
14
15#include "omap-secure.h"
16
17#include "common.h"
18#include "omap44xx.h"
19#include "omap4-sar-layout.h"
20
21 .arch armv7-a
22
23#if defined(CONFIG_SMP) && defined(CONFIG_PM)
24
25 .arch_extension sec
26.macro DO_SMC
27 dsb
28 smc #0
29 dsb
30.endm
31
32#ifdef CONFIG_ARCH_OMAP4
33
34/*
35 * =============================
36 * == CPU suspend finisher ==
37 * =============================
38 *
39 * void omap4_finish_suspend(unsigned long cpu_state)
40 *
41 * This function code saves the CPU context and performs the CPU
42 * power down sequence. Calling WFI effectively changes the CPU
43 * power domains states to the desired target power state.
44 *
45 * @cpu_state : contains context save state (r0)
46 * 0 - No context lost
47 * 1 - CPUx L1 and logic lost: MPUSS CSWR
48 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
49 * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
50 * @return: This function never returns for CPU OFF and DORMANT power states.
51 * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
52 * from this follows a full CPU reset path via ROM code to CPU restore code.
53 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
54 * It returns to the caller for CPU INACTIVE and ON power states or in case
55 * CPU failed to transition to targeted OFF/DORMANT state.
56 *
57 * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save
58 * stack frame and it expects the caller to take care of it. Hence the entire
59 * stack frame is saved to avoid possible stack corruption.
60 */
61ENTRY(omap4_finish_suspend)
62 stmfd sp!, {r4-r12, lr}
63 cmp r0, #0x0
64 beq do_WFI @ No lowpower state, jump to WFI
65
66 /*
67 * Flush all data from the L1 data cache before disabling
68 * SCTLR.C bit.
69 */
70 bl omap4_get_sar_ram_base
71 ldr r9, [r0, #OMAP_TYPE_OFFSET]
72 cmp r9, #0x1 @ Check for HS device
73 bne skip_secure_l1_clean
74 mov r0, #SCU_PM_NORMAL
75 mov r1, #0xFF @ clean seucre L1
76 stmfd r13!, {r4-r12, r14}
77 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
78 DO_SMC
79 ldmfd r13!, {r4-r12, r14}
80skip_secure_l1_clean:
81 bl v7_flush_dcache_all
82
83 /*
84 * Clear the SCTLR.C bit to prevent further data cache
85 * allocation. Clearing SCTLR.C would make all the data accesses
86 * strongly ordered and would not hit the cache.
87 */
88 mrc p15, 0, r0, c1, c0, 0
89 bic r0, r0, #(1 << 2) @ Disable the C bit
90 mcr p15, 0, r0, c1, c0, 0
91 isb
92
93 bl v7_invalidate_l1
94
95 /*
96 * Switch the CPU from Symmetric Multiprocessing (SMP) mode
97 * to AsymmetricMultiprocessing (AMP) mode by programming
98 * the SCU power status to DORMANT or OFF mode.
99 * This enables the CPU to be taken out of coherency by
100 * preventing the CPU from receiving cache, TLB, or BTB
101 * maintenance operations broadcast by other CPUs in the cluster.
102 */
103 bl omap4_get_sar_ram_base
104 mov r8, r0
105 ldr r9, [r8, #OMAP_TYPE_OFFSET]
106 cmp r9, #0x1 @ Check for HS device
107 bne scu_gp_set
108 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
109 ands r0, r0, #0x0f
110 ldreq r0, [r8, #SCU_OFFSET0]
111 ldrne r0, [r8, #SCU_OFFSET1]
112 mov r1, #0x00
113 stmfd r13!, {r4-r12, r14}
114 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
115 DO_SMC
116 ldmfd r13!, {r4-r12, r14}
117 b skip_scu_gp_set
118scu_gp_set:
119 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
120 ands r0, r0, #0x0f
121 ldreq r1, [r8, #SCU_OFFSET0]
122 ldrne r1, [r8, #SCU_OFFSET1]
123 bl omap4_get_scu_base
124 bl scu_power_mode
125skip_scu_gp_set:
126 mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
127 tst r0, #(1 << 18)
128 mrcne p15, 0, r0, c1, c0, 1
129 bicne r0, r0, #(1 << 6) @ Disable SMP bit
130 mcrne p15, 0, r0, c1, c0, 1
131 isb
132 dsb
133#ifdef CONFIG_CACHE_L2X0
134 /*
135 * Clean and invalidate the L2 cache.
136 * Common cache-l2x0.c functions can't be used here since it
137 * uses spinlocks. We are out of coherency here with data cache
138 * disabled. The spinlock implementation uses exclusive load/store
139 * instruction which can fail without data cache being enabled.
140 * OMAP4 hardware doesn't support exclusive monitor which can
141 * overcome exclusive access issue. Because of this, CPU can
142 * lead to deadlock.
143 */
144 bl omap4_get_sar_ram_base
145 mov r8, r0
146 mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
147 ands r5, r5, #0x0f
148 ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR
149 ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory.
150 cmp r0, #3
151 bne do_WFI
152#ifdef CONFIG_PL310_ERRATA_727915
153 mov r0, #0x03
154 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
155 DO_SMC
156#endif
157 bl omap4_get_l2cache_base
158 mov r2, r0
159 ldr r0, =0xffff
160 str r0, [r2, #L2X0_CLEAN_INV_WAY]
161wait:
162 ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
163 ldr r1, =0xffff
164 ands r0, r0, r1
165 bne wait
166#ifdef CONFIG_PL310_ERRATA_727915
167 mov r0, #0x00
168 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
169 DO_SMC
170#endif
171l2x_sync:
172 bl omap4_get_l2cache_base
173 mov r2, r0
174 mov r0, #0x0
175 str r0, [r2, #L2X0_CACHE_SYNC]
176sync:
177 ldr r0, [r2, #L2X0_CACHE_SYNC]
178 ands r0, r0, #0x1
179 bne sync
180#endif
181
182do_WFI:
183 bl omap_do_wfi
184
185 /*
186 * CPU is here when it failed to enter OFF/DORMANT or
187 * no low power state was attempted.
188 */
189 mrc p15, 0, r0, c1, c0, 0
190 tst r0, #(1 << 2) @ Check C bit enabled?
191 orreq r0, r0, #(1 << 2) @ Enable the C bit
192 mcreq p15, 0, r0, c1, c0, 0
193 isb
194
195 /*
196 * Ensure the CPU power state is set to NORMAL in
197 * SCU power state so that CPU is back in coherency.
198 * In non-coherent mode CPU can lock-up and lead to
199 * system deadlock.
200 */
201 mrc p15, 0, r0, c1, c0, 1
202 tst r0, #(1 << 6) @ Check SMP bit enabled?
203 orreq r0, r0, #(1 << 6)
204 mcreq p15, 0, r0, c1, c0, 1
205 isb
206 bl omap4_get_sar_ram_base
207 mov r8, r0
208 ldr r9, [r8, #OMAP_TYPE_OFFSET]
209 cmp r9, #0x1 @ Check for HS device
210 bne scu_gp_clear
211 mov r0, #SCU_PM_NORMAL
212 mov r1, #0x00
213 stmfd r13!, {r4-r12, r14}
214 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
215 DO_SMC
216 ldmfd r13!, {r4-r12, r14}
217 b skip_scu_gp_clear
218scu_gp_clear:
219 bl omap4_get_scu_base
220 mov r1, #SCU_PM_NORMAL
221 bl scu_power_mode
222skip_scu_gp_clear:
223 isb
224 dsb
225 ldmfd sp!, {r4-r12, pc}
226ENDPROC(omap4_finish_suspend)
227
228/*
229 * ============================
230 * == CPU resume entry point ==
231 * ============================
232 *
233 * void omap4_cpu_resume(void)
234 *
235 * ROM code jumps to this function while waking up from CPU
236 * OFF or DORMANT state. Physical address of the function is
237 * stored in the SAR RAM while entering to OFF or DORMANT mode.
238 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
239 */
240ENTRY(omap4_cpu_resume)
241 /*
242 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
243 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
244 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
245 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
246 * OMAP443X GP devices- SMP bit isn't accessible.
247 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
248 */
249 ldr r8, =OMAP44XX_SAR_RAM_BASE
250 ldr r9, [r8, #OMAP_TYPE_OFFSET]
251 cmp r9, #0x1 @ Skip if GP device
252 bne skip_ns_smp_enable
253 mrc p15, 0, r0, c0, c0, 5
254 ands r0, r0, #0x0f
255 beq skip_ns_smp_enable
256ppa_actrl_retry:
257 mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
258 adr r1, ppa_zero_params_offset
259 ldr r3, [r1]
260 add r3, r3, r1 @ Pointer to ppa_zero_params
261 mov r1, #0x0 @ Process ID
262 mov r2, #0x4 @ Flag
263 mov r6, #0xff
264 mov r12, #0x00 @ Secure Service ID
265 DO_SMC
266 cmp r0, #0x0 @ API returns 0 on success.
267 beq enable_smp_bit
268 b ppa_actrl_retry
269enable_smp_bit:
270 mrc p15, 0, r0, c1, c0, 1
271 tst r0, #(1 << 6) @ Check SMP bit enabled?
272 orreq r0, r0, #(1 << 6)
273 mcreq p15, 0, r0, c1, c0, 1
274 isb
275skip_ns_smp_enable:
276#ifdef CONFIG_CACHE_L2X0
277 /*
278 * Restore the L2 AUXCTRL and enable the L2 cache.
279 * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL
280 * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL
281 * register r0 contains value to be programmed.
282 * L2 cache is already invalidate by ROM code as part
283 * of MPUSS OFF wakeup path.
284 */
285 ldr r2, =OMAP44XX_L2CACHE_BASE
286 ldr r0, [r2, #L2X0_CTRL]
287 and r0, #0x0f
288 cmp r0, #1
289 beq skip_l2en @ Skip if already enabled
290 ldr r3, =OMAP44XX_SAR_RAM_BASE
291 ldr r1, [r3, #OMAP_TYPE_OFFSET]
292 cmp r1, #0x1 @ Check for HS device
293 bne set_gp_por
294 ldr r0, =OMAP4_PPA_L2_POR_INDEX
295 ldr r1, =OMAP44XX_SAR_RAM_BASE
296 ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
297 adr r1, ppa_por_params_offset
298 ldr r3, [r1]
299 add r3, r3, r1 @ Pointer to ppa_por_params
300 str r4, [r3, #0x04]
301 mov r1, #0x0 @ Process ID
302 mov r2, #0x4 @ Flag
303 mov r6, #0xff
304 mov r12, #0x00 @ Secure Service ID
305 DO_SMC
306 b set_aux_ctrl
307set_gp_por:
308 ldr r1, =OMAP44XX_SAR_RAM_BASE
309 ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
310 ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
311 DO_SMC
312set_aux_ctrl:
313 ldr r1, =OMAP44XX_SAR_RAM_BASE
314 ldr r0, [r1, #L2X0_AUXCTRL_OFFSET]
315 ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
316 DO_SMC
317 mov r0, #0x1
318 ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
319 DO_SMC
320skip_l2en:
321#endif
322
323 b cpu_resume @ Jump to generic resume
324ppa_por_params_offset:
325 .long ppa_por_params - .
326ENDPROC(omap4_cpu_resume)
327#endif /* CONFIG_ARCH_OMAP4 */
328
329#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
330
331ENTRY(omap_do_wfi)
332 stmfd sp!, {lr}
333#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
334 /* Drain interconnect write buffers. */
335 bl omap_interconnect_sync
336#endif
337
338 /*
339 * Execute an ISB instruction to ensure that all of the
340 * CP15 register changes have been committed.
341 */
342 isb
343
344 /*
345 * Execute a barrier instruction to ensure that all cache,
346 * TLB and branch predictor maintenance operations issued
347 * by any CPU in the cluster have completed.
348 */
349 dsb
350 dmb
351
352 /*
353 * Execute a WFI instruction and wait until the
354 * STANDBYWFI output is asserted to indicate that the
355 * CPU is in idle and low power state. CPU can specualatively
356 * prefetch the instructions so add NOPs after WFI. Sixteen
357 * NOPs as per Cortex-A9 pipeline.
358 */
359 wfi @ Wait For Interrupt
360 nop
361 nop
362 nop
363 nop
364 nop
365 nop
366 nop
367 nop
368 nop
369 nop
370 nop
371 nop
372 nop
373 nop
374 nop
375 nop
376
377 ldmfd sp!, {pc}
378ppa_zero_params_offset:
379 .long ppa_zero_params - .
380ENDPROC(omap_do_wfi)
381
382 .data
383 .align 2
384ppa_zero_params:
385 .word 0
386
387ppa_por_params:
388 .word 1, 0
1/*
2 * OMAP44xx sleep code.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software,you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/linkage.h>
13#include <asm/smp_scu.h>
14#include <asm/memory.h>
15#include <asm/hardware/cache-l2x0.h>
16
17#include "omap-secure.h"
18
19#include "common.h"
20#include "omap44xx.h"
21#include "omap4-sar-layout.h"
22
23#if defined(CONFIG_SMP) && defined(CONFIG_PM)
24
25.macro DO_SMC
26 dsb
27 smc #0
28 dsb
29.endm
30
31ppa_zero_params:
32 .word 0x0
33
34ppa_por_params:
35 .word 1, 0
36
37#ifdef CONFIG_ARCH_OMAP4
38
39/*
40 * =============================
41 * == CPU suspend finisher ==
42 * =============================
43 *
44 * void omap4_finish_suspend(unsigned long cpu_state)
45 *
46 * This function code saves the CPU context and performs the CPU
47 * power down sequence. Calling WFI effectively changes the CPU
48 * power domains states to the desired target power state.
49 *
50 * @cpu_state : contains context save state (r0)
51 * 0 - No context lost
52 * 1 - CPUx L1 and logic lost: MPUSS CSWR
53 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
54 * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
55 * @return: This function never returns for CPU OFF and DORMANT power states.
56 * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
57 * from this follows a full CPU reset path via ROM code to CPU restore code.
58 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
59 * It returns to the caller for CPU INACTIVE and ON power states or in case
60 * CPU failed to transition to targeted OFF/DORMANT state.
61 *
62 * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save
63 * stack frame and it expects the caller to take care of it. Hence the entire
64 * stack frame is saved to avoid possible stack corruption.
65 */
66ENTRY(omap4_finish_suspend)
67 stmfd sp!, {r4-r12, lr}
68 cmp r0, #0x0
69 beq do_WFI @ No lowpower state, jump to WFI
70
71 /*
72 * Flush all data from the L1 data cache before disabling
73 * SCTLR.C bit.
74 */
75 bl omap4_get_sar_ram_base
76 ldr r9, [r0, #OMAP_TYPE_OFFSET]
77 cmp r9, #0x1 @ Check for HS device
78 bne skip_secure_l1_clean
79 mov r0, #SCU_PM_NORMAL
80 mov r1, #0xFF @ clean seucre L1
81 stmfd r13!, {r4-r12, r14}
82 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
83 DO_SMC
84 ldmfd r13!, {r4-r12, r14}
85skip_secure_l1_clean:
86 bl v7_flush_dcache_all
87
88 /*
89 * Clear the SCTLR.C bit to prevent further data cache
90 * allocation. Clearing SCTLR.C would make all the data accesses
91 * strongly ordered and would not hit the cache.
92 */
93 mrc p15, 0, r0, c1, c0, 0
94 bic r0, r0, #(1 << 2) @ Disable the C bit
95 mcr p15, 0, r0, c1, c0, 0
96 isb
97
98 /*
99 * Invalidate L1 data cache. Even though only invalidate is
100 * necessary exported flush API is used here. Doing clean
101 * on already clean cache would be almost NOP.
102 */
103 bl v7_flush_dcache_all
104
105 /*
106 * Switch the CPU from Symmetric Multiprocessing (SMP) mode
107 * to AsymmetricMultiprocessing (AMP) mode by programming
108 * the SCU power status to DORMANT or OFF mode.
109 * This enables the CPU to be taken out of coherency by
110 * preventing the CPU from receiving cache, TLB, or BTB
111 * maintenance operations broadcast by other CPUs in the cluster.
112 */
113 bl omap4_get_sar_ram_base
114 mov r8, r0
115 ldr r9, [r8, #OMAP_TYPE_OFFSET]
116 cmp r9, #0x1 @ Check for HS device
117 bne scu_gp_set
118 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
119 ands r0, r0, #0x0f
120 ldreq r0, [r8, #SCU_OFFSET0]
121 ldrne r0, [r8, #SCU_OFFSET1]
122 mov r1, #0x00
123 stmfd r13!, {r4-r12, r14}
124 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
125 DO_SMC
126 ldmfd r13!, {r4-r12, r14}
127 b skip_scu_gp_set
128scu_gp_set:
129 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
130 ands r0, r0, #0x0f
131 ldreq r1, [r8, #SCU_OFFSET0]
132 ldrne r1, [r8, #SCU_OFFSET1]
133 bl omap4_get_scu_base
134 bl scu_power_mode
135skip_scu_gp_set:
136 mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
137 tst r0, #(1 << 18)
138 mrcne p15, 0, r0, c1, c0, 1
139 bicne r0, r0, #(1 << 6) @ Disable SMP bit
140 mcrne p15, 0, r0, c1, c0, 1
141 isb
142 dsb
143#ifdef CONFIG_CACHE_L2X0
144 /*
145 * Clean and invalidate the L2 cache.
146 * Common cache-l2x0.c functions can't be used here since it
147 * uses spinlocks. We are out of coherency here with data cache
148 * disabled. The spinlock implementation uses exclusive load/store
149 * instruction which can fail without data cache being enabled.
150 * OMAP4 hardware doesn't support exclusive monitor which can
151 * overcome exclusive access issue. Because of this, CPU can
152 * lead to deadlock.
153 */
154 bl omap4_get_sar_ram_base
155 mov r8, r0
156 mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
157 ands r5, r5, #0x0f
158 ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR
159 ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory.
160 cmp r0, #3
161 bne do_WFI
162#ifdef CONFIG_PL310_ERRATA_727915
163 mov r0, #0x03
164 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
165 DO_SMC
166#endif
167 bl omap4_get_l2cache_base
168 mov r2, r0
169 ldr r0, =0xffff
170 str r0, [r2, #L2X0_CLEAN_INV_WAY]
171wait:
172 ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
173 ldr r1, =0xffff
174 ands r0, r0, r1
175 bne wait
176#ifdef CONFIG_PL310_ERRATA_727915
177 mov r0, #0x00
178 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
179 DO_SMC
180#endif
181l2x_sync:
182 bl omap4_get_l2cache_base
183 mov r2, r0
184 mov r0, #0x0
185 str r0, [r2, #L2X0_CACHE_SYNC]
186sync:
187 ldr r0, [r2, #L2X0_CACHE_SYNC]
188 ands r0, r0, #0x1
189 bne sync
190#endif
191
192do_WFI:
193 bl omap_do_wfi
194
195 /*
196 * CPU is here when it failed to enter OFF/DORMANT or
197 * no low power state was attempted.
198 */
199 mrc p15, 0, r0, c1, c0, 0
200 tst r0, #(1 << 2) @ Check C bit enabled?
201 orreq r0, r0, #(1 << 2) @ Enable the C bit
202 mcreq p15, 0, r0, c1, c0, 0
203 isb
204
205 /*
206 * Ensure the CPU power state is set to NORMAL in
207 * SCU power state so that CPU is back in coherency.
208 * In non-coherent mode CPU can lock-up and lead to
209 * system deadlock.
210 */
211 mrc p15, 0, r0, c1, c0, 1
212 tst r0, #(1 << 6) @ Check SMP bit enabled?
213 orreq r0, r0, #(1 << 6)
214 mcreq p15, 0, r0, c1, c0, 1
215 isb
216 bl omap4_get_sar_ram_base
217 mov r8, r0
218 ldr r9, [r8, #OMAP_TYPE_OFFSET]
219 cmp r9, #0x1 @ Check for HS device
220 bne scu_gp_clear
221 mov r0, #SCU_PM_NORMAL
222 mov r1, #0x00
223 stmfd r13!, {r4-r12, r14}
224 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
225 DO_SMC
226 ldmfd r13!, {r4-r12, r14}
227 b skip_scu_gp_clear
228scu_gp_clear:
229 bl omap4_get_scu_base
230 mov r1, #SCU_PM_NORMAL
231 bl scu_power_mode
232skip_scu_gp_clear:
233 isb
234 dsb
235 ldmfd sp!, {r4-r12, pc}
236ENDPROC(omap4_finish_suspend)
237
238/*
239 * ============================
240 * == CPU resume entry point ==
241 * ============================
242 *
243 * void omap4_cpu_resume(void)
244 *
245 * ROM code jumps to this function while waking up from CPU
246 * OFF or DORMANT state. Physical address of the function is
247 * stored in the SAR RAM while entering to OFF or DORMANT mode.
248 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
249 */
250ENTRY(omap4_cpu_resume)
251 /*
252 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
253 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
254 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
255 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
256 * OMAP443X GP devices- SMP bit isn't accessible.
257 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
258 */
259 ldr r8, =OMAP44XX_SAR_RAM_BASE
260 ldr r9, [r8, #OMAP_TYPE_OFFSET]
261 cmp r9, #0x1 @ Skip if GP device
262 bne skip_ns_smp_enable
263 mrc p15, 0, r0, c0, c0, 5
264 ands r0, r0, #0x0f
265 beq skip_ns_smp_enable
266ppa_actrl_retry:
267 mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
268 adr r3, ppa_zero_params @ Pointer to parameters
269 mov r1, #0x0 @ Process ID
270 mov r2, #0x4 @ Flag
271 mov r6, #0xff
272 mov r12, #0x00 @ Secure Service ID
273 DO_SMC
274 cmp r0, #0x0 @ API returns 0 on success.
275 beq enable_smp_bit
276 b ppa_actrl_retry
277enable_smp_bit:
278 mrc p15, 0, r0, c1, c0, 1
279 tst r0, #(1 << 6) @ Check SMP bit enabled?
280 orreq r0, r0, #(1 << 6)
281 mcreq p15, 0, r0, c1, c0, 1
282 isb
283skip_ns_smp_enable:
284#ifdef CONFIG_CACHE_L2X0
285 /*
286 * Restore the L2 AUXCTRL and enable the L2 cache.
287 * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL
288 * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL
289 * register r0 contains value to be programmed.
290 * L2 cache is already invalidate by ROM code as part
291 * of MPUSS OFF wakeup path.
292 */
293 ldr r2, =OMAP44XX_L2CACHE_BASE
294 ldr r0, [r2, #L2X0_CTRL]
295 and r0, #0x0f
296 cmp r0, #1
297 beq skip_l2en @ Skip if already enabled
298 ldr r3, =OMAP44XX_SAR_RAM_BASE
299 ldr r1, [r3, #OMAP_TYPE_OFFSET]
300 cmp r1, #0x1 @ Check for HS device
301 bne set_gp_por
302 ldr r0, =OMAP4_PPA_L2_POR_INDEX
303 ldr r1, =OMAP44XX_SAR_RAM_BASE
304 ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
305 adr r3, ppa_por_params
306 str r4, [r3, #0x04]
307 mov r1, #0x0 @ Process ID
308 mov r2, #0x4 @ Flag
309 mov r6, #0xff
310 mov r12, #0x00 @ Secure Service ID
311 DO_SMC
312 b set_aux_ctrl
313set_gp_por:
314 ldr r1, =OMAP44XX_SAR_RAM_BASE
315 ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
316 ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
317 DO_SMC
318set_aux_ctrl:
319 ldr r1, =OMAP44XX_SAR_RAM_BASE
320 ldr r0, [r1, #L2X0_AUXCTRL_OFFSET]
321 ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
322 DO_SMC
323 mov r0, #0x1
324 ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
325 DO_SMC
326skip_l2en:
327#endif
328
329 b cpu_resume @ Jump to generic resume
330ENDPROC(omap4_cpu_resume)
331#endif /* CONFIG_ARCH_OMAP4 */
332
333#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
334
335#ifndef CONFIG_OMAP4_ERRATA_I688
336ENTRY(omap_bus_sync)
337 mov pc, lr
338ENDPROC(omap_bus_sync)
339#endif
340
341ENTRY(omap_do_wfi)
342 stmfd sp!, {lr}
343 /* Drain interconnect write buffers. */
344 bl omap_bus_sync
345
346 /*
347 * Execute an ISB instruction to ensure that all of the
348 * CP15 register changes have been committed.
349 */
350 isb
351
352 /*
353 * Execute a barrier instruction to ensure that all cache,
354 * TLB and branch predictor maintenance operations issued
355 * by any CPU in the cluster have completed.
356 */
357 dsb
358 dmb
359
360 /*
361 * Execute a WFI instruction and wait until the
362 * STANDBYWFI output is asserted to indicate that the
363 * CPU is in idle and low power state. CPU can specualatively
364 * prefetch the instructions so add NOPs after WFI. Sixteen
365 * NOPs as per Cortex-A9 pipeline.
366 */
367 wfi @ Wait For Interrupt
368 nop
369 nop
370 nop
371 nop
372 nop
373 nop
374 nop
375 nop
376 nop
377 nop
378 nop
379 nop
380 nop
381 nop
382 nop
383 nop
384
385 ldmfd sp!, {pc}
386ENDPROC(omap_do_wfi)