ARM: tegra: power: Conditionalize diagnostic register save/restore
[linux-3.10.git] / arch / arm / mach-tegra / sleep.h
1 /*
2  * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #ifndef __MACH_TEGRA_SLEEP_H
18 #define __MACH_TEGRA_SLEEP_H
19
20 #include "iomap.h"
21
22 #ifdef CONFIG_CACHE_L2X0
23 #define USE_TEGRA_CPU_SUSPEND   1
24 #else
25 #define USE_TEGRA_CPU_SUSPEND   0
26 #endif
27 /* FIXME: The core associated with this should be removed if our change to
28    save the diagnostic regsiter in the CPU context is accepted. */
29 #define USE_TEGRA_DIAG_REG_SAVE 1
30
31 #define TEGRA_POWER_SDRAM_SELFREFRESH   (1 << 26) /* SDRAM is in self-refresh */
32 #define TEGRA_POWER_HOTPLUG_SHUTDOWN    (1 << 27) /* Hotplug shutdown */
33 #define TEGRA_POWER_CLUSTER_G           (1 << 28) /* G CPU */
34 #define TEGRA_POWER_CLUSTER_LP          (1 << 29) /* LP CPU */
35 #define TEGRA_POWER_CLUSTER_MASK        (TEGRA_POWER_CLUSTER_G | \
36                                                 TEGRA_POWER_CLUSTER_LP)
37 #define TEGRA_POWER_CLUSTER_IMMEDIATE   (1 << 30) /* Immediate wake */
38 #define TEGRA_POWER_CLUSTER_FORCE       (1 << 31) /* Force switch */
39
40 #define TEGRA_IRAM_CODE_AREA            (TEGRA_IRAM_BASE + SZ_4K)
41
42 /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock in Tegra2 idle */
43 #define PMC_SCRATCH37                   0x130
44 #define PMC_SCRATCH38                   0x134
45 /* PMC_SCRATCH39 stores the reset vector of the AVP (always 0) after LP0 */
46 #define PMC_SCRATCH39                   0x138
47 /* PMC_SCRATCH41 stores the reset vector of the CPU after LP0 and LP1 */
48 #define PMC_SCRATCH41                   0x140
49
50 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
51 #define CPU_RESETTABLE                  2
52 #define CPU_RESETTABLE_SOON             1
53 #define CPU_NOT_RESETTABLE              0
54 #endif
55
56 #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
57                                         + IO_CPU_VIRT)
58 #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
59                                         + IO_PPSB_VIRT)
60 #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
61                                         + IO_PPSB_VIRT)
62
63 #ifdef __ASSEMBLY__
64 /* waits until the microsecond counter (base) is > rn */
65 .macro  wait_until, rn, base, tmp
66         add     \rn, \rn, #1
67 1002:   ldr     \tmp, [\base]
68         sub     \tmp, \tmp, \rn
69         ands    \tmp, \tmp, #0x80000000
70         dmb
71         bne     1002b
72 .endm
73
74 /* returns the offset of the flow controller halt register for a cpu */
75 .macro cpu_to_halt_reg rd, rcpu
76         cmp     \rcpu, #0
77         subne   \rd, \rcpu, #1
78         movne   \rd, \rd, lsl #3
79         addne   \rd, \rd, #0x14
80         moveq   \rd, #0
81 .endm
82
83 /* returns the offset of the flow controller csr register for a cpu */
84 .macro cpu_to_csr_reg rd, rcpu
85         cmp     \rcpu, #0
86         subne   \rd, \rcpu, #1
87         movne   \rd, \rd, lsl #3
88         addne   \rd, \rd, #0x18
89         moveq   \rd, #8
90 .endm
91
92 /* returns the ID of the current processor */
93 .macro cpu_id, rd
94         mrc     p15, 0, \rd, c0, c0, 5
95         and     \rd, \rd, #0xF
96 .endm
97
98 /* loads a 32-bit value into a register without a data access */
99 .macro mov32, reg, val
100         movw    \reg, #:lower16:\val
101         movt    \reg, #:upper16:\val
102 .endm
103
104 /* Macro to exit SMP coherency. */
105 .macro exit_smp, tmp1, tmp2
106         mrc     p15, 0, \tmp1, c1, c0, 1        @ ACTLR
107         bic     \tmp1, \tmp1, #(1<<6) | (1<<0)  @ clear ACTLR.SMP | ACTLR.FW
108         mcr     p15, 0, \tmp1, c1, c0, 1        @ ACTLR
109         isb
110         cpu_id  \tmp1
111         mov     \tmp1, \tmp1, lsl #2
112         mov     \tmp2, #0xf
113         mov     \tmp2, \tmp2, lsl \tmp1
114         mov32   \tmp1, TEGRA_ARM_PERIF_VIRT + 0xC
115         str     \tmp2, [\tmp1]                  @ invalidate SCU tags for CPU
116         dsb
117 .endm
118
119 #define DEBUG_CONTEXT_STACK     0
120
121 /* pops a debug check token from the stack */
122 .macro  pop_stack_token tmp1, tmp2
123 #if DEBUG_CONTEXT_STACK
124         mov32   \tmp1, 0xBAB1F00D
125         ldmfd   sp!, {\tmp2}
126         cmp     \tmp1, \tmp2
127         movne   pc, #0
128 #endif
129 .endm
130
131 /* pushes a debug check token onto the stack */
132 .macro  push_stack_token tmp1
133 #if DEBUG_CONTEXT_STACK
134         mov32   \tmp1, 0xBAB1F00D
135         stmfd   sp!, {\tmp1}
136 #endif
137 .endm
138
139 .macro push_ctx_regs, tmp1
140         push_stack_token \tmp1          @ debug check word
141         stmfd   sp!, {r4 - r11, lr}
142 #if USE_TEGRA_DIAG_REG_SAVE
143         mrc     p15, 0, r4, c15, c0, 1  @ read diagnostic register
144         stmfd   sp!, {r4}
145 #endif
146 .endm
147
148 .macro pop_ctx_regs, tmp1, tmp2
149 #if USE_TEGRA_DIAG_REG_SAVE
150         ldmfd   sp!, {r4}
151         mcr     p15, 0, r4, c15, c0, 1  @ write diagnostic register
152 #endif
153         ldmfd   sp!, {r4 - r11, lr}
154         pop_stack_token \tmp1, \tmp2    @ debug stack debug token
155 .endm
156
157 #else
158
159 #ifdef CONFIG_HOTPLUG_CPU
160 void tegra20_hotplug_init(void);
161 void tegra30_hotplug_init(void);
162 #else
163 static inline void tegra20_hotplug_init(void) {}
164 static inline void tegra30_hotplug_init(void) {}
165 #endif
166
167 void tegra_pen_lock(void);
168 void tegra_pen_unlock(void);
169 void tegra_cpu_wfi(void);
170
171 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
172 extern void tegra2_iram_start;
173 extern void tegra2_iram_end;
174 int  tegra2_cpu_is_resettable_soon(void);
175 void tegra2_cpu_reset(int cpu);
176 void tegra2_cpu_set_resettable_soon(void);
177 void tegra2_sleep_core(unsigned long v2p);
178 void tegra2_sleep_wfi(unsigned long v2p);
179 #else
180 extern void tegra3_iram_start;
181 extern void tegra3_iram_end;
182 void tegra3_sleep_core(unsigned long v2p);
183 void tegra3_sleep_cpu_secondary(unsigned long v2p);
184 #endif
185
186 static inline void *tegra_iram_start(void)
187 {
188 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
189         return &tegra2_iram_start;
190 #else
191         return &tegra3_iram_start;
192 #endif
193 }
194
195 static inline void *tegra_iram_end(void)
196 {
197 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
198         return &tegra2_iram_end;
199 #else
200         return &tegra3_iram_end;
201 #endif
202 }
203
204 static inline void tegra_sleep_core(unsigned long v2p)
205 {
206 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
207         tegra2_sleep_core(v2p);
208 #else
209         /* tegra3_sleep_core(v2p);    !!!FIXME!!! not supported yet */
210         BUG();
211 #endif
212 }
213
214 void tegra_sleep_cpu(unsigned long v2p);
215 void tegra_resume(void);
216
217 #endif
218
219 #endif