blob: 515727c219a56c708de6883d3a354f22f1396777 [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.
Pratik Patel17f3b822011-11-21 12:41:47 -08005 * Copyright (c) 2007-2009, 2011-2012 Code Aurora Forum. 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"
23
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -060024#ifdef CONFIG_ARCH_MSM_KRAIT
25#define SCM_SVC_BOOT 0x1
26#define SCM_CMD_TERMINATE_PC 0x2
27#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070028
29ENTRY(msm_arch_idle)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070030 wfi
Pratik Patelcbcc1f02011-11-08 12:58:00 -080031#ifdef CONFIG_ARCH_MSM8X60
32 mrc p14, 1, r1, c1, c5, 4 /* read ETM PDSR to clear sticky bit */
33 mrc p14, 0, r1, c1, c5, 4 /* read DBG PRSR to clear sticky bit */
34 isb
35#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070036 bx lr
37
38ENTRY(msm_pm_collapse)
39#if defined(CONFIG_MSM_FIQ_SUPPORT)
40 cpsid f
41#endif
42
Steve Mucklefcece052012-02-18 20:09:58 -080043 ldr r0, =msm_saved_state /* address of msm_saved_state ptr */
44 ldr r0, [r0] /* load ptr */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045#if (NR_CPUS >= 2)
46 mrc p15, 0, r1, c0, c0, 5 /* MPIDR */
47 ands r1, r1, #15 /* What CPU am I */
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -070048 mov r2, #CPU_SAVED_STATE_SIZE
49 mul r1, r1, r2
50 add r0, r0, r1
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070051#endif
52
53 stmia r0!, {r4-r14}
54 mrc p15, 0, r1, c1, c0, 0 /* MMU control */
55 mrc p15, 0, r2, c2, c0, 0 /* TTBR0 */
56 mrc p15, 0, r3, c3, c0, 0 /* dacr */
57#ifdef CONFIG_ARCH_MSM_SCORPION
58 /* This instruction is not valid for non scorpion processors */
59 mrc p15, 3, r4, c15, c0, 3 /* L2CR1 is the L2 cache control reg 1 */
60#endif
61 mrc p15, 0, r5, c10, c2, 0 /* PRRR */
62 mrc p15, 0, r6, c10, c2, 1 /* NMRR */
63 mrc p15, 0, r7, c1, c0, 1 /* ACTLR */
64 mrc p15, 0, r8, c2, c0, 1 /* TTBR1 */
65 mrc p15, 0, r9, c13, c0, 3 /* TPIDRURO */
66 mrc p15, 0, ip, c13, c0, 1 /* context ID */
67 stmia r0!, {r1-r9, ip}
68#ifdef CONFIG_MSM_CPU_AVS
69 mrc p15, 7, r1, c15, c1, 7 /* AVSCSR is the Adaptive Voltage Scaling
70 * Control and Status Register */
71 mrc p15, 7, r2, c15, c0, 6 /* AVSDSCR is the Adaptive Voltage
72 * Scaling Delay Synthesizer Control
73 * Register */
74#ifndef CONFIG_ARCH_MSM_KRAIT
75 mrc p15, 7, r3, c15, c1, 0 /* TSCSR is the Temperature Status and
76 * Control Register
77 */
78#endif
79
80 stmia r0!, {r1-r3}
81#endif
82
Pratik Patel17f3b822011-11-21 12:41:47 -080083#ifdef CONFIG_MSM_JTAG
84 bl msm_jtag_save_state
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085#endif
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -060086
87 ldr r0, =msm_pm_flush_l2_flag
88 ldr r0, [r0]
89 mov r1, #0
90 mcr p15, 2, r1, c0, c0, 0 /*CCSELR*/
Maheshkumar Sivasubramanian1d2b69c2011-11-17 10:26:09 -070091 isb
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -060092 mrc p15, 1, r1, c0, c0, 0 /*CCSIDR*/
93 mov r2, #1
94 and r1, r2, r1, ASR #30 /* Check if the cache is write back */
95 orr r1, r0, r1
96 cmp r1, #1
97 bne skip
98 bl v7_flush_dcache_all
Steve Mucklefcece052012-02-18 20:09:58 -080099skip:
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600100#ifdef CONFIG_ARCH_MSM_KRAIT
101 ldr r0, =SCM_SVC_BOOT
102 ldr r1, =SCM_CMD_TERMINATE_PC
Maheshkumar Sivasubramanian16588412011-10-13 12:16:23 -0600103 ldr r2, =msm_pm_flush_l2_flag
104 ldr r2, [r2]
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600105 bl scm_call_atomic1
106#else
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800107 mrc p15, 0, r4, c1, c0, 0 /* read current CR */
108 bic r0, r4, #(1 << 2) /* clear dcache bit */
109 bic r0, r0, #(1 << 12) /* clear icache bit */
110 mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
111 dsb
112
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700113 wfi
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800114
Maheshkumar Sivasubramanianfa1d0dd2011-07-26 16:02:55 -0600115 mcr p15, 0, r4, c1, c0, 0 /* restore d/i cache */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700116 isb
Stepan Moskovchenko34dc00f2012-01-28 19:31:41 -0800117#endif
118
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700119
120#if defined(CONFIG_MSM_FIQ_SUPPORT)
121 cpsie f
122#endif
Pratik Patel17f3b822011-11-21 12:41:47 -0800123#ifdef CONFIG_MSM_JTAG
124 bl msm_jtag_restore_state
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125#endif
Steve Mucklefcece052012-02-18 20:09:58 -0800126 ldr r0, =msm_saved_state /* address of msm_saved_state ptr */
127 ldr r0, [r0] /* load ptr */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128#if (NR_CPUS >= 2)
129 mrc p15, 0, r1, c0, c0, 5 /* MPIDR */
130 ands r1, r1, #15 /* What CPU am I */
Praveen Chidambaram4b1e6f02012-02-11 16:17:30 -0700131 mov r2, #CPU_SAVED_STATE_SIZE
132 mul r2, r2, r1
133 add r0, r0, r2
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134#endif
135
Steve Mucklefcece052012-02-18 20:09:58 -0800136 ldmfd r0, {r4-r14} /* restore registers */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 mov r0, #0 /* return power collapse failed */
138 bx lr
139
140ENTRY(msm_pm_collapse_exit)
141#if 0 /* serial debug */
142 mov r0, #0x80000016
143 mcr p15, 0, r0, c15, c2, 4
144 mov r0, #0xA9000000
145 add r0, r0, #0x00A00000 /* UART1 */
146 /*add r0, r0, #0x00C00000*/ /* UART3 */
147 mov r1, #'A'
148 str r1, [r0, #0x00C]
149#endif
Steve Mucklefcece052012-02-18 20:09:58 -0800150 ldr r1, =msm_saved_state_phys
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700151 ldr r2, =msm_pm_collapse_exit
152 adr r3, msm_pm_collapse_exit
153 add r1, r1, r3
154 sub r1, r1, r2
Steve Mucklefcece052012-02-18 20:09:58 -0800155 ldr r1, [r1]
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -0700156 add r1, r1, #CPU_SAVED_STATE_SIZE
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700157#if (NR_CPUS >= 2)
158 mrc p15, 0, r2, c0, c0, 5 /* MPIDR */
159 ands r2, r2, #15 /* What CPU am I */
Mahesh Sivasubramanian0ff37e72011-12-15 14:12:31 -0700160 mov r3, #CPU_SAVED_STATE_SIZE
161 mul r2, r2, r3
162 add r1, r1, r2
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163#endif
164
165#ifdef CONFIG_MSM_CPU_AVS
166 ldmdb r1!, {r2-r4}
167#ifndef CONFIG_ARCH_MSM_KRAIT
168 mcr p15, 7, r4, c15, c1, 0 /* TSCSR */
169#endif
170 mcr p15, 7, r3, c15, c0, 6 /* AVSDSCR */
171 mcr p15, 7, r2, c15, c1, 7 /* AVSCSR */
172#endif
173 ldmdb r1!, {r2-r11}
174 mcr p15, 0, r4, c3, c0, 0 /* dacr */
175 mcr p15, 0, r3, c2, c0, 0 /* TTBR0 */
176#ifdef CONFIG_ARCH_MSM_SCORPION
177 /* This instruction is not valid for non scorpion processors */
178 mcr p15, 3, r5, c15, c0, 3 /* L2CR1 */
179#endif
180 mcr p15, 0, r6, c10, c2, 0 /* PRRR */
181 mcr p15, 0, r7, c10, c2, 1 /* NMRR */
182 mcr p15, 0, r8, c1, c0, 1 /* ACTLR */
183 mcr p15, 0, r9, c2, c0, 1 /* TTBR1 */
184 mcr p15, 0, r10, c13, c0, 3 /* TPIDRURO */
185 mcr p15, 0, r11, c13, c0, 1 /* context ID */
186 isb
187 ldmdb r1!, {r4-r14}
188 ldr r0, =msm_pm_pc_pgd
189 ldr r1, =msm_pm_collapse_exit
190 adr r3, msm_pm_collapse_exit
191 add r0, r0, r3
192 sub r0, r0, r1
193 ldr r0, [r0]
194 mrc p15, 0, r1, c2, c0, 0 /* save current TTBR0 */
195 and r3, r1, #0x7f /* mask to get TTB flags */
196 orr r0, r0, r3 /* add TTB flags to switch TTBR value */
197 mcr p15, 0, r0, c2, c0, 0 /* temporary switch TTBR0 */
198 isb
199 mcr p15, 0, r2, c1, c0, 0 /* MMU control */
200 isb
201msm_pm_mapped_pa:
202 /* Switch to virtual */
203 ldr r0, =msm_pm_pa_to_va
204 mov pc, r0
205msm_pm_pa_to_va:
206 mcr p15, 0, r1, c2, c0, 0 /* restore TTBR0 */
207 isb
208 mcr p15, 0, r3, c8, c7, 0 /* UTLBIALL */
209 mcr p15, 0, r3, c7, c5, 6 /* BPIALL */
210 dsb
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 isb
Stepan Moskovchenko6fd9c922011-12-08 18:15:05 -0800212#ifdef CONFIG_ARCH_MSM_KRAIT
213 mrc p15, 0, r1, c0, c0, 0
214 ldr r3, =0xff00fc00
215 and r3, r1, r3
216 ldr r1, =0x51000400
217 cmp r3, r1
218 mrceq p15, 7, r3, c15, c0, 2
219 biceq r3, r3, #0x400
220 mcreq p15, 7, r3, c15, c0, 2
221#endif
Pratik Patel17f3b822011-11-21 12:41:47 -0800222#ifdef CONFIG_MSM_JTAG
Steve Mucklec1421e32012-03-26 11:05:06 -0700223 stmfd sp!, {lr}
Pratik Patel17f3b822011-11-21 12:41:47 -0800224 bl msm_jtag_restore_state
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225 ldmfd sp!, {lr}
Steve Mucklec1421e32012-03-26 11:05:06 -0700226#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700227 mov r0, #1
228 bx lr
229 nop
230 nop
231 nop
232 nop
233 nop
2341: b 1b
235
236ENTRY(msm_pm_boot_entry)
237 mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
238 and r0, r0, #15 /* what CPU am I */
239
240 ldr r1, =msm_pm_boot_vector
241 ldr r2, =msm_pm_boot_entry
242 adr r3, msm_pm_boot_entry
243 add r1, r1, r3 /* translate virt to phys addr */
244 sub r1, r1, r2
245
246 add r1, r1, r0, LSL #2 /* locate boot vector for our cpu */
247 ldr pc, [r1] /* jump */
248
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600249ENTRY(msm_pm_set_l2_flush_flag)
250 ldr r1, =msm_pm_flush_l2_flag
251 str r0, [r1]
252 bx lr
253
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700254 .data
255
256 .globl msm_pm_pc_pgd
257msm_pm_pc_pgd:
258 .long 0x0
259
Steve Mucklefcece052012-02-18 20:09:58 -0800260 .globl msm_saved_state
261msm_saved_state:
262 .long 0x0
263
264 .globl msm_saved_state_phys
265msm_saved_state_phys:
266 .long 0x0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700267
Steve Mucklec25a9362012-03-22 16:40:01 -0700268 .globl msm_pm_boot_vector
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700269msm_pm_boot_vector:
270 .space 4 * NR_CPUS
Maheshkumar Sivasubramaniana012e092011-08-18 10:13:03 -0600271
272/*
273 * Default the l2 flush flag to 1 so that caches are flushed during power
274 * collapse unless the L2 driver decides to flush them only during L2
275 * Power collapse.
276 */
277msm_pm_flush_l2_flag:
278 .long 0x1