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