aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/sleep.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/sleep.h')
-rw-r--r--arch/arm/mach-tegra/sleep.h246
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
195static 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
204void tegra_pen_lock(void);
205void tegra_pen_unlock(void);
206void tegra_cpu_wfi(void);
207void tegra_sleep_cpu_save(unsigned long v2p);
208void tegra_resume(void);
209
210#ifdef CONFIG_ARCH_TEGRA_2x_SOC
211extern void tegra2_iram_start;
212extern void tegra2_iram_end;
213int tegra2_cpu_is_resettable_soon(void);
214void tegra2_cpu_reset(int cpu);
215void tegra2_cpu_set_resettable_soon(void);
216void tegra2_cpu_clear_resettable(void);
217void tegra2_sleep_core(unsigned long v2p);
218void tegra2_hotplug_shutdown(void);
219void tegra2_sleep_wfi(unsigned long v2p);
220#else
221extern void tegra3_iram_start;
222extern void tegra3_iram_end;
223void tegra3_sleep_core(unsigned long v2p);
224void tegra3_sleep_cpu_secondary(unsigned long v2p);
225void tegra3_hotplug_shutdown(void);
226#endif
227
228static 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
237static 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