diff options
Diffstat (limited to 'arch/arm/mach-tegra/sleep.h')
-rw-r--r-- | arch/arm/mach-tegra/sleep.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h new file mode 100644 index 00000000000..7b8f84d6169 --- /dev/null +++ b/arch/arm/mach-tegra/sleep.h | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/sleep.h | ||
3 | * | ||
4 | * Declarations for power state transition code | ||
5 | * | ||
6 | * Copyright (c) 2010-2011, NVIDIA Corporation. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef __MACH_TEGRA_SLEEP_H | ||
24 | #define __MACH_TEGRA_SLEEP_H | ||
25 | |||
26 | #include <mach/iomap.h> | ||
27 | |||
28 | #ifdef CONFIG_CACHE_L2X0 | ||
29 | #define USE_TEGRA_CPU_SUSPEND 1 | ||
30 | #else | ||
31 | #define USE_TEGRA_CPU_SUSPEND 0 | ||
32 | #endif | ||
33 | #ifndef CONFIG_TRUSTED_FOUNDATIONS | ||
34 | /* FIXME: The code associated with this should be removed if our change to | ||
35 | save the diagnostic regsiter in the CPU context is accepted. */ | ||
36 | #define USE_TEGRA_DIAG_REG_SAVE 1 | ||
37 | #else | ||
38 | #define USE_TEGRA_DIAG_REG_SAVE 0 | ||
39 | #endif | ||
40 | |||
41 | #define TEGRA_POWER_SDRAM_SELFREFRESH (1 << 26) /* SDRAM is in self-refresh */ | ||
42 | #define TEGRA_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */ | ||
43 | #define TEGRA_POWER_CLUSTER_G (1 << 28) /* G CPU */ | ||
44 | #define TEGRA_POWER_CLUSTER_LP (1 << 29) /* LP CPU */ | ||
45 | #define TEGRA_POWER_CLUSTER_MASK (TEGRA_POWER_CLUSTER_G | \ | ||
46 | TEGRA_POWER_CLUSTER_LP) | ||
47 | #define TEGRA_POWER_CLUSTER_IMMEDIATE (1 << 30) /* Immediate wake */ | ||
48 | #define TEGRA_POWER_CLUSTER_FORCE (1 << 31) /* Force switch */ | ||
49 | |||
50 | #define TEGRA_IRAM_CODE_AREA (TEGRA_IRAM_BASE + SZ_4K) | ||
51 | |||
52 | /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock in Tegra2 idle */ | ||
53 | #define PMC_SCRATCH37 0x130 | ||
54 | #define PMC_SCRATCH38 0x134 | ||
55 | /* PMC_SCRATCH39 stores the reset vector of the AVP (always 0) after LP0 */ | ||
56 | #define PMC_SCRATCH39 0x138 | ||
57 | /* PMC_SCRATCH41 stores the reset vector of the CPU after LP0 and LP1 */ | ||
58 | #define PMC_SCRATCH41 0x140 | ||
59 | |||
60 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
61 | #define CPU_RESETTABLE 2 | ||
62 | #define CPU_RESETTABLE_SOON 1 | ||
63 | #define CPU_NOT_RESETTABLE 0 | ||
64 | #endif | ||
65 | |||
66 | #define FLOW_CTRL_HALT_CPU0_EVENTS 0x0 | ||
67 | #define FLOW_CTRL_WAITEVENT (2 << 29) | ||
68 | #define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29) | ||
69 | #define FLOW_CTRL_JTAG_RESUME (1 << 28) | ||
70 | #define FLOW_CTRL_HALT_CPU_IRQ (1 << 10) | ||
71 | #define FLOW_CTRL_HALT_CPU_FIQ (1 << 8) | ||
72 | #define FLOW_CTRL_CPU0_CSR 0x8 | ||
73 | #define FLOW_CTRL_CSR_INTR_FLAG (1 << 15) | ||
74 | #define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14) | ||
75 | #define FLOW_CTRL_CSR_ENABLE (1 << 0) | ||
76 | #define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 | ||
77 | #define FLOW_CTRL_CPU1_CSR 0x18 | ||
78 | |||
79 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
80 | #define FLOW_CTRL_CSR_WFE_CPU0 (1 << 4) | ||
81 | #define FLOW_CTRL_CSR_WFE_BITMAP (3 << 4) | ||
82 | #define FLOW_CTRL_CSR_WFI_BITMAP 0 | ||
83 | #else | ||
84 | #define FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4) | ||
85 | #define FLOW_CTRL_CSR_WFI_CPU0 (1 << 8) | ||
86 | #define FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) | ||
87 | #endif | ||
88 | |||
89 | #define TEGRA_PL310_VIRT (TEGRA_ARM_PL310_BASE - IO_CPU_PHYS + IO_CPU_VIRT) | ||
90 | #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS + IO_PPSB_VIRT) | ||
91 | #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS + IO_CPU_VIRT) | ||
92 | |||
93 | #ifdef __ASSEMBLY__ | ||
94 | |||
95 | /* Macro to exit SMP coherency. */ | ||
96 | .macro exit_smp, tmp1, tmp2 | ||
97 | mrc p15, 0, \tmp1, c1, c0, 1 @ ACTLR | ||
98 | bic \tmp1, \tmp1, #(1<<6) | (1<<0) @ clear ACTLR.SMP | ACTLR.FW | ||
99 | mcr p15, 0, \tmp1, c1, c0, 1 @ ACTLR | ||
100 | isb | ||
101 | cpu_id \tmp1 | ||
102 | mov \tmp1, \tmp1, lsl #2 | ||
103 | mov \tmp2, #0xf | ||
104 | mov \tmp2, \tmp2, lsl \tmp1 | ||
105 | mov32 \tmp1, TEGRA_ARM_PERIF_VIRT + 0xC | ||
106 | str \tmp2, [\tmp1] @ invalidate SCU tags for CPU | ||
107 | dsb | ||
108 | .endm | ||
109 | |||
110 | #define DEBUG_CONTEXT_STACK 0 | ||
111 | |||
112 | /* pops a debug check token from the stack */ | ||
113 | .macro pop_stack_token tmp1, tmp2 | ||
114 | #if DEBUG_CONTEXT_STACK | ||
115 | mov32 \tmp1, 0xBAB1F00D | ||
116 | ldmfd sp!, {\tmp2} | ||
117 | cmp \tmp1, \tmp2 | ||
118 | movne pc, #0 | ||
119 | #endif | ||
120 | .endm | ||
121 | |||
122 | /* pushes a debug check token onto the stack */ | ||
123 | .macro push_stack_token tmp1 | ||
124 | #if DEBUG_CONTEXT_STACK | ||
125 | mov32 \tmp1, 0xBAB1F00D | ||
126 | stmfd sp!, {\tmp1} | ||
127 | #endif | ||
128 | .endm | ||
129 | |||
130 | .macro push_ctx_regs, tmp1 | ||
131 | push_stack_token \tmp1 @ debug check word | ||
132 | stmfd sp!, {r4 - r11, lr} | ||
133 | /* Save the current TTB0 and CONTEXTID registers. */ | ||
134 | mrc p15, 0, r5, c2, c0, 0 @ TTB 0 | ||
135 | mrc p15, 0, r6, c13, c0, 1 @ CONTEXTID | ||
136 | #if USE_TEGRA_DIAG_REG_SAVE | ||
137 | mrc p15, 0, r4, c15, c0, 1 @ read diagnostic register | ||
138 | stmfd sp!, {r4-r6} | ||
139 | #else | ||
140 | stmfd sp!, {r5-r6} | ||
141 | #endif | ||
142 | /* Switch to the tegra_pgd so that IRAM and the MMU shut-off code | ||
143 | will be flat mapped (VA==PA). We also do this because the common | ||
144 | ARM CPU state save/restore code doesn't support an external L2 | ||
145 | cache controller. If the current PGD is left active, the common | ||
146 | ARM MMU restore may (and eventually will) damage the currently | ||
147 | running page tables by adding a temporary flat section mapping | ||
148 | that could be picked up by other CPUs from the L2 cache | ||
149 | resulting in a kernel panic. */ | ||
150 | ldr r6, tegra_pgd_phys_address | ||
151 | ldr r6, [r6] | ||
152 | mov r7, #0 | ||
153 | dsb | ||
154 | mcr p15, 0, r7, c13, c0, 1 @ CONTEXTID = reserved context | ||
155 | isb | ||
156 | mcr p15, 0, r6, c2, c0, 0 @ TTB 0 | ||
157 | isb | ||
158 | mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB | ||
159 | mcr p15, 0, r7, c7, c5, 6 @ flush BTAC | ||
160 | mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache | ||
161 | dsb | ||
162 | .endm | ||
163 | |||
164 | .macro pop_ctx_regs, tmp1, tmp2 | ||
165 | #if USE_TEGRA_DIAG_REG_SAVE | ||
166 | ldmfd sp!, {r4-r6} | ||
167 | mcr p15, 0, r4, c15, c0, 1 @ write diagnostic register | ||
168 | #else | ||
169 | ldmfd sp!, {r5-r6} | ||
170 | #endif | ||
171 | dsb | ||
172 | mcr p15, 0, r5, c2, c0, 0 @ TTB 0 | ||
173 | isb | ||
174 | mcr p15, 0, r6, c13, c0, 1 @ CONTEXTID = reserved context | ||
175 | isb | ||
176 | mov r7, #0 | ||
177 | mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB | ||
178 | mcr p15, 0, r7, c7, c5, 6 @ flush BTAC | ||
179 | mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache | ||
180 | dsb | ||
181 | ldmfd sp!, {r4 - r11, lr} | ||
182 | pop_stack_token \tmp1, \tmp2 @ debug stack debug token | ||
183 | .endm | ||
184 | |||
185 | #else /* !defined(__ASSEMBLY__) */ | ||
186 | |||
187 | #define FLOW_CTRL_HALT_CPU(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \ | ||
188 | ((cpu) ? (FLOW_CTRL_HALT_CPU1_EVENTS + 8 * ((cpu) - 1)) : \ | ||
189 | FLOW_CTRL_HALT_CPU0_EVENTS)) | ||
190 | |||
191 | #define FLOW_CTRL_CPU_CSR(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \ | ||
192 | ((cpu) ? (FLOW_CTRL_CPU1_CSR + 8 * ((cpu) - 1)) : \ | ||
193 | FLOW_CTRL_CPU0_CSR)) | ||
194 | |||
195 | static inline void flowctrl_writel(unsigned long val, void __iomem *addr) | ||
196 | { | ||
197 | writel(val, addr); | ||
198 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
199 | wmb(); | ||
200 | #endif | ||
201 | (void)__raw_readl(addr); | ||
202 | } | ||
203 | |||
204 | void tegra_pen_lock(void); | ||
205 | void tegra_pen_unlock(void); | ||
206 | void tegra_cpu_wfi(void); | ||
207 | void tegra_sleep_cpu_save(unsigned long v2p); | ||
208 | void tegra_resume(void); | ||
209 | |||
210 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
211 | extern void tegra2_iram_start; | ||
212 | extern void tegra2_iram_end; | ||
213 | int tegra2_cpu_is_resettable_soon(void); | ||
214 | void tegra2_cpu_reset(int cpu); | ||
215 | void tegra2_cpu_set_resettable_soon(void); | ||
216 | void tegra2_cpu_clear_resettable(void); | ||
217 | void tegra2_sleep_core(unsigned long v2p); | ||
218 | void tegra2_hotplug_shutdown(void); | ||
219 | void tegra2_sleep_wfi(unsigned long v2p); | ||
220 | #else | ||
221 | extern void tegra3_iram_start; | ||
222 | extern void tegra3_iram_end; | ||
223 | void tegra3_sleep_core(unsigned long v2p); | ||
224 | void tegra3_sleep_cpu_secondary(unsigned long v2p); | ||
225 | void tegra3_hotplug_shutdown(void); | ||
226 | #endif | ||
227 | |||
228 | static inline void *tegra_iram_start(void) | ||
229 | { | ||
230 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
231 | return &tegra2_iram_start; | ||
232 | #else | ||
233 | return &tegra3_iram_start; | ||
234 | #endif | ||
235 | } | ||
236 | |||
237 | static inline void *tegra_iram_end(void) | ||
238 | { | ||
239 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
240 | return &tegra2_iram_end; | ||
241 | #else | ||
242 | return &tegra3_iram_end; | ||
243 | #endif | ||
244 | } | ||
245 | #endif | ||
246 | #endif | ||