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#define PLLC_STORE_MASK (1 << 0)
47#define PLLM_STORE_MASK (1 << 1)
48#define PLLP_STORE_MASK (1 << 2)
49
50.macro test_pll_state, rd, test_mask
51 ldr \rd, tegra_pll_state
52 tst \rd,
53.endm
54
55.macro store_pll_state, rd, tmp, r_car_base, pll_base, pll_mask
56 ldr \rd, [\r_car_base,
57 tst \rd,
58 ldr \rd, tegra_pll_state
59 biceq \rd, \rd,
60 orrne \rd, \rd,
61 adr \tmp, tegra_pll_state
62 str \rd, [\tmp]
63.endm
64
65.macro pll_enable, rd, r_car_base, pll_base, test_mask
66 test_pll_state \rd, \test_mask
67 beq 1f
68
69 ldr \rd, [\r_car_base,
70 tst \rd,
71 orreq \rd, \rd,
72 streq \rd, [\r_car_base,
731:
74.endm
75
76.macro emc_device_mask, rd, base
77 ldr \rd, [\base,
78 tst \rd,
79 moveq \rd,
80 movne \rd,
81.endm
82
83
84
85
86
87
88
89
90ENTRY(tegra20_hotplug_shutdown)
91
92 cpu_id r0
93 bl tegra20_cpu_shutdown
94 ret lr @ should never get here
95ENDPROC(tegra20_hotplug_shutdown)
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110ENTRY(tegra20_cpu_shutdown)
111 cmp r0,
112 reteq lr @ must not be called for CPU 0
113
114 cpu_to_halt_reg r1, r0
115 ldr r3, =TEGRA_FLOW_CTRL_VIRT
116 mov r2,
117 str r2, [r3, r1] @ put flow controller in wait event mode
118 ldr r2, [r3, r1]
119 isb
120 dsb
121 movw r1, 0x1011
122 mov r1, r1, lsl r0
123 ldr r3, =TEGRA_CLK_RESET_VIRT
124 str r1, [r3,
125 isb
126 dsb
127 cpu_id r3
128 cmp r3, r0
129 beq .
130 ret lr
131ENDPROC(tegra20_cpu_shutdown)
132#endif
133
134#ifdef CONFIG_PM_SLEEP
135
136
137
138
139
140
141ENTRY(tegra20_sleep_core_finish)
142 mov r4, r0
143
144 mov r0,
145 bl tegra_disable_clean_inv_dcache
146 mov r0, r4
147
148 mov32 r3, tegra_shut_off_mmu
149 add r3, r3, r0
150
151 mov32 r0, tegra20_tear_down_core
152 mov32 r1, tegra20_iram_start
153 sub r0, r0, r1
154 mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
155 add r0, r0, r1
156
157 ret r3
158ENDPROC(tegra20_sleep_core_finish)
159
160
161
162
163
164
165ENTRY(tegra20_tear_down_cpu)
166 bl tegra_switch_cpu_to_pllp
167 b tegra20_enter_sleep
168ENDPROC(tegra20_tear_down_cpu)
169
170
171 .align L1_CACHE_SHIFT
172 .globl tegra20_iram_start
173tegra20_iram_start:
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188ENTRY(tegra20_lp1_reset)
189
190
191
192
193
194 mov32 r0, TEGRA_CLK_RESET_BASE
195
196 mov r1,
197 str r1, [r0,
198 str r1, [r0,
199 mov r1,
200 str r1, [r0,
201 str r1, [r0,
202
203 pll_enable r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
204 pll_enable r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
205 pll_enable r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
206
207 adr r2, tegra20_sdram_pad_address
208 adr r4, tegra20_sdram_pad_save
209 mov r5,
210
211 ldr r6, tegra20_sdram_pad_size
212padload:
213 ldr r7, [r2, r5] @ r7 is the addr in the pad_address
214
215 ldr r1, [r4, r5]
216 str r1, [r7] @ restore the value in pad_save
217
218 add r5, r5,
219 cmp r6, r5
220 bne padload
221
222padload_done:
223
224 mov32 r7, TEGRA_TMRUS_BASE
225 ldr r1, [r7]
226 add r1, r1,
227 wait_until r1, r7, r9
228
229 adr r4, tegra20_sclk_save
230 ldr r4, [r4]
231 str r4, [r0,
232 mov32 r4, ((1 << 28) | (4)) @ burst policy is PLLP
233 str r4, [r0,
234
235 mov32 r0, TEGRA_EMC_BASE
236 ldr r1, [r0,
237 bic r1, r1,
238 str r1, [r0,
239
240 mov r1,
241 str r1, [r0,
242 mov r1,
243 str r1, [r0,
244 str r1, [r0,
245
246 emc_device_mask r1, r0
247
248exit_selfrefresh_loop:
249 ldr r2, [r0,
250 ands r2, r2, r1
251 bne exit_selfrefresh_loop
252
253 mov r1,
254 str r1, [r0,
255
256 mov32 r0, TEGRA_PMC_BASE
257 ldr r0, [r0,
258 ret r0 @ jump to tegra_resume
259ENDPROC(tegra20_lp1_reset)
260
261
262
263
264
265
266
267tegra20_tear_down_core:
268 bl tegra20_sdram_self_refresh
269 bl tegra20_switch_cpu_to_clk32k
270 b tegra20_enter_sleep
271
272
273
274
275
276
277
278tegra20_switch_cpu_to_clk32k:
279
280
281
282
283 mov r0,
284 str r0, [r5,
285 str r0, [r5,
286 mov r0,
287 str r0, [r5,
288 str r0, [r5,
289
290
291 mov32 r7, TEGRA_TMRUS_BASE
292 ldr r1, [r7]
293 add r1, r1,
294 wait_until r1, r7, r9
295
296 store_pll_state r0, r1, r5, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
297 store_pll_state r0, r1, r5, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
298 store_pll_state r0, r1, r5, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
299
300
301 ldr r0, [r5,
302 bic r0, r0,
303 str r0, [r5,
304 ldr r0, [r5,
305 bic r0, r0,
306 str r0, [r5,
307 ldr r0, [r5,
308 bic r0, r0,
309 str r0, [r5,
310
311
312 mov r0,
313 str r0, [r5,
314
315 ret lr
316
317
318
319
320
321
322
323
324tegra20_enter_sleep:
325 mov32 r6, TEGRA_FLOW_CTRL_BASE
326
327 mov r0,
328 orr r0, r0,
329 cpu_id r1
330 cpu_to_halt_reg r1, r1
331 str r0, [r6, r1]
332 dsb
333 ldr r0, [r6, r1]
334
335halted:
336 dsb
337 wfe
338 isb
339 b halted
340
341
342
343
344
345
346
347
348tegra20_sdram_self_refresh:
349 mov32 r1, TEGRA_EMC_BASE @ r1 reserved for emc base addr
350
351 mov r2,
352 str r2, [r1,
353
354emcidle:
355 ldr r2, [r1,
356 tst r2,
357 beq emcidle
358
359 mov r2,
360 str r2, [r1,
361
362 emc_device_mask r2, r1
363
364emcself:
365 ldr r3, [r1,
366 and r3, r3, r2
367 cmp r3, r2
368 bne emcself @ loop until DDR in self-refresh
369
370 adr r2, tegra20_sdram_pad_address
371 adr r3, tegra20_sdram_pad_safe
372 adr r4, tegra20_sdram_pad_save
373 mov r5,
374
375 ldr r6, tegra20_sdram_pad_size
376padsave:
377 ldr r0, [r2, r5] @ r0 is the addr in the pad_address
378
379 ldr r1, [r0]
380 str r1, [r4, r5] @ save the content of the addr
381
382 ldr r1, [r3, r5]
383 str r1, [r0] @ set the save val to the addr
384
385 add r5, r5,
386 cmp r6, r5
387 bne padsave
388padsave_done:
389
390 mov32 r5, TEGRA_CLK_RESET_BASE
391 ldr r0, [r5,
392 adr r2, tegra20_sclk_save
393 str r0, [r2]
394 dsb
395 ret lr
396
397tegra20_sdram_pad_address:
398 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL
399 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL
400 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CLKCFGPADCTRL
401 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2COMPPADCTRL
402 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2VTTGENPADCTRL
403 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL2
404 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL2
405
406tegra20_sdram_pad_size:
407 .word tegra20_sdram_pad_size - tegra20_sdram_pad_address
408
409tegra20_sdram_pad_safe:
410 .word 0x8
411 .word 0x8
412 .word 0x0
413 .word 0x8
414 .word 0x5500
415 .word 0x08080040
416 .word 0x0
417
418tegra20_sclk_save:
419 .word 0x0
420
421tegra20_sdram_pad_save:
422 .rept (tegra20_sdram_pad_size - tegra20_sdram_pad_address) / 4
423 .long 0
424 .endr
425
426tegra_pll_state:
427 .word 0x0
428
429 .ltorg
430
431 .align L1_CACHE_SHIFT
432 .globl tegra20_iram_end
433tegra20_iram_end:
434 b .
435#endif
436