f2a3338035cc2a8a996256f4fa2a724fb0e6d5e0
[linux-3.10.git] / arch / arm / mach-tegra / sleep-t20.S
1 /*
2  * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
3  * Copyright (c) 2011, Google, Inc.
4  *
5  * Author: Colin Cross <ccross@android.com>
6  *         Gary King <gking@nvidia.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/const.h>
22 #include <linux/init.h>
23 #include <linux/linkage.h>
24
25 #include <asm/assembler.h>
26 #include <asm/cache.h>
27 #include <asm/domain.h>
28 #include <asm/memory.h>
29 #include <asm/page.h>
30 #include <asm/ptrace.h>
31 #include <asm/asm-offsets.h>
32 #include <asm/glue-cache.h>
33 #include <asm/glue-proc.h>
34 #include <asm/system.h>
35
36 #include "sleep.h"
37 #include "flowctrl.h"
38
39 #define EMC_CFG                         0xc
40 #define EMC_ADR_CFG                     0x10
41 #define EMC_REFRESH                     0x70
42 #define EMC_NOP                         0xdc
43 #define EMC_SELF_REF                    0xe0
44 #define EMC_REQ_CTRL                    0x2b0
45 #define EMC_EMC_STATUS                  0x2b4
46
47 #define CLK_RESET_CCLK_BURST            0x20
48 #define CLK_RESET_CCLK_DIVIDER          0x24
49 #define CLK_RESET_SCLK_BURST            0x28
50 #define CLK_RESET_SCLK_DIVIDER          0x2c
51
52 #define CLK_RESET_PLLC_BASE             0x80
53 #define CLK_RESET_PLLM_BASE             0x90
54 #define CLK_RESET_PLLP_BASE             0xa0
55 #define CLK_RESET_PLLP_OUTA             0xa4
56 #define CLK_RESET_PLLP_OUTB             0xa8
57 #define CLK_RESET_PLLP_MISC             0xac
58 #define CLK_RESET_PLLX_BASE             0xe0
59 #define CLK_RESET_PLLX_MISC             0xe4
60
61 #define CLK_RESET_RST_CPU_CMPLX_SET     0x340
62
63 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
64 /*
65  * tegra20_hotplug_shutdown(void)
66  *
67  * puts the current cpu in reset
68  * should never return
69  */
70 ENTRY(tegra20_hotplug_shutdown)
71         mov     r6, lr
72         bl      tegra_cpu_exit_coherency
73
74         /* Put this CPU down */
75         cpu_id  r0
76         bl      tegra20_cpu_shutdown
77         mov     pc, r6                  @ should never get here
78 ENDPROC(tegra20_hotplug_shutdown)
79 #endif
80
81 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
82 /*
83  * tegra20_cpu_shutdown(int cpu)
84  *
85  * r0 is cpu to reset
86  *
87  * puts the specified CPU in wait-for-event mode on the flow controller
88  * and puts the CPU in reset
89  * can be called on the current cpu or another cpu
90  * if called on the current cpu, does not return
91  * MUST NOT BE CALLED FOR CPU 0.
92  *
93  * corrupts r0-r3, r12
94  */
95 ENTRY(tegra20_cpu_shutdown)
96         cmp     r0, #0
97         moveq   pc, lr                  @ must not be called for CPU 0
98
99         mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
100         mov     r12, #CPU_RESETTABLE
101         str     r12, [r1]
102
103         cpu_to_halt_reg r1, r0
104         mov32   r3, TEGRA_FLOW_CTRL_VIRT
105         mov     r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
106         str     r2, [r3, r1]            @ put flow controller in wait event mode
107         ldr     r2, [r3, r1]
108         isb
109         dsb
110         movw    r1, 0x1011
111         mov     r1, r1, lsl r0
112         mov32   r3, TEGRA_CLK_RESET_VIRT
113         str     r1, [r3, #CLK_RESET_RST_CPU_CMPLX_SET]  @ put slave CPU in reset
114         isb
115         dsb
116         cpu_id  r3
117         cmp     r3, r0
118         beq     .
119         mov     pc, lr
120 ENDPROC(tegra20_cpu_shutdown)
121 #endif
122
123 #ifdef CONFIG_PM_SLEEP
124 /*
125  * tegra2_cpu_clear_resettable(void)
126  *
127  * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
128  * it is expected that the secondary CPU will be idle soon.
129  */
130 ENTRY(tegra2_cpu_clear_resettable)
131         mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
132         mov     r12, #CPU_NOT_RESETTABLE
133         str     r12, [r1]
134         mov     pc, lr
135 ENDPROC(tegra2_cpu_clear_resettable)
136
137 /*
138  * tegra2_cpu_set_resettable_soon(void)
139  *
140  * Called to set the "resettable soon" flag in PMC_SCRATCH41 when
141  * it is expected that the secondary CPU will be idle soon.
142  */
143 ENTRY(tegra2_cpu_set_resettable_soon)
144         mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
145         mov     r12, #CPU_RESETTABLE_SOON
146         str     r12, [r1]
147         mov     pc, lr
148 ENDPROC(tegra2_cpu_set_resettable_soon)
149
150 /*
151  * tegra2_cpu_is_resettable_soon(void)
152  *
153  * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
154  * set because it is expected that the secondary CPU will be idle soon.
155  */
156 ENTRY(tegra2_cpu_is_resettable_soon)
157         mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
158         ldr     r12, [r1]
159         cmp     r12, #CPU_RESETTABLE_SOON
160         moveq   r0, #1
161         movne   r0, #0
162         mov     pc, lr
163 ENDPROC(tegra2_cpu_is_resettable_soon)
164
165 /*
166  * tegra2_sleep_core(unsigned long v2p)
167  *
168  * enters suspend in LP0 or LP1 by turning off the mmu and jumping to
169  * tegra2_tear_down_core in IRAM
170  */
171 ENTRY(tegra2_sleep_core_finish)
172         bl      tegra_cpu_exit_coherency
173         mov32   r1, tegra2_tear_down_core
174         mov32   r2, tegra2_iram_start
175         sub     r1, r1, r2
176         mov32   r2, TEGRA_IRAM_CODE_AREA
177         add     r1, r1, r2
178         b       tegra_turn_off_mmu
179 ENDPROC(tegra2_sleep_core_finish)
180
181 /*
182  * tegra2_sleep_cpu_secondary_finish(unsigned long v2p)
183  *
184  * Enters WFI on secondary CPU by exiting coherency.
185  */
186 ENTRY(tegra2_finish_sleep_cpu_secondary)
187         mrc     p15, 0, r11, c1, c0, 1  @ save actlr before exiting coherency
188
189         dsb
190 #ifdef MULTI_CACHE
191         mov32   r10, cpu_cache
192         mov     lr, pc
193         ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
194 #else
195         bl      __cpuc_flush_kern_all
196 #endif
197
198         bl      tegra_cpu_exit_coherency
199
200         mov32   r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
201         mov     r3, #CPU_RESETTABLE
202         str     r3, [r0]
203
204         bl      tegra_cpu_wfi
205
206         /*
207          * cpu may be reset while in wfi, which will return through
208          * tegra_resume to tegra_cpu_resume_phys to tegra_cpu_resume
209          * or interrupt may wake wfi, which will return here
210          * cpu state is unchanged - MMU is on, cache is on, coherency
211          * is off, and the data cache is off
212          *
213          * r11 contains the original actlr
214          */
215         bl      tegra_pen_lock
216
217         mov32   r3, TEGRA_PMC_VIRT
218         add     r0, r3, #PMC_SCRATCH41
219         mov     r3, #CPU_NOT_RESETTABLE
220         str     r3, [r0]
221
222         bl      tegra_pen_unlock
223
224         mcr     p15, 0, r11, c1, c0, 1  @ reenable coherency
225
226         /* Invalidate the TLBs & BTAC */
227         mov     r1, #0
228         mcr     p15, 0, r1, c8, c3, 0   @ invalidate shared TLBs
229         mcr     p15, 0, r1, c7, c1, 6   @ invalidate shared BTAC
230         dsb
231         isb
232
233         @ the cpu was running with coherency disabled, caches may be out of date
234 #ifdef MULTI_CACHE
235         mov32   r10, cpu_cache
236         mov     lr, pc
237         ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
238 #else
239         bl      __cpuc_flush_kern_all
240 #endif
241
242         ldmia   sp!, {r1 - r3}          @ pop phys pgd, virt SP, phys resume fn
243         mov     r0, #0                  @ return success
244         mov     sp, r2                  @ sp is stored in r2 by __cpu_suspend
245         ldmfd   sp!, {r4 - r11, pc}
246 ENDPROC(tegra2_finish_sleep_cpu_secondary)
247
248 /*
249  * tegra2_tear_down_cpu
250  *
251  * Switches the CPU cluster to PLL-P and enters sleep.
252  */
253 ENTRY(tegra2_tear_down_cpu)
254         bl      tegra_cpu_pllp
255         b       tegra2_enter_sleep
256 ENDPROC(tegra2_tear_down_cpu)
257
258 /* START OF ROUTINES COPIED TO IRAM */
259         .align L1_CACHE_SHIFT
260         .globl tegra2_iram_start
261 tegra2_iram_start:
262
263 /*
264  * tegra2_lp1_reset
265  *
266  * reset vector for LP1 restore; copied into IRAM during suspend.
267  * brings the system back up to a safe starting point (SDRAM out of
268  * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
269  * system clock running on the same PLL that it suspended at), and
270  * jumps to tegra_lp2_startup to restore PLLX and virtual addressing.
271  * physical address of tegra_lp2_startup expected to be stored in
272  * PMC_SCRATCH41
273  *
274  * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA AND MUST BE FIRST.
275  */
276 ENTRY(tegra2_lp1_reset)
277         /*
278          * the CPU and system bus are running at 32KHz and executing from
279          * IRAM when this code is executed; immediately switch to CLKM and
280          * enable PLLP.
281          */
282         mov32   r0, TEGRA_CLK_RESET_BASE
283 #ifndef CONFIG_TRUSTED_FOUNDATIONS
284         /* secure code handles 32KHz to CLKM/OSC clock switch */
285         mov     r1, #(1 << 28)
286         str     r1, [r0, #CLK_RESET_SCLK_BURST]
287         str     r1, [r0, #CLK_RESET_CCLK_BURST]
288         mov     r1, #0
289         str     r1, [r0, #CLK_RESET_SCLK_DIVIDER]
290         str     r1, [r0, #CLK_RESET_CCLK_DIVIDER]
291 #endif
292         ldr     r1, [r0, #CLK_RESET_PLLM_BASE]
293         tst     r1, #(1 << 30)
294         orreq   r1, r1, #(1 << 30)
295         streq   r1, [r0, #CLK_RESET_PLLM_BASE]
296         ldr     r1, [r0, #CLK_RESET_PLLP_BASE]
297         tst     r1, #(1 << 30)
298         orreq   r1, r1, #(1 << 30)
299         streq   r1, [r0, #CLK_RESET_PLLP_BASE]
300         ldr     r1, [r0, #CLK_RESET_PLLC_BASE]
301         tst     r1, #(1 << 30)
302         orreq   r1, r1, #(1 << 30)
303         streq   r1, [r0, #CLK_RESET_PLLC_BASE]
304
305         adr     r2, tegra2_sdram_pad_address
306         adr     r4, tegra2_sdram_pad_save
307         mov     r5, #0
308
309 padload:
310         ldr     r0, [r2, r5]            @ r0 is emc register address
311
312         ldr     r1, [r4, r5]
313         str     r1, [r0]                @ set emc register to safe vals
314
315         add     r5, r5, #4
316         ldr     r0, tegra2_sdram_pad_size
317         cmp     r0, r5
318         bne     padload
319
320 padload_done:
321         mov32   r7, TEGRA_TMRUS_BASE
322         ldr     r1, [r7]
323         add     r1, r1, #0xff           @ 255uS delay for PLL stabilization
324
325 1:      ldr     r0, [r7]
326         cmp     r0, r1
327         dmb
328         bmi     1b
329
330         adr     r4, tegra2_sclk_save
331         ldr     r4, [r4]
332         mov32   r0, TEGRA_CLK_RESET_BASE
333         str     r4, [r0, #CLK_RESET_SCLK_BURST]
334         ldr     r4, =((1 << 28) | (4))  @ burst policy is PLLP
335         str     r4, [r0, #CLK_RESET_CCLK_BURST]
336
337         mov32   r0, TEGRA_EMC_BASE
338         ldr     r1, [r0, #EMC_CFG]
339         bic     r1, r1, #(1 << 31)      @ disable DRAM_CLK_STOP
340         str     r1, [r0, #EMC_CFG]
341
342         mov     r1, #0
343         str     r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
344         mov     r1, #1
345         str     r1, [r0, #EMC_NOP]
346         str     r1, [r0, #EMC_NOP]
347         str     r1, [r0, #EMC_REFRESH]
348
349         ldr     r1, [r0, #EMC_ADR_CFG]
350         tst     r1, #(0x3 << 24)
351         moveq   r1, #(0x1 << 8)         @ just 1 device
352         movne   r1, #(0x3 << 8)         @ 2 devices
353
354 exit_selfrefresh_loop:
355         ldr     r2, [r0, #EMC_EMC_STATUS]
356         ands    r2, r2, r1
357         bne     exit_selfrefresh_loop
358
359         mov     r1, #0
360         str     r1, [r0, #EMC_REQ_CTRL]
361
362         ldr     r0, =TEGRA_PMC_BASE
363         ldr     r0, [r0, #PMC_SCRATCH41]
364         mov     pc, r0
365 ENDPROC(tegra2_lp1_reset)
366
367 /*
368  * tegra2_tear_down_core
369  *
370  * copied into and executed from IRAM
371  * puts memory in self-refresh for LP0 and LP1
372  */
373 tegra2_tear_down_core:
374         bl      tegra2_sdram_self_refresh
375         bl      tegra2_cpu_clk32k
376         b       tegra2_enter_sleep
377
378 /*
379  * tegra2_cpu_clk32k
380  *
381  * In LP0 and LP1 all plls will be turned off.  Switch the CPU and system clock
382  * to the 32khz clock (clks)
383  */
384 tegra2_cpu_clk32k:
385         /* start by jumping to clkm to safely disable PLLs, then jump
386          * to clks */
387         mov     r0, #(1 << 28)
388         str     r0, [r5, #CLK_RESET_SCLK_BURST]
389         str     r0, [r5, #CLK_RESET_CCLK_BURST]
390         mov     r0, #0
391         str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
392         str     r0, [r5, #CLK_RESET_SCLK_DIVIDER]
393
394         /* 2 us delay between changing sclk and disabling PLLs */
395         mov32   r7, TEGRA_TMRUS_BASE
396         ldr     r1, [r7]
397         add     r1, r1, #3
398
399 1:      ldr     r0, [r7]
400         cmp     r0, r1
401         dmb
402         bmi     1b
403
404         /* switch to CLKS */
405         mov     r0, #0  /* burst policy = 32KHz */
406         str     r0, [r5, #CLK_RESET_SCLK_BURST]
407
408         /* disable PLLP, PLLM, PLLC in LP0 and LP1 states */
409         ldr     r0, [r5, #CLK_RESET_PLLM_BASE]
410         bic     r0, r0, #(1 << 30)
411         str     r0, [r5, #CLK_RESET_PLLM_BASE]
412         ldr     r0, [r5, #CLK_RESET_PLLP_BASE]
413         bic     r0, r0, #(1 << 30)
414         str     r0, [r5, #CLK_RESET_PLLP_BASE]
415         ldr     r0, [r5, #CLK_RESET_PLLC_BASE]
416         bic     r0, r0, #(1 << 30)
417         str     r0, [r5, #CLK_RESET_PLLC_BASE]
418         mov     pc, lr
419
420 /*
421  * tegra2_enter_sleep
422  *
423  * uses flow controller to enter sleep state
424  * executes from IRAM with SDRAM in selfrefresh when target state is LP0 and LP1
425  * executes from SDRAM with target state is LP2
426  */
427 tegra2_enter_sleep:
428         mov32   r7, TEGRA_TMRUS_BASE
429         ldr     r1, [r7]
430         mov32   r4, TEGRA_PMC_BASE
431         str     r1, [r4, #PMC_SCRATCH38]
432         dsb
433         mov32   r6, TEGRA_FLOW_CTRL_BASE
434
435         mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
436         orr     r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
437         cpu_id  r1
438         cpu_to_halt_reg r1, r1
439         str     r0, [r6, r1]
440         dsb
441         ldr     r0, [r6, r1] /* memory barrier */
442
443 halted: dsb
444         wfe     /* CPU should be power gated here */
445         isb
446         b       halted
447
448 /*
449  * tegra2_sdram_self_refresh
450  *
451  * called with MMU off and caches disabled
452  * puts sdram in self refresh
453  * must execute from IRAM
454  */
455 tegra2_sdram_self_refresh:
456         mov32   r1, TEGRA_EMC_BASE
457         mov     r2, #3
458         str     r2, [r1, #EMC_REQ_CTRL]         @ stall incoming DRAM requests
459
460 emcidle:ldr     r2, [r1, #EMC_EMC_STATUS]
461         tst     r2, #4
462         beq     emcidle
463
464         mov     r2, #1
465         str     r2, [r1, #EMC_SELF_REF]
466
467         ldr     r2, [r1, #EMC_ADR_CFG]
468         tst     r2, #(0x3 << 24)
469         moveq   r2, #(0x1 << 8)                 @ just 1 device
470         movne   r2, #(0x3 << 8)                 @ 2 devices
471
472 emcself:ldr     r3, [r1, #EMC_EMC_STATUS]
473         and     r3, r3, r2
474         cmp     r3, r2
475         bne     emcself                         @ loop until DDR in self-refresh
476
477         adr     r2, tegra2_sdram_pad_address
478         adr     r3, tegra2_sdram_pad_safe
479         adr     r4, tegra2_sdram_pad_save
480         mov     r5, #0
481
482 padsave:
483         ldr     r0, [r2, r5]                    @ r0 is emc register address
484
485         ldr     r1, [r0]
486         str     r1, [r4, r5]                    @ save emc register
487
488         ldr     r1, [r3, r5]
489         str     r1, [r0]                        @ set emc register to safe vals
490
491         add     r5, r5, #4
492         ldr     r0, tegra2_sdram_pad_size
493         cmp     r0, r5
494         bne     padsave
495 padsave_done:
496
497         mov32   r5, TEGRA_CLK_RESET_BASE
498         ldr     r0, [r5, #CLK_RESET_SCLK_BURST]
499         adr     r2, tegra2_sclk_save
500         str     r0, [r2]
501         dsb
502         mov     pc, lr
503
504 tegra2_sdram_pad_address:
505         .word   TEGRA_APB_MISC_BASE + 0x8c8 /* XM2CFGCPADCTRL */
506         .word   TEGRA_APB_MISC_BASE + 0x8cc /* XM2CFGDPADCTRL */
507         .word   TEGRA_APB_MISC_BASE + 0x8d0 /* XM2CLKCFGPADCTRL */
508         .word   TEGRA_APB_MISC_BASE + 0x8d4 /* XM2COMPPADCTRL */
509         .word   TEGRA_APB_MISC_BASE + 0x8d8 /* XM2VTTGENPADCTRL */
510         .word   TEGRA_APB_MISC_BASE + 0x8e4 /* XM2CFGCPADCTRL2 */
511         .word   TEGRA_APB_MISC_BASE + 0x8e8 /* XM2CFGDPADCTRL2 */
512
513 tegra2_sdram_pad_size:
514         .word   tegra2_sdram_pad_size - tegra2_sdram_pad_address
515
516 tegra2_sdram_pad_safe:
517         .word   0x8
518         .word   0x8
519         .word   0x0
520         .word   0x8
521         .word   0x5500
522         .word   0x08080040
523         .word   0x0
524
525 tegra2_sclk_save:
526         .word   0x0
527
528 tegra2_sdram_pad_save:
529         .word   0
530         .word   0
531         .word   0
532         .word   0
533         .word   0
534         .word   0
535         .word   0
536
537         .ltorg
538 /* dummy symbol for end of IRAM */
539         .align L1_CACHE_SHIFT
540         .globl tegra2_iram_end
541 tegra2_iram_end:
542         b       .
543 #endif