1
2
3
4
5
6
7
8
9
10#include <linux/linkage.h>
11
12#include <soc/tegra/flowctrl.h>
13
14#include <asm/assembler.h>
15#include <asm/proc-fns.h>
16#include <asm/cp15.h>
17#include <asm/cache.h>
18
19#include "irammap.h"
20#include "reset.h"
21#include "sleep.h"
22
23#define EMC_CFG 0xc
24#define EMC_ADR_CFG 0x10
25#define EMC_NOP 0xdc
26#define EMC_SELF_REF 0xe0
27#define EMC_REQ_CTRL 0x2b0
28#define EMC_EMC_STATUS 0x2b4
29
30#define CLK_RESET_CCLK_BURST 0x20
31#define CLK_RESET_CCLK_DIVIDER 0x24
32#define CLK_RESET_SCLK_BURST 0x28
33#define CLK_RESET_SCLK_DIVIDER 0x2c
34#define CLK_RESET_PLLC_BASE 0x80
35#define CLK_RESET_PLLM_BASE 0x90
36#define CLK_RESET_PLLP_BASE 0xa0
37
38#define APB_MISC_XM2CFGCPADCTRL 0x8c8
39#define APB_MISC_XM2CFGDPADCTRL 0x8cc
40#define APB_MISC_XM2CLKCFGPADCTRL 0x8d0
41#define APB_MISC_XM2COMPPADCTRL 0x8d4
42#define APB_MISC_XM2VTTGENPADCTRL 0x8d8
43#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
44#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
45
46.macro pll_enable, rd, r_car_base, pll_base
47 ldr \rd, [\r_car_base,
48 tst \rd,
49 orreq \rd, \rd,
50 streq \rd, [\r_car_base,
51.endm
52
53.macro emc_device_mask, rd, base
54 ldr \rd, [\base,
55 tst \rd,
56 moveq \rd,
57 movne \rd,
58.endm
59
60
61
62
63
64
65
66
67ENTRY(tegra20_hotplug_shutdown)
68
69 cpu_id r0
70 bl tegra20_cpu_shutdown
71 ret lr @ should never get here
72ENDPROC(tegra20_hotplug_shutdown)
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87ENTRY(tegra20_cpu_shutdown)
88 cmp r0,
89 reteq lr @ must not be called for CPU 0
90
91 cpu_to_halt_reg r1, r0
92 ldr r3, =TEGRA_FLOW_CTRL_VIRT
93 mov r2,
94 str r2, [r3, r1] @ put flow controller in wait event mode
95 ldr r2, [r3, r1]
96 isb
97 dsb
98 movw r1, 0x1011
99 mov r1, r1, lsl r0
100 ldr r3, =TEGRA_CLK_RESET_VIRT
101 str r1, [r3,
102 isb
103 dsb
104 cpu_id r3
105 cmp r3, r0
106 beq .
107 ret lr
108ENDPROC(tegra20_cpu_shutdown)
109#endif
110
111#ifdef CONFIG_PM_SLEEP
112
113
114
115
116
117
118ENTRY(tegra20_sleep_core_finish)
119 mov r4, r0
120
121 mov r0,
122 bl tegra_disable_clean_inv_dcache
123 mov r0, r4
124
125 mov32 r3, tegra_shut_off_mmu
126 add r3, r3, r0
127
128 mov32 r0, tegra20_tear_down_core
129 mov32 r1, tegra20_iram_start
130 sub r0, r0, r1
131 mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
132 add r0, r0, r1
133
134 ret r3
135ENDPROC(tegra20_sleep_core_finish)
136
137
138
139
140
141
142ENTRY(tegra20_tear_down_cpu)
143 bl tegra_switch_cpu_to_pllp
144 b tegra20_enter_sleep
145ENDPROC(tegra20_tear_down_cpu)
146
147
148 .align L1_CACHE_SHIFT
149 .globl tegra20_iram_start
150tegra20_iram_start:
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165ENTRY(tegra20_lp1_reset)
166
167
168
169
170
171 mov32 r0, TEGRA_CLK_RESET_BASE
172
173 mov r1,
174 str r1, [r0,
175 str r1, [r0,
176 mov r1,
177 str r1, [r0,
178 str r1, [r0,
179
180 pll_enable r1, r0, CLK_RESET_PLLM_BASE
181 pll_enable r1, r0, CLK_RESET_PLLP_BASE
182 pll_enable r1, r0, CLK_RESET_PLLC_BASE
183
184 adr r2, tegra20_sdram_pad_address
185 adr r4, tegra20_sdram_pad_save
186 mov r5,
187
188 ldr r6, tegra20_sdram_pad_size
189padload:
190 ldr r7, [r2, r5] @ r7 is the addr in the pad_address
191
192 ldr r1, [r4, r5]
193 str r1, [r7] @ restore the value in pad_save
194
195 add r5, r5,
196 cmp r6, r5
197 bne padload
198
199padload_done:
200
201 mov32 r7, TEGRA_TMRUS_BASE
202 ldr r1, [r7]
203 add r1, r1,
204 wait_until r1, r7, r9
205
206 adr r4, tegra20_sclk_save
207 ldr r4, [r4]
208 str r4, [r0,
209 mov32 r4, ((1 << 28) | (4)) @ burst policy is PLLP
210 str r4, [r0,
211
212 mov32 r0, TEGRA_EMC_BASE
213 ldr r1, [r0,
214 bic r1, r1,
215 str r1, [r0,
216
217 mov r1,
218 str r1, [r0,
219 mov r1,
220 str r1, [r0,
221 str r1, [r0,
222
223 emc_device_mask r1, r0
224
225exit_selfrefresh_loop:
226 ldr r2, [r0,
227 ands r2, r2, r1
228 bne exit_selfrefresh_loop
229
230 mov r1,
231 str r1, [r0,
232
233 mov32 r0, TEGRA_PMC_BASE
234 ldr r0, [r0,
235 ret r0 @ jump to tegra_resume
236ENDPROC(tegra20_lp1_reset)
237
238
239
240
241
242
243
244tegra20_tear_down_core:
245 bl tegra20_sdram_self_refresh
246 bl tegra20_switch_cpu_to_clk32k
247 b tegra20_enter_sleep
248
249
250
251
252
253
254
255tegra20_switch_cpu_to_clk32k:
256
257
258
259
260 mov r0,
261 str r0, [r5,
262 str r0, [r5,
263 mov r0,
264 str r0, [r5,
265 str r0, [r5,
266
267
268 mov32 r7, TEGRA_TMRUS_BASE
269 ldr r1, [r7]
270 add r1, r1,
271 wait_until r1, r7, r9
272
273
274 ldr r0, [r5,
275 bic r0, r0,
276 str r0, [r5,
277 ldr r0, [r5,
278 bic r0, r0,
279 str r0, [r5,
280 ldr r0, [r5,
281 bic r0, r0,
282 str r0, [r5,
283
284
285 mov r0,
286 str r0, [r5,
287
288 ret lr
289
290
291
292
293
294
295
296
297tegra20_enter_sleep:
298 mov32 r6, TEGRA_FLOW_CTRL_BASE
299
300 mov r0,
301 orr r0, r0,
302 cpu_id r1
303 cpu_to_halt_reg r1, r1
304 str r0, [r6, r1]
305 dsb
306 ldr r0, [r6, r1]
307
308halted:
309 dsb
310 wfe
311 isb
312 b halted
313
314
315
316
317
318
319
320
321tegra20_sdram_self_refresh:
322 mov32 r1, TEGRA_EMC_BASE @ r1 reserved for emc base addr
323
324 mov r2,
325 str r2, [r1,
326
327emcidle:
328 ldr r2, [r1,
329 tst r2,
330 beq emcidle
331
332 mov r2,
333 str r2, [r1,
334
335 emc_device_mask r2, r1
336
337emcself:
338 ldr r3, [r1,
339 and r3, r3, r2
340 cmp r3, r2
341 bne emcself @ loop until DDR in self-refresh
342
343 adr r2, tegra20_sdram_pad_address
344 adr r3, tegra20_sdram_pad_safe
345 adr r4, tegra20_sdram_pad_save
346 mov r5,
347
348 ldr r6, tegra20_sdram_pad_size
349padsave:
350 ldr r0, [r2, r5] @ r0 is the addr in the pad_address
351
352 ldr r1, [r0]
353 str r1, [r4, r5] @ save the content of the addr
354
355 ldr r1, [r3, r5]
356 str r1, [r0] @ set the save val to the addr
357
358 add r5, r5,
359 cmp r6, r5
360 bne padsave
361padsave_done:
362
363 mov32 r5, TEGRA_CLK_RESET_BASE
364 ldr r0, [r5,
365 adr r2, tegra20_sclk_save
366 str r0, [r2]
367 dsb
368 ret lr
369
370tegra20_sdram_pad_address:
371 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL
372 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL
373 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CLKCFGPADCTRL
374 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2COMPPADCTRL
375 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2VTTGENPADCTRL
376 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL2
377 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL2
378
379tegra20_sdram_pad_size:
380 .word tegra20_sdram_pad_size - tegra20_sdram_pad_address
381
382tegra20_sdram_pad_safe:
383 .word 0x8
384 .word 0x8
385 .word 0x0
386 .word 0x8
387 .word 0x5500
388 .word 0x08080040
389 .word 0x0
390
391tegra20_sclk_save:
392 .word 0x0
393
394tegra20_sdram_pad_save:
395 .rept (tegra20_sdram_pad_size - tegra20_sdram_pad_address) / 4
396 .long 0
397 .endr
398
399 .ltorg
400
401 .align L1_CACHE_SHIFT
402 .globl tegra20_iram_end
403tegra20_iram_end:
404 b .
405#endif
406