blob: 6840f1cde9eff8ad20ca9f0728316b48eb83eee2 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * Idle processing for ARMv7-based Qualcomm SoCs.
3 *
4 * Copyright (C) 2007 Google, Inc.
Pushkar Joshi64cae782012-12-15 18:59:03 -08005 * Copyright (c) 2007-2009, 2011-2013 The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/linkage.h>
19#include <linux/threads.h>
20#include <asm/assembler.h>
21
Steve Mucklefcece052012-02-18 20:09:58 -080022#include "idle.h"
Murali Nalajala73c13332012-05-15 11:30:59 +053023#include "idle-macros.S"
Steve Mucklefcece052012-02-18 20:09:58 -080024
Girish Mahadevan55944992012-10-26 11:03:07 -060025#ifdef CONFIG_MSM_SCM
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -060026#define SCM_SVC_BOOT 0x1
27#define SCM_CMD_TERMINATE_PC 0x2
28#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029
30ENTRY(msm_arch_idle)
Stepan Moskovchenkoae920e72012-07-03 19:10:44 -070031#ifdef CONFIG_ARCH_MSM_KRAIT
32 mrc p15, 0, r0, c0, c0, 0
33 bic r1, r0, #0xff
34 movw r2, #0x0400
35 movt r2, #0x511F
36 movw r3, #0x0600
37 movt r3, #0x510F
38 cmp r2, r1
39 cmpne r3, r1
40 bne go_wfi
41
42 mrs r0, cpsr
43 cpsid if
44
45 mrc p15, 7, r1, c15, c0, 5
46 bic r2, r1, #0x20000
47 mcr p15, 7, r2, c15, c0, 5
48 isb
49
50go_wfi:
51 wfi
52 bne wfi_done
53 mcr p15, 7, r1, c15, c0, 5
54 isb
55 msr cpsr_c, r0
56
57wfi_done:
58 bx lr
59#else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070060 wfi
Pratik Patelcbcc1f02011-11-08 12:58:00 -080061#ifdef CONFIG_ARCH_MSM8X60
62 mrc p14, 1, r1, c1, c5, 4 /* read ETM PDSR to clear sticky bit */
63 mrc p14, 0, r1, c1, c5, 4 /* read DBG PRSR to clear sticky bit */
64 isb
65#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066 bx lr
Stepan Moskovchenkoae920e72012-07-03 19:10:44 -070067#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068
69ENTRY(msm_pm_collapse)
70#if defined(CONFIG_MSM_FIQ_SUPPORT)
71 cpsid f
72#endif
73
Steve Mucklefcece052012-02-18 20:09:58 -080074 ldr r0, =msm_saved_state /* address of msm_saved_state ptr */
75 ldr r0, [r0] /* load ptr */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076#if (NR_CPUS >= 2)
77 mrc p15, 0, r1, c0, c0, 5 /* MPIDR */
78 ands r1, r1, #15 /* What CPU am I */
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -070079 mov r2, #CPU_SAVED_STATE_SIZE
80 mul r1, r1, r2
81 add r0, r0, r1
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082#endif
83
84 stmia r0!, {r4-r14}
85 mrc p15, 0, r1, c1, c0, 0 /* MMU control */
86 mrc p15, 0, r2, c2, c0, 0 /* TTBR0 */
87 mrc p15, 0, r3, c3, c0, 0 /* dacr */
88#ifdef CONFIG_ARCH_MSM_SCORPION
89 /* This instruction is not valid for non scorpion processors */
90 mrc p15, 3, r4, c15, c0, 3 /* L2CR1 is the L2 cache control reg 1 */
91#endif
92 mrc p15, 0, r5, c10, c2, 0 /* PRRR */
93 mrc p15, 0, r6, c10, c2, 1 /* NMRR */
94 mrc p15, 0, r7, c1, c0, 1 /* ACTLR */
95 mrc p15, 0, r8, c2, c0, 1 /* TTBR1 */
96 mrc p15, 0, r9, c13, c0, 3 /* TPIDRURO */
97 mrc p15, 0, ip, c13, c0, 1 /* context ID */
98 stmia r0!, {r1-r9, ip}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070099
Pushkar Joshi64cae782012-12-15 18:59:03 -0800100#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
Pratik Patel17f3b822011-11-21 12:41:47 -0800101 bl msm_jtag_save_state
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102#endif
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600103
104 ldr r0, =msm_pm_flush_l2_flag
105 ldr r0, [r0]
106 mov r1, #0
107 mcr p15, 2, r1, c0, c0, 0 /*CCSELR*/
Maheshkumar Sivasubramanian1d2b69c2011-11-17 10:26:09 -0700108 isb
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600109 mrc p15, 1, r1, c0, c0, 0 /*CCSIDR*/
110 mov r2, #1
111 and r1, r2, r1, ASR #30 /* Check if the cache is write back */
112 orr r1, r0, r1
113 cmp r1, #1
114 bne skip
115 bl v7_flush_dcache_all
Girish Mahadevan55944992012-10-26 11:03:07 -0600116 ldr r1, =msm_pm_flush_l2_fn
117 ldr r1, [r1]
118 cmp r1, #0
119 blxne r1
120
Steve Mucklefcece052012-02-18 20:09:58 -0800121skip:
Girish Mahadevan55944992012-10-26 11:03:07 -0600122 ldr r1, =msm_pm_disable_l2_fn
123 ldr r1, [r1]
124 cmp r1, #0
125 blxne r1
126 dmb
127
Mahesh Sivasubramaniancb396622012-03-14 14:50:37 -0600128 mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
129 and r0, r0, #15 /* what CPU am I */
130
131 ldr r1, =msm_pc_debug_counters /*load the IMEM debug location */
132 ldr r1, [r1]
133 cmp r1, #0
134 beq skip_pc_debug1
135 add r1, r1, r0, LSL #4 /* debug location for this CPU */
136 ldr r2, [r1]
137 add r2, #1
138 str r2, [r1]
139skip_pc_debug1:
140
Girish Mahadevan55944992012-10-26 11:03:07 -0600141#ifdef CONFIG_MSM_SCM
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600142 ldr r0, =SCM_SVC_BOOT
143 ldr r1, =SCM_CMD_TERMINATE_PC
Maheshkumar Sivasubramanian16588412011-10-13 12:16:23 -0600144 ldr r2, =msm_pm_flush_l2_flag
145 ldr r2, [r2]
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600146 bl scm_call_atomic1
147#else
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800148 mrc p15, 0, r4, c1, c0, 0 /* read current CR */
149 bic r0, r4, #(1 << 2) /* clear dcache bit */
150 bic r0, r0, #(1 << 12) /* clear icache bit */
151 mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
Murali Nalajala73c13332012-05-15 11:30:59 +0530152 isb
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800153
Murali Nalajala73c13332012-05-15 11:30:59 +0530154 SUSPEND_8x25_L2
Murali Nalajala93f29992012-03-21 15:59:27 +0530155 SET_SMP_COHERENCY OFF
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700156 wfi
Murali Nalajala3a6de242012-05-11 15:05:35 +0530157 DELAY_8x25 300
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800158
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600159 mcr p15, 0, r4, c1, c0, 0 /* restore d/i cache */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160 isb
Murali Nalajala73c13332012-05-15 11:30:59 +0530161 ENABLE_8x25_L2 /* enable only l2, no need to restore the reg back */
Murali Nalajala93f29992012-03-21 15:59:27 +0530162 SET_SMP_COHERENCY ON
Murali Nalajala73c13332012-05-15 11:30:59 +0530163#endif
164
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165#if defined(CONFIG_MSM_FIQ_SUPPORT)
166 cpsie f
167#endif
Mahesh Sivasubramaniancb396622012-03-14 14:50:37 -0600168 mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
169 and r0, r0, #15 /* what CPU am I */
170
171 ldr r1, =msm_pc_debug_counters /*load the IMEM debug location */
172 ldr r1, [r1]
173 cmp r1, #0
174 beq skip_pc_debug2
175 add r1, r1, r0, LSL #4 /* debug location for this CPU */
176 add r1, #8
177 ldr r2, [r1]
178 add r2, #1
179 str r2, [r1]
180
181skip_pc_debug2:
Girish Mahadevan55944992012-10-26 11:03:07 -0600182 ldr r1, =msm_pm_enable_l2_fn
183 ldr r1, [r1]
184 cmp r1, #0
185 blxne r1
186 dmb
Mahesh Sivasubramaniancb396622012-03-14 14:50:37 -0600187
Pushkar Joshi64cae782012-12-15 18:59:03 -0800188#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
Pratik Patel17f3b822011-11-21 12:41:47 -0800189 bl msm_jtag_restore_state
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190#endif
Steve Mucklefcece052012-02-18 20:09:58 -0800191 ldr r0, =msm_saved_state /* address of msm_saved_state ptr */
192 ldr r0, [r0] /* load ptr */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193#if (NR_CPUS >= 2)
194 mrc p15, 0, r1, c0, c0, 5 /* MPIDR */
195 ands r1, r1, #15 /* What CPU am I */
Praveen Chidambaram4b1e6f02012-02-11 16:17:30 -0700196 mov r2, #CPU_SAVED_STATE_SIZE
197 mul r2, r2, r1
198 add r0, r0, r2
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199#endif
Steve Mucklefcece052012-02-18 20:09:58 -0800200 ldmfd r0, {r4-r14} /* restore registers */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201 mov r0, #0 /* return power collapse failed */
202 bx lr
203
204ENTRY(msm_pm_collapse_exit)
205#if 0 /* serial debug */
206 mov r0, #0x80000016
207 mcr p15, 0, r0, c15, c2, 4
208 mov r0, #0xA9000000
209 add r0, r0, #0x00A00000 /* UART1 */
210 /*add r0, r0, #0x00C00000*/ /* UART3 */
211 mov r1, #'A'
212 str r1, [r0, #0x00C]
213#endif
Steve Mucklefcece052012-02-18 20:09:58 -0800214 ldr r1, =msm_saved_state_phys
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700215 ldr r2, =msm_pm_collapse_exit
216 adr r3, msm_pm_collapse_exit
217 add r1, r1, r3
218 sub r1, r1, r2
Steve Mucklefcece052012-02-18 20:09:58 -0800219 ldr r1, [r1]
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -0700220 add r1, r1, #CPU_SAVED_STATE_SIZE
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221#if (NR_CPUS >= 2)
222 mrc p15, 0, r2, c0, c0, 5 /* MPIDR */
223 ands r2, r2, #15 /* What CPU am I */
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -0700224 mov r3, #CPU_SAVED_STATE_SIZE
225 mul r2, r2, r3
226 add r1, r1, r2
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700227#endif
228
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700229 ldmdb r1!, {r2-r11}
230 mcr p15, 0, r4, c3, c0, 0 /* dacr */
231 mcr p15, 0, r3, c2, c0, 0 /* TTBR0 */
232#ifdef CONFIG_ARCH_MSM_SCORPION
233 /* This instruction is not valid for non scorpion processors */
234 mcr p15, 3, r5, c15, c0, 3 /* L2CR1 */
235#endif
236 mcr p15, 0, r6, c10, c2, 0 /* PRRR */
237 mcr p15, 0, r7, c10, c2, 1 /* NMRR */
238 mcr p15, 0, r8, c1, c0, 1 /* ACTLR */
239 mcr p15, 0, r9, c2, c0, 1 /* TTBR1 */
240 mcr p15, 0, r10, c13, c0, 3 /* TPIDRURO */
241 mcr p15, 0, r11, c13, c0, 1 /* context ID */
242 isb
243 ldmdb r1!, {r4-r14}
244 ldr r0, =msm_pm_pc_pgd
245 ldr r1, =msm_pm_collapse_exit
246 adr r3, msm_pm_collapse_exit
247 add r0, r0, r3
248 sub r0, r0, r1
249 ldr r0, [r0]
250 mrc p15, 0, r1, c2, c0, 0 /* save current TTBR0 */
251 and r3, r1, #0x7f /* mask to get TTB flags */
252 orr r0, r0, r3 /* add TTB flags to switch TTBR value */
253 mcr p15, 0, r0, c2, c0, 0 /* temporary switch TTBR0 */
254 isb
255 mcr p15, 0, r2, c1, c0, 0 /* MMU control */
256 isb
257msm_pm_mapped_pa:
258 /* Switch to virtual */
259 ldr r0, =msm_pm_pa_to_va
260 mov pc, r0
261msm_pm_pa_to_va:
262 mcr p15, 0, r1, c2, c0, 0 /* restore TTBR0 */
263 isb
264 mcr p15, 0, r3, c8, c7, 0 /* UTLBIALL */
265 mcr p15, 0, r3, c7, c5, 6 /* BPIALL */
266 dsb
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700267 isb
Murali Nalajala93f29992012-03-21 15:59:27 +0530268
Stepan Moskovchenko6fd9c922011-12-08 18:15:05 -0800269#ifdef CONFIG_ARCH_MSM_KRAIT
270 mrc p15, 0, r1, c0, c0, 0
271 ldr r3, =0xff00fc00
272 and r3, r1, r3
273 ldr r1, =0x51000400
274 cmp r3, r1
275 mrceq p15, 7, r3, c15, c0, 2
276 biceq r3, r3, #0x400
277 mcreq p15, 7, r3, c15, c0, 2
Murali Nalajala73c13332012-05-15 11:30:59 +0530278#else
279 RESUME_8x25_L2
280 SET_SMP_COHERENCY ON
Stepan Moskovchenko6fd9c922011-12-08 18:15:05 -0800281#endif
Murali Nalajala73c13332012-05-15 11:30:59 +0530282
Girish Mahadevan55944992012-10-26 11:03:07 -0600283 ldr r1, =msm_pm_enable_l2_fn
284 ldr r1, [r1]
285 cmp r1, #0
Steve Mucklec1421e32012-03-26 11:05:06 -0700286 stmfd sp!, {lr}
Girish Mahadevan55944992012-10-26 11:03:07 -0600287 blxne r1
288 dmb
Pushkar Joshi64cae782012-12-15 18:59:03 -0800289#if defined(CONFIG_MSM_JTAG) || defined(CONFIG_MSM_JTAG_MM)
Pratik Patel17f3b822011-11-21 12:41:47 -0800290 bl msm_jtag_restore_state
Steve Mucklec1421e32012-03-26 11:05:06 -0700291#endif
Girish Mahadevan55944992012-10-26 11:03:07 -0600292 ldmfd sp!, {lr}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700293 mov r0, #1
294 bx lr
295 nop
296 nop
297 nop
298 nop
299 nop
3001: b 1b
301
302ENTRY(msm_pm_boot_entry)
303 mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
304 and r0, r0, #15 /* what CPU am I */
305
Mahesh Sivasubramaniancb396622012-03-14 14:50:37 -0600306 ldr r1, =msm_pc_debug_counters_phys /*phys addr for IMEM reg */
307 ldr r2, =msm_pm_boot_entry
308 adr r3, msm_pm_boot_entry
309 add r1, r1, r3 /* translate virt to phys addr */
310 sub r1, r1, r2
311 ldr r1,[r1]
312
313 cmp r1, #0
314 beq skip_pc_debug3
315 add r1, r1, r0, LSL #4 /* debug location for this CPU */
316 add r1, #4 /* warmboot entry counter*/
317 ldr r2, [r1]
318 add r2, #1
319 str r2, [r1]
320
321skip_pc_debug3:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 ldr r1, =msm_pm_boot_vector
323 ldr r2, =msm_pm_boot_entry
324 adr r3, msm_pm_boot_entry
325 add r1, r1, r3 /* translate virt to phys addr */
326 sub r1, r1, r2
327
328 add r1, r1, r0, LSL #2 /* locate boot vector for our cpu */
329 ldr pc, [r1] /* jump */
330
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600331ENTRY(msm_pm_set_l2_flush_flag)
Praveen Chidambaramc594a092012-09-18 19:48:29 -0600332 ldr r1, =msm_pm_flush_l2_flag
333 str r0, [r1]
334 bx lr
335
336ENTRY(msm_pm_get_l2_flush_flag)
337 ldr r1, =msm_pm_flush_l2_flag
338 ldr r0, [r1]
339 bx lr
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600340
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700341 .data
342
343 .globl msm_pm_pc_pgd
344msm_pm_pc_pgd:
345 .long 0x0
346
Steve Mucklefcece052012-02-18 20:09:58 -0800347 .globl msm_saved_state
348msm_saved_state:
349 .long 0x0
350
351 .globl msm_saved_state_phys
352msm_saved_state_phys:
353 .long 0x0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700354
Steve Mucklec25a9362012-03-22 16:40:01 -0700355 .globl msm_pm_boot_vector
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356msm_pm_boot_vector:
357 .space 4 * NR_CPUS
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600358
Murali Nalajala93f29992012-03-21 15:59:27 +0530359 .globl target_type
360target_type:
361 .long 0x0
362
Murali Nalajala73c13332012-05-15 11:30:59 +0530363 .globl apps_power_collapse
364apps_power_collapse:
365 .long 0x0
366
367 .globl l2x0_base_addr
368l2x0_base_addr:
369 .long 0x0
370
Mahesh Sivasubramaniancb396622012-03-14 14:50:37 -0600371 .globl msm_pc_debug_counters_phys
372msm_pc_debug_counters_phys:
373 .long 0x0
374
375 .globl msm_pc_debug_counters
376msm_pc_debug_counters:
377 .long 0x0
378
Girish Mahadevan55944992012-10-26 11:03:07 -0600379 .globl msm_pm_enable_l2_fn
380msm_pm_enable_l2_fn:
381 .long 0x0
382
383 .globl msm_pm_disable_l2_fn
384msm_pm_disable_l2_fn:
385 .long 0x0
386
387 .globl msm_pm_flush_l2_fn
388msm_pm_flush_l2_fn:
389 .long 0x0
390
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600391/*
392 * Default the l2 flush flag to 1 so that caches are flushed during power
393 * collapse unless the L2 driver decides to flush them only during L2
394 * Power collapse.
395 */
396msm_pm_flush_l2_flag:
397 .long 0x1
Murali Nalajala73c13332012-05-15 11:30:59 +0530398
399/*
400 * Save & restore l2x0 registers while system is entering and resuming
401 * from Power Collapse.
402 * 1. aux_ctrl_save (0x0)
403 * 2. data_latency_ctrl (0x4)
404 * 3. prefetch control (0x8)
405 */
406l2x0_saved_ctrl_reg_val:
407 .space 4 * 3