Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux/fpc-iii.git] / arch / arm / mach-omap2 / sleep44xx.S
blob9086ce03ae12a00fa500553b80f68902c0fc852a
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  */
12 #include <linux/linkage.h>
13 #include <asm/smp_scu.h>
14 #include <asm/memory.h>
15 #include <asm/hardware/cache-l2x0.h>
17 #include "omap-secure.h"
19 #include "common.h"
20 #include "omap44xx.h"
21 #include "omap4-sar-layout.h"
23 #if defined(CONFIG_SMP) && defined(CONFIG_PM)
25 .macro  DO_SMC
26         dsb
27         smc     #0
28         dsb
29 .endm
31 ppa_zero_params:
32         .word           0x0
34 ppa_por_params:
35         .word           1, 0
37 #ifdef CONFIG_ARCH_OMAP4
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  */
66 ENTRY(omap4_finish_suspend)
67         stmfd   sp!, {r4-r12, lr}
68         cmp     r0, #0x0
69         beq     do_WFI                          @ No lowpower state, jump to WFI
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}
85 skip_secure_l1_clean:
86         bl      v7_flush_dcache_all
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
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
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
128 scu_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
135 skip_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]
171 wait:
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
181 l2x_sync:
182         bl      omap4_get_l2cache_base
183         mov     r2, r0
184         mov     r0, #0x0
185         str     r0, [r2, #L2X0_CACHE_SYNC]
186 sync:
187         ldr     r0, [r2, #L2X0_CACHE_SYNC]
188         ands    r0, r0, #0x1
189         bne     sync
190 #endif
192 do_WFI:
193         bl      omap_do_wfi
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
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
228 scu_gp_clear:
229         bl      omap4_get_scu_base
230         mov     r1, #SCU_PM_NORMAL
231         bl      scu_power_mode
232 skip_scu_gp_clear:
233         isb
234         dsb
235         ldmfd   sp!, {r4-r12, pc}
236 ENDPROC(omap4_finish_suspend)
239  * ============================
240  * == CPU resume entry point ==
241  * ============================
243  * void omap4_cpu_resume(void)
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  */
250 ENTRY(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
266 ppa_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
277 enable_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
283 skip_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
313 set_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
318 set_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
326 skip_l2en:
327 #endif
329         b       cpu_resume                      @ Jump to generic resume
330 ENDPROC(omap4_cpu_resume)
331 #endif  /* CONFIG_ARCH_OMAP4 */
333 #endif  /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
335 #ifndef CONFIG_OMAP4_ERRATA_I688
336 ENTRY(omap_bus_sync)
337         mov     pc, lr
338 ENDPROC(omap_bus_sync)
339 #endif
341 ENTRY(omap_do_wfi)
342         stmfd   sp!, {lr}
343         /* Drain interconnect write buffers. */
344         bl omap_bus_sync
346         /*
347          * Execute an ISB instruction to ensure that all of the
348          * CP15 register changes have been committed.
349          */
350         isb
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
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
385         ldmfd   sp!, {pc}
386 ENDPROC(omap_do_wfi)