]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/arm/mach-tegra/sleep-tegra30.S
Merge tag 'for-linus-3.11-merge-window-part-2' of git://git.kernel.org/pub/scm/linux...
[karo-tx-linux.git] / arch / arm / mach-tegra / sleep-tegra30.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/linkage.h>
18
19 #include <asm/assembler.h>
20 #include <asm/asm-offsets.h>
21
22 #include "fuse.h"
23 #include "sleep.h"
24 #include "flowctrl.h"
25
26 #define TEGRA30_POWER_HOTPLUG_SHUTDOWN  (1 << 27) /* Hotplug shutdown */
27
28 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
29 /*
30  * tegra30_hotplug_shutdown(void)
31  *
32  * Powergates the current CPU.
33  * Should never return.
34  */
35 ENTRY(tegra30_hotplug_shutdown)
36         /* Powergate this CPU */
37         mov     r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
38         bl      tegra30_cpu_shutdown
39         mov     pc, lr                  @ should never get here
40 ENDPROC(tegra30_hotplug_shutdown)
41
42 /*
43  * tegra30_cpu_shutdown(unsigned long flags)
44  *
45  * Puts the current CPU in wait-for-event mode on the flow controller
46  * and powergates it -- flags (in R0) indicate the request type.
47  *
48  * r10 = SoC ID
49  * corrupts r0-r4, r10-r12
50  */
51 ENTRY(tegra30_cpu_shutdown)
52         cpu_id  r3
53         tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
54         cmp     r10, #TEGRA30
55         bne     _no_cpu0_chk    @ It's not Tegra30
56
57         cmp     r3, #0
58         moveq   pc, lr          @ Must never be called for CPU 0
59 _no_cpu0_chk:
60
61         ldr     r12, =TEGRA_FLOW_CTRL_VIRT
62         cpu_to_csr_reg r1, r3
63         add     r1, r1, r12     @ virtual CSR address for this CPU
64         cpu_to_halt_reg r2, r3
65         add     r2, r2, r12     @ virtual HALT_EVENTS address for this CPU
66
67         /*
68          * Clear this CPU's "event" and "interrupt" flags and power gate
69          * it when halting but not before it is in the "WFE" state.
70          */
71         movw    r12, \
72                 FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
73                 FLOW_CTRL_CSR_ENABLE
74         cmp     r10, #TEGRA30
75         moveq   r4, #(1 << 4)                   @ wfe bitmap
76         movne   r4, #(1 << 8)                   @ wfi bitmap
77  ARM(   orr     r12, r12, r4, lsl r3    )
78  THUMB( lsl     r4, r4, r3              )
79  THUMB( orr     r12, r12, r4            )
80         str     r12, [r1]
81
82         /* Halt this CPU. */
83         mov     r3, #0x400
84 delay_1:
85         subs    r3, r3, #1                      @ delay as a part of wfe war.
86         bge     delay_1;
87         cpsid   a                               @ disable imprecise aborts.
88         ldr     r3, [r1]                        @ read CSR
89         str     r3, [r1]                        @ clear CSR
90
91         tst     r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
92         beq     flow_ctrl_setting_for_lp2
93
94         /* flow controller set up for hotplug */
95         mov     r3, #FLOW_CTRL_WAITEVENT                @ For hotplug
96         b       flow_ctrl_done
97 flow_ctrl_setting_for_lp2:
98         /* flow controller set up for LP2 */
99         cmp     r10, #TEGRA30
100         moveq   r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT       @ For LP2
101         movne   r3, #FLOW_CTRL_WAITEVENT
102 flow_ctrl_done:
103         cmp     r10, #TEGRA30
104         str     r3, [r2]
105         ldr     r0, [r2]
106         b       wfe_war
107
108 __cpu_reset_again:
109         dsb
110         .align 5
111         wfeeq                                   @ CPU should be power gated here
112         wfine
113 wfe_war:
114         b       __cpu_reset_again
115
116         /*
117          * 38 nop's, which fills reset of wfe cache line and
118          * 4 more cachelines with nop
119          */
120         .rept 38
121         nop
122         .endr
123         b       .                               @ should never get here
124
125 ENDPROC(tegra30_cpu_shutdown)
126 #endif
127
128 #ifdef CONFIG_PM_SLEEP
129 /*
130  * tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
131  *
132  * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
133  */
134 ENTRY(tegra30_sleep_cpu_secondary_finish)
135         mov     r7, lr
136
137         /* Flush and disable the L1 data cache */
138         bl      tegra_disable_clean_inv_dcache
139
140         /* Powergate this CPU. */
141         mov     r0, #0                          @ power mode flags (!hotplug)
142         bl      tegra30_cpu_shutdown
143         mov     r0, #1                          @ never return here
144         mov     pc, r7
145 ENDPROC(tegra30_sleep_cpu_secondary_finish)
146
147 /*
148  * tegra30_tear_down_cpu
149  *
150  * Switches the CPU to enter sleep.
151  */
152 ENTRY(tegra30_tear_down_cpu)
153         mov32   r6, TEGRA_FLOW_CTRL_BASE
154
155         b       tegra30_enter_sleep
156 ENDPROC(tegra30_tear_down_cpu)
157
158 /*
159  * tegra30_enter_sleep
160  *
161  * uses flow controller to enter sleep state
162  * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
163  * executes from SDRAM with target state is LP2
164  * r6 = TEGRA_FLOW_CTRL_BASE
165  */
166 tegra30_enter_sleep:
167         cpu_id  r1
168
169         cpu_to_csr_reg  r2, r1
170         ldr     r0, [r6, r2]
171         orr     r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
172         orr     r0, r0, #FLOW_CTRL_CSR_ENABLE
173         str     r0, [r6, r2]
174
175         mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
176         orr     r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
177         cpu_to_halt_reg r2, r1
178         str     r0, [r6, r2]
179         dsb
180         ldr     r0, [r6, r2] /* memory barrier */
181
182 halted:
183         isb
184         dsb
185         wfi     /* CPU should be power gated here */
186
187         /* !!!FIXME!!! Implement halt failure handler */
188         b       halted
189
190 #endif