ARM: tegra30: pm: flush L1 data before exit coherency on secondary CPU
[linux-2.6.git] / arch / arm / mach-tegra / sleep-t3.S
1 /*
2  * arch/arm/mach-tegra/include/mach/sleep-t3.S
3  *
4  * Copyright (c) 2010-2012, NVIDIA Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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 <mach/iomap.h>
37 #include <mach/io.h>
38
39 #include "asm_macros.h"
40 #include "sleep.h"
41 #include "clock.h"
42
43 #define EMC_CFG                         0xc
44 #define EMC_ADR_CFG                     0x10
45 #define EMC_TIMING_CONTROL              0x28
46 #define EMC_REFRESH                     0x70
47 #define EMC_NOP                         0xdc
48 #define EMC_SELF_REF                    0xe0
49 #define EMC_MRW                         0xe8
50 #define EMC_REQ_CTRL                    0x2b0
51 #define EMC_EMC_STATUS                  0x2b4
52 #define EMC_FBIO_CFG5                   0x104
53 #define EMC_AUTO_CAL_CONFIG             0x2a4
54 #define EMC_AUTO_CAL_INTERVAL           0x2a8
55 #define EMC_AUTO_CAL_STATUS             0x2ac
56 #define EMC_CFG_DIG_DLL                 0x2bc
57 #define EMC_ZCAL_INTERVAL               0x2e0
58 #define EMC_ZQ_CAL                      0x2ec
59 #define EMC_XM2VTTGENPADCTRL            0x310
60 #define EMC_XM2VTTGENPADCTRL2           0x314
61
62 #define PMC_CTRL                        0x0
63 #define PMC_CTRL_SIDE_EFFECT_LP0        (1 << 14)  /* enter LP0 when CPU pwr gated */
64
65 #define PMC_PWRGATE_TOGGLE              0x30
66 #define PMC_REMOVE_CLAMPING_CMD         0x34
67 #define PMC_PWRGATE_STATUS              0x38
68
69 #define PMC_PWRGATE_PARTID_L2C          (0x5)
70
71 #define PMC_IO_DPD_REQ                  0x1b8
72 #define PMC_IO_DPD_STATUS               0x1bc
73
74 #define CLK_RESET_CCLK_BURST            0x20
75 #define CLK_RESET_CCLK_DIVIDER          0x24
76 #define CLK_RESET_SCLK_BURST            0x28
77 #define CLK_RESET_SCLK_DIVIDER          0x2c
78
79 #define CLK_RESET_PLLC_BASE             0x80
80 #define CLK_RESET_PLLM_BASE             0x90
81 #define CLK_RESET_PLLP_BASE             0xa0
82 #define CLK_RESET_PLLA_BASE             0xb0
83 #define CLK_RESET_PLLX_BASE             0xe0
84
85 #define CLK_RESET_PLLC_MISC             0x8c
86 #define CLK_RESET_PLLM_MISC             0x9c
87 #define CLK_RESET_PLLP_MISC             0xac
88 #define CLK_RESET_PLLA_MISC             0xbc
89 #define CLK_RESET_PLLX_MISC             0xe4
90
91 #define CLK_RESET_PLLP_OUTA             0xa4
92 #define CLK_RESET_PLLP_OUTB             0xa8
93
94 #define PMC_PLLP_WB0_OVERRIDE           0xf8
95
96 #define CLK_RESET_CLK_SOURCE_MSELECT    0x3b4
97
98 #define MSELECT_CLKM                    (0x3 << 30)
99
100 #if USE_PLL_LOCK_BITS
101 #define LOCK_DELAY              PLL_POST_LOCK_DELAY
102 #else
103 #define LOCK_DELAY              0xff /* 255uS delay for PLL stabilization */
104 #endif
105
106 #define USE_PLLP_ON_SLEEP_ENTRY 0
107
108 .macro emc_device_mask, rd, base
109         ldr     \rd, [\base, #EMC_ADR_CFG]
110         tst     \rd, #0x1
111         moveq   \rd, #(0x1<<8)          @ just 1 device
112         movne   \rd, #(0x3<<8)          @ 2 devices
113 .endm
114
115 .macro emc_timing_update, rd, base
116         mov     \rd, #1
117         str     \rd, [\base, #EMC_TIMING_CONTROL]
118 1001:
119         ldr     \rd, [\base, #EMC_EMC_STATUS]
120         tst     \rd, #(0x1<<23)         @ wait until EMC_STATUS_TIMING_UPDATE_STALLED is clear
121         bne     1001b
122 .endm
123
124 #ifdef CONFIG_HOTPLUG_CPU
125 /*
126  * tegra3_hotplug_shutdown(void)
127  *
128  * Powergates the current CPU.
129  * Should never return.
130  */
131 ENTRY(tegra3_hotplug_shutdown)
132         mov     r6, lr
133         bl      tegra_cpu_exit_coherency
134
135         /* Powergate this CPU. */
136         mov     r0, #TEGRA_POWER_HOTPLUG_SHUTDOWN
137         bl      tegra3_cpu_reset
138         mov     pc, r6                          @ should never get here
139 ENDPROC(tegra3_hotplug_shutdown)
140 #endif
141
142 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
143 /*
144  * tegra3_cpu_reset(unsigned long flags)
145  *
146  * Puts the current CPU in wait-for-event mode on the flow controller
147  * and powergates it -- flags (in R0) indicate the request type.
148  * Must never be called for CPU 0.
149  *
150  * corrupts r0-r4, r12
151  */
152 ENTRY(tegra3_cpu_reset)
153         cpu_id  r3
154         cmp     r3, #0
155         moveq   pc, lr          @ Must never be called for CPU 0
156
157         mov32   r12, TEGRA_FLOW_CTRL_VIRT
158         cpu_to_csr_reg r1, r3
159         add     r1, r1, r12     @ virtual CSR address for this CPU
160         cpu_to_halt_reg r2, r3
161         add     r2, r2, r12     @ virtual HALT_EVENTS address for this CPU
162
163         /* Clear this CPU's "event" and "interrupt" flags and power gate
164            it when halting but not before it is in the "WFE" state. */
165         movw    r12, FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | FLOW_CTRL_CSR_ENABLE
166         mov     r4, #(1 << 4)
167         orr     r12, r12, r4, lsl r3
168         str     r12, [r1]
169
170         /* Halt this CPU. */
171         mov     r3, #0x400
172 delay_1:
173         subs    r3, r3, #1                              @ delay as a part of wfe war.
174         bge     delay_1;
175         cpsid   a                                       @ disable imprecise aborts.
176         ldr     r3, [r1]                                @ read CSR
177         str     r3, [r1]                                @ clear CSR
178         tst     r0, #TEGRA_POWER_HOTPLUG_SHUTDOWN
179         moveq   r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT       @ For LP2
180         movne   r3, #FLOW_CTRL_WAITEVENT                @ For hotplug
181         str     r3, [r2]
182         ldr     r0, [r2]
183         b       wfe_war
184
185 __cpu_reset_again:
186         dsb
187         .align 5
188         wfe                                     @ CPU should be power gated here
189 wfe_war:
190         b       __cpu_reset_again
191
192         /* 38 nop's, which fills reset of wfe cache line and 4 more cachelines with nop*/
193         .rept 38
194         nop
195         .endr
196         b       .                               @ should never get here
197
198 ENDPROC(tegra3_cpu_reset)
199 #endif
200
201 #ifdef CONFIG_PM_SLEEP
202
203 /*
204  * tegra3_sleep_core_finish(unsigned long int)
205  *
206  * enters suspend in LP0 or LP1 by turning off the mmu and jumping to
207  * tegra3_tear_down_core in IRAM
208  */
209 ENTRY(tegra3_sleep_core_finish)
210         bl      tegra_cpu_exit_coherency
211
212         /* preload all the address literals that are needed for the
213          * CPU power-gating process, to avoid loads from SDRAM (which are
214          * not supported once SDRAM is put into self-refresh.
215          * LP0 / LP1 use physical address, since the MMU needs to be
216          * disabled before putting SDRAM into self-refresh to avoid
217          * memory access due to page table walks */
218         mov32   r4, TEGRA_PMC_BASE
219         mov32   r5, TEGRA_CLK_RESET_BASE
220         mov32   r6, TEGRA_FLOW_CTRL_BASE
221         mov32   r7, TEGRA_TMRUS_BASE
222
223         mov32   r1, tegra3_tear_down_core
224         mov32   r2, tegra3_iram_start
225         sub     r1, r1, r2
226         mov32   r2, TEGRA_IRAM_CODE_AREA
227         add     r1, r1, r2
228         b       tegra_turn_off_mmu
229 ENDPROC(tegra3_sleep_core_finish)
230
231 /*
232  * tegra3_sleep_cpu_secondary_finish(unsigned long v2p)
233  *
234  * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
235  */
236 ENTRY(tegra3_sleep_cpu_secondary_finish)
237         mov     r6, lr
238
239         dsb
240 #ifdef MULTI_CACHE
241         mov32   r10, cpu_cache
242         mov     lr, pc
243         ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
244 #else
245         bl      __cpuc_flush_kern_all
246 #endif
247
248         bl      tegra_cpu_exit_coherency
249
250         /* Powergate this CPU. */
251         mov     r0, #0                          @ power mode flags (!hotplug)
252         bl      tegra3_cpu_reset
253         mov     r0, #1                          @ never return here
254         mov     pc, r6
255 ENDPROC(tegra3_sleep_cpu_secondary_finish)
256
257 /*
258  * tegra3_tear_down_cpu
259  *
260  * Switches the CPU cluster to PLL-P and enters sleep.
261  */
262 ENTRY(tegra3_tear_down_cpu)
263         mov32   r4, TEGRA_PMC_BASE
264         mov32   r5, TEGRA_CLK_RESET_BASE
265         mov32   r6, TEGRA_FLOW_CTRL_BASE
266         mov32   r7, TEGRA_TMRUS_BASE
267 #if USE_PLLP_ON_SLEEP_ENTRY
268         bl      tegra_cpu_pllp
269 #endif
270         b       tegra3_enter_sleep
271 ENDPROC(tegra3_tear_down_cpu)
272
273 /* START OF ROUTINES COPIED TO IRAM */
274         .align L1_CACHE_SHIFT
275         .globl tegra3_iram_start
276 tegra3_iram_start:
277
278 /*
279  * tegra3_lp1_reset
280  *
281  * reset vector for LP1 restore; copied into IRAM during suspend.
282  * brings the system back up to a safe starting point (SDRAM out of
283  * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
284  * system clock running on the same PLL that it suspended at), and
285  * jumps to tegra_lp2_startup to restore PLLX and virtual addressing.
286  * physical address of tegra_lp2_startup expected to be stored in
287  * PMC_SCRATCH41
288  *
289  * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA AND MUST BE FIRST.
290  */
291 .macro pll_enable, rd, car, base, misc
292         ldr     \rd, [\car, #\base]
293         tst     \rd, #(1<<30)
294         orreq   \rd, \rd, #(1<<30)
295         streq   \rd, [\car, #\base]
296 #if USE_PLL_LOCK_BITS
297         ldr     \rd, [\car, #\misc]
298         orr     \rd, \rd, #(1<<18)
299         str     \rd, [\car, #\misc]
300 #endif
301 .endm
302
303 .macro pll_locked, rd, car, base
304 #if USE_PLL_LOCK_BITS
305 1:
306         ldr     \rd, [\car, #\base]
307         tst     \rd, #(1<<27)
308         beq     1b
309 #endif
310 .endm
311
312 ENTRY(tegra3_lp1_reset)
313         /* the CPU and system bus are running at 32KHz and executing from
314          * IRAM when this code is executed; immediately switch to CLKM and
315          * enable PLLP, PLLM, PLLC, PLLA and PLLX. */
316         mov32   r0, TEGRA_CLK_RESET_BASE
317 #ifndef CONFIG_TRUSTED_FOUNDATIONS
318         /* secure code handles 32KHz to CLKM/OSC clock switch */
319         mov     r1, #(1<<28)
320         str     r1, [r0, #CLK_RESET_SCLK_BURST]
321         str     r1, [r0, #CLK_RESET_CCLK_BURST]
322         mov     r1, #0
323         str     r1, [r0, #CLK_RESET_SCLK_DIVIDER]
324         str     r1, [r0, #CLK_RESET_CCLK_DIVIDER]
325 #endif
326         /* enable PLLM via PMC */
327         mov32   r2, TEGRA_PMC_BASE
328         ldr     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
329         orr     r1, r1, #(1<<12)
330         str     r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
331
332         pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
333         pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
334         pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
335         pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
336         pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
337
338         pll_locked r1, r0, CLK_RESET_PLLM_BASE
339         pll_locked r1, r0, CLK_RESET_PLLP_BASE
340         pll_locked r1, r0, CLK_RESET_PLLA_BASE
341         pll_locked r1, r0, CLK_RESET_PLLC_BASE
342         pll_locked r1, r0, CLK_RESET_PLLX_BASE
343
344         mov32   r7, TEGRA_TMRUS_BASE
345         ldr     r1, [r7]
346         add     r1, r1, #LOCK_DELAY
347         wait_until r1, r7, r3
348
349         add     r5, pc, #tegra3_sdram_pad_save-(.+8)    @ r5 reserved for pad base
350
351         ldr     r4, [r5, #0x18]
352         str     r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
353
354         ldr     r4, [r5, #0x1C]
355         str     r4, [r0, #CLK_RESET_SCLK_BURST]
356
357         mov32   r4, ((1<<28) | (8))     @ burst policy is PLLX
358         str     r4, [r0, #CLK_RESET_CCLK_BURST]
359
360 #if defined (CONFIG_CACHE_L2X0)
361         /* power up L2 */
362         ldr     r0, [r2, #PMC_PWRGATE_STATUS]
363         tst     r0, #(1<<PMC_PWRGATE_PARTID_L2C)
364         bne     powerup_l2_done
365         movw    r0, #(1<<8) | PMC_PWRGATE_PARTID_L2C
366         str     r0, [r2, #PMC_PWRGATE_TOGGLE]
367 powerup_l2_wait:
368         ldr     r0, [r2, #PMC_PWRGATE_STATUS]
369         tst     r0, #(1<<PMC_PWRGATE_PARTID_L2C)
370         beq     powerup_l2_wait
371 powerup_l2_done:
372         mov     r0, #PMC_PWRGATE_PARTID_L2C
373         str     r0, [r2, #PMC_REMOVE_CLAMPING_CMD]
374 #endif
375
376         mov32   r0, TEGRA_EMC_BASE                      @ r0 reserved for emc base
377
378         ldr     r1, [r5, #0x14] @ PMC_IO_DPD_STATUS
379         mvn     r1, r1
380         bic     r1, r1, #(0x1<<31)
381         orr     r1, r1, #(0x1<<30)
382         str     r1, [r2, #PMC_IO_DPD_REQ]
383         ldr     r1, [r5, #0xC]
384         str     r1, [r0, #EMC_XM2VTTGENPADCTRL]
385         ldr     r1, [r5, #0x10]
386         str     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
387         ldr     r1, [r5, #0x8]
388         str     r1, [r0, #EMC_AUTO_CAL_INTERVAL]
389
390         ldr     r1, [r0, #EMC_CFG_DIG_DLL]
391         orr     r1, r1, #(0x1<<30)              @ set DLL_RESET
392         str     r1, [r0, #EMC_CFG_DIG_DLL]
393
394         emc_timing_update r1, r0
395
396         ldr     r1, [r0, #EMC_AUTO_CAL_CONFIG]
397         orr     r1, r1, #(0x1<<31)              @ set AUTO_CAL_ACTIVE
398         str     r1, [r0, #EMC_AUTO_CAL_CONFIG]
399
400 emc_wait_audo_cal_onetime:
401         ldr     r1, [r0, #EMC_AUTO_CAL_STATUS]
402         tst     r1, #(0x1<<31)          @ wait until AUTO_CAL_ACTIVE is clear
403         bne     emc_wait_audo_cal_onetime
404
405         ldr     r1, [r0, #EMC_CFG]
406         bic     r1, r1, #(1<<31)        @ disable DRAM_CLK_STOP
407         str     r1, [r0, #EMC_CFG]
408
409         mov     r1, #0
410         str     r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
411         mov     r1, #1
412         str     r1, [r0, #EMC_NOP]
413         str     r1, [r0, #EMC_NOP]
414         str     r1, [r0, #EMC_REFRESH]
415
416         emc_device_mask r1, r0
417
418 exit_selfrefresh_loop:
419         ldr     r2, [r0, #EMC_EMC_STATUS]
420         ands    r2, r2, r1
421         bne     exit_selfrefresh_loop
422
423         lsr     r1, r1, #8              @ devSel, bit0:dev0 bit1:dev1
424
425         mov32   r7, TEGRA_TMRUS_BASE
426         ldr     r2, [r0, #EMC_FBIO_CFG5]
427
428         and     r2, r2, #3
429         cmp     r2, #2
430         beq     emc_lpddr2
431
432         mov32   r2, 0x80000011
433         str     r2, [r0, #EMC_ZQ_CAL]
434         ldr     r2, [r7]
435         add     r2, r2, #10
436         wait_until r2, r7, r3
437
438         tst     r1, #2
439         beq zcal_done
440
441         mov32   r2, 0x40000011
442         str     r2, [r0, #EMC_ZQ_CAL]
443         ldr     r2, [r7]
444         add     r2, r2, #10
445         wait_until r2, r7, r3
446         b zcal_done
447
448 emc_lpddr2:
449
450         mov32   r2, 0x800A00AB
451         str     r2, [r0, #EMC_MRW]
452         ldr     r2, [r7]
453         add     r2, r2, #1
454         wait_until r2, r7, r3
455
456         tst     r1, #2
457         beq zcal_done
458
459         mov32   r2, 0x400A00AB
460         str     r2, [r0, #EMC_MRW]
461         ldr     r2, [r7]
462         add     r2, r2, #1
463         wait_until r2, r7, r3
464
465 zcal_done:
466
467         mov     r1, #0
468         str     r1, [r0, #EMC_REQ_CTRL]
469         ldr     r1, [r5, #0x4]
470         str     r1, [r0, #EMC_ZCAL_INTERVAL]
471         ldr     r1, [r5, #0x0]
472         str     r1, [r0, #EMC_CFG]
473
474         mov32   r0, TEGRA_PMC_BASE
475         ldr     r0, [r0, #PMC_SCRATCH41]
476         mov     pc, r0
477 ENDPROC(tegra3_lp1_reset)
478
479         .align  L1_CACHE_SHIFT
480         .type   tegra3_sdram_pad_save, %object
481 tegra3_sdram_pad_save:
482         .word   0
483         .word   0
484         .word   0
485         .word   0
486         .word   0
487         .word   0
488         .word   0
489         .word   0
490
491 tegra3_sdram_pad_address:
492         .word   TEGRA_EMC_BASE + EMC_CFG                                @0x0
493         .word   TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL                      @0x4
494         .word   TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL                  @0x8
495         .word   TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL                   @0xc
496         .word   TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2                  @0x10
497         .word   TEGRA_PMC_BASE + PMC_IO_DPD_STATUS                      @0x14
498         .word   TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT     @0x18
499         .word   TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST             @0x1c
500
501 tegra3_sdram_pad_size:
502         .word   tegra3_sdram_pad_address - tegra3_sdram_pad_save
503
504 /*
505  * tegra3_tear_down_core
506  *
507  * copied into and executed from IRAM
508  * puts memory in self-refresh for LP0 and LP1
509  */
510 tegra3_tear_down_core:
511         bl      tegra3_sdram_self_refresh
512         bl      tegra3_cpu_clk32k
513         b       tegra3_enter_sleep
514
515 /*
516  * tegra3_cpu_clk32k
517  *
518  * In LP0 and LP1 all plls will be turned off.  Switch the CPU and system clock
519  * to the 32khz clock (clks)
520  * r4 = TEGRA_PMC_BASE
521  * r5 = TEGRA_CLK_RESET_BASE
522  * r6 = TEGRA_FLOW_CTRL_BASE
523  * r7 = TEGRA_TMRUS_BASE
524  */
525 tegra3_cpu_clk32k:
526         ldr     r0, [r4, #PMC_CTRL]
527         tst     r0, #PMC_CTRL_SIDE_EFFECT_LP0
528         beq     lp1_clocks_prepare
529
530         /* enable PLLM via PMC in LP0 */
531         ldr     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
532         orr     r0, r0, #((1 << 12) | (1 << 11))
533         str     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
534         mov     pc, lr
535
536         /* start by jumping to clkm to safely disable PLLs, then jump
537          * to clks */
538 lp1_clocks_prepare:
539         mov     r0, #(1 << 28)
540         str     r0, [r5, #CLK_RESET_SCLK_BURST]
541         str     r0, [r5, #CLK_RESET_CCLK_BURST]
542         mov     r0, #0
543         str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
544         str     r0, [r5, #CLK_RESET_SCLK_DIVIDER]
545
546         /* switch the clock source for mselect to be CLK_M */
547         ldr     r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
548         orr     r0, r0, #MSELECT_CLKM
549         str     r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
550
551         /* 2 us delay between changing sclk and disabling PLLs */
552         wait_for_us r1, r7, r9
553         add     r1, r1, #2
554         wait_until r1, r7, r9
555
556         /* switch to CLKS */
557         mov     r0, #0  /* burst policy = 32KHz */
558         str     r0, [r5, #CLK_RESET_SCLK_BURST]
559
560         /* disable PLLM via PMC in LP1 */
561         ldr     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
562         bic     r0, r0, #(1 << 12)
563         str     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
564         b       powerdown_pll_pcx
565
566 powerdown_pll_pcx:
567         ldr     r11, [r4, #PMC_SCRATCH37]       @ load the LP1 flags
568         tst     r11, #TEGRA_POWER_LP1_AUDIO     @ check if voice call is going on
569         bne     powerdown_pll_cx                @ if yes, do not turn off pll-p/pll-a
570
571         ldr     r0, [r5, #CLK_RESET_PLLP_BASE]
572         bic     r0, r0, #(1<<30)
573         str     r0, [r5, #CLK_RESET_PLLP_BASE]
574         ldr     r0, [r5, #CLK_RESET_PLLA_BASE]
575         bic     r0, r0, #(1<<30)
576         str     r0, [r5, #CLK_RESET_PLLA_BASE]
577
578 powerdown_pll_cx:
579         ldr     r0, [r5, #CLK_RESET_PLLC_BASE]
580         bic     r0, r0, #(1<<30)
581         str     r0, [r5, #CLK_RESET_PLLC_BASE]
582         ldr     r0, [r5, #CLK_RESET_PLLX_BASE]
583         bic     r0, r0, #(1<<30)
584         str     r0, [r5, #CLK_RESET_PLLX_BASE]
585
586         mov     pc, lr
587
588 /*
589  * tegra3_enter_sleep
590  *
591  * uses flow controller to enter sleep state
592  * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
593  * executes from SDRAM with target state is LP2
594  * r4 = TEGRA_PMC_BASE
595  * r5 = TEGRA_CLK_RESET_BASE
596  * r6 = TEGRA_FLOW_CTRL_BASE
597  * r7 = TEGRA_TMRUS_BASE
598  */
599 tegra3_enter_sleep:
600         ldr     r1, [r7]
601         str     r1, [r4, #PMC_SCRATCH38]
602         dsb
603         cpu_id  r1
604
605         cpu_to_csr_reg  r2, r1
606         ldr     r0, [r6, r2]
607         orr     r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
608         orr     r0, r0, #FLOW_CTRL_CSR_ENABLE
609         str     r0, [r6, r2]
610
611         mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
612         orr     r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
613         cpu_to_halt_reg r2, r1
614         str     r0, [r6, r2]
615         dsb
616         ldr     r0, [r6, r2] /* memory barrier */
617
618 halted:
619         isb
620         dsb
621         wfi     /* CPU should be power gated here */
622
623         /* !!!FIXME!!! Implement halt failure handler */
624         b       halted
625
626 /*
627  * tegra3_sdram_self_refresh
628  *
629  * called with MMU off and caches disabled
630  /* puts sdram in self refresh
631  * must execute from IRAM
632  * r4 = TEGRA_PMC_BASE
633  * r5 = TEGRA_CLK_RESET_BASE
634  * r6 = TEGRA_FLOW_CTRL_BASE
635  * r7 = TEGRA_TMRUS_BASE
636  */
637
638 tegra3_sdram_self_refresh:
639
640         adr     r2, tegra3_sdram_pad_address
641         adr     r8, tegra3_sdram_pad_save
642         mov     r9, #0
643
644 padsave:
645         ldr     r0, [r2, r9]                    @ r0 is emc register address
646
647         ldr     r1, [r0]
648         str     r1, [r8, r9]                    @ save emc register
649
650         add     r9, r9, #4
651         ldr     r0, tegra3_sdram_pad_size
652         cmp     r0, r9
653         bne     padsave
654 padsave_done:
655
656         dsb
657
658         mov32   r0, TEGRA_EMC_BASE                      @ r0 reserved for emc base
659
660         mov     r1, #0
661         str     r1, [r0, #EMC_ZCAL_INTERVAL]
662         str     r1, [r0, #EMC_AUTO_CAL_INTERVAL]
663         ldr     r1, [r0, #EMC_CFG]
664         bic     r1, r1, #(1<<28)
665         str     r1, [r0, #EMC_CFG]              @ disable DYN_SELF_REF
666
667         emc_timing_update r1, r0
668
669         ldr     r1, [r7]
670         add     r1, r1, #5
671         wait_until r1, r7, r2
672
673 emc_wait_audo_cal:
674         ldr     r1, [r0, #EMC_AUTO_CAL_STATUS]
675         tst     r1, #(0x1<<31)          @ wait until AUTO_CAL_ACTIVE is clear
676         bne     emc_wait_audo_cal
677
678         mov     r1, #3
679         str     r1, [r0, #EMC_REQ_CTRL]         @ stall incoming DRAM requests
680
681 emcidle:
682         ldr     r1, [r0, #EMC_EMC_STATUS]
683         tst     r1, #4
684         beq     emcidle
685
686         mov     r1, #1
687         str     r1, [r0, #EMC_SELF_REF]
688
689         emc_device_mask r1, r0
690
691 emcself:
692         ldr     r2, [r0, #EMC_EMC_STATUS]
693         and     r2, r2, r1
694         cmp     r2, r1
695         bne     emcself                         @ loop until DDR in self-refresh
696
697         ldr     r1, [r0, #EMC_XM2VTTGENPADCTRL]
698         mov32   r2, 0xF8F8FFFF          @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
699         and     r1, r1, r2
700         str     r1, [r0, #EMC_XM2VTTGENPADCTRL]
701         ldr     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
702         orr     r1, r1, #7                      @ set E_NO_VTTGEN
703         str     r1, [r0, #EMC_XM2VTTGENPADCTRL2]
704
705         emc_timing_update r1, r0
706
707         ldr     r1, [r4, #PMC_CTRL]
708         tst     r1, #PMC_CTRL_SIDE_EFFECT_LP0
709         bne     pmc_io_dpd_skip
710         mov32   r1, 0x8EC00000
711         str     r1, [r4, #PMC_IO_DPD_REQ]
712 pmc_io_dpd_skip:
713
714         dsb
715
716         mov     pc, lr
717
718         .ltorg
719 /* dummy symbol for end of IRAM */
720         .align L1_CACHE_SHIFT
721         .globl tegra3_iram_end
722 tegra3_iram_end:
723         b       .
724 #endif