ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / sleep.S
1 /*
2  * arch/arm/mach-tegra/sleep.S
3  *
4  * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
5  * Copyright (c) 2011, Google, Inc.
6  *
7  * Author: Colin Cross <ccross@android.com>
8  *         Gary King <gking@nvidia.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/const.h>
26 #include <linux/init.h>
27 #include <linux/linkage.h>
28
29 #include <asm/assembler.h>
30 #include <asm/cache.h>
31 #include <asm/domain.h>
32 #include <asm/memory.h>
33 #include <asm/page.h>
34 #include <asm/ptrace.h>
35 #include <asm/asm-offsets.h>
36 #include <asm/glue-cache.h>
37 #include <asm/glue-proc.h>
38 #include <asm/cp15.h>
39 #include <asm/hardware/cache-l2x0.h>
40
41 #include "iomap.h"
42
43 #include "sleep.h"
44 #include "flowctrl.h"
45 #include "reset.h"
46
47 #define CLK_RESET_CCLK_BURST            0x20
48 #define CLK_RESET_CCLK_DIVIDER          0x24
49
50 #define TEGRA_PMC_VIRT          (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
51
52 #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
53                                         + IO_PPSB_VIRT)
54
55 /*
56  * tegra_pen_lock
57  *
58  * spinlock implementation with no atomic test-and-set and no coherence
59  * using Peterson's algorithm on strongly-ordered registers
60  * used to synchronize a cpu waking up from wfi with entering lp2 on idle
61  *
62  * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
63  * on cpu 0:
64  * SCRATCH38 = r2 = flag[0]
65  * SCRATCH39 = r3 = flag[1]
66  * on cpu1:
67  * SCRATCH39 = r2 = flag[1]
68  * SCRATCH38 = r3 = flag[0]
69  *
70  * must be called with MMU on
71  * corrupts r0-r3, r12
72  */
73 ENTRY(tegra_pen_lock)
74         mov32   r3, TEGRA_PMC_VIRT
75         cpu_id  r0
76         add     r1, r3, #PMC_SCRATCH37
77         cmp     r0, #0
78         addeq   r2, r3, #PMC_SCRATCH38
79         addeq   r3, r3, #PMC_SCRATCH39
80         addne   r2, r3, #PMC_SCRATCH39
81         addne   r3, r3, #PMC_SCRATCH38
82
83         mov     r12, #1
84         str     r12, [r2]               @ flag[cpu] = 1
85         dsb
86         str     r12, [r1]               @ !turn = cpu
87 1:      dsb
88         ldr     r12, [r3]
89         cmp     r12, #1                 @ flag[!cpu] == 1?
90         ldreq   r12, [r1]
91         cmpeq   r12, r0                 @ !turn == cpu?
92         beq     1b                      @ while !turn == cpu && flag[!cpu] == 1
93
94         mov     pc, lr                  @ locked
95 ENDPROC(tegra_pen_lock)
96
97 ENTRY(tegra_pen_unlock)
98         dsb
99         mov32   r3, TEGRA_PMC_VIRT
100         cpu_id  r0
101         cmp     r0, #0
102         addeq   r2, r3, #PMC_SCRATCH38
103         addne   r2, r3, #PMC_SCRATCH39
104         mov     r12, #0
105         str     r12, [r2]
106         mov     pc, lr
107 ENDPROC(tegra_pen_unlock)
108
109 /*
110  * tegra_cpu_exit_coherency
111  *
112  * Exits SMP coherency.
113  * corrupts r4-r5
114  */
115 ENTRY(tegra_cpu_exit_coherency)
116         exit_smp r4, r5
117         mov     pc, lr
118 ENDPROC(tegra_cpu_exit_coherency)
119
120 /*
121  * tegra_flush_cache
122  *
123  * clean & invalidate inner cache
124  *
125  * Disable is needed before flush to prevent allocations during flush
126  * When cache is disabled, we cannot push to stack.
127  */
128 ENTRY(tegra_flush_cache)
129         stmfd   sp!, {r4-r5, r7, r9-r11, lr}
130         dmb                                     @ ensure ordering
131
132         /* Disable the data cache */
133         mrc     p15, 0, r2, c1, c0, 0
134         bic     r2, r2, #CR_C
135         dsb
136         mcr     p15, 0, r2, c1, c0, 0
137
138         bl      v7_flush_dcache_all
139
140         ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
141         mov     pc, lr
142 ENDPROC(tegra_flush_cache)
143
144 /*
145  * tegra_flush_l1_cache
146  *
147  * clean & invalidate the L1 cache
148  *
149  * The flush_cache_all flushes all caches within level of coherence, this
150  * may not be desired if all we need is to flush L1 only. Therefore this
151  * function is implemented to flush the L1 cache only.
152  *
153  * Disable is needed before flush to prevent allocations during flush
154  * When cache is disabled, we cannot push to stack.
155  *
156  * Corrupted registers: r0-r7, r9-r11
157  */
158 ENTRY(tegra_flush_l1_cache)
159         stmfd   sp!, {r4-r5, r7, r9-r11, lr}
160         dmb                                     @ ensure ordering with previous memory accesses
161
162         /* Disable the data cache */
163         mrc     p15, 0, r2, c1, c0, 0
164         bic     r2, r2, #CR_C
165         dsb
166         mcr     p15, 0, r2, c1, c0, 0
167
168         mov     r10, #0
169 #ifdef CONFIG_PREEMPT
170         save_and_disable_irqs_notrace r9
171 #endif
172         mcr     p15, 2, r10, c0, c0, 0          @ select cache level 0
173         isb
174         mrc     p15, 1, r1, c0, c0, 0           @ read the new csidr
175 #ifdef CONFIG_PREEMPT
176         restore_irqs_notrace r9
177 #endif
178         and     r2, r1, #7                                      @ extract the length of the cache lines
179         add     r2, r2, #4                                      @ add 4 (line length offset)
180         ldr     r4, =0x3ff
181         ands    r4, r4, r1, lsr #3              @ find maximum number on the way size
182         clz     r5, r4                                          @ find bit position of way size increment
183         ldr     r7, =0x7fff
184         ands    r7, r7, r1, lsr #13             @ extract max number of the index size
185 1001:
186         mov     r9, r4                                          @ create working copy of max way size
187 1002:
188         orr     r11, r10, r9, lsl r5            @ factor way and cache number into r11
189         orr     r11, r11, r7, lsl r2            @ factor index number into r11
190         mcr     p15, 0, r11, c7, c14, 2         @ op=c10/c14, clean/flush by set/way
191         subs    r9, r9, #1                              @ decrement the way
192         bge     1002b
193         subs    r7, r7, #1                              @ decrement the index
194         bge     1001b
195         mcr     p15, 2, r10, c0, c0, 0          @ restore cache level 0
196         isb
197         dsb
198         ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
199         mov     pc, lr
200 ENDPROC(tegra_flush_l1_cache)
201
202 #ifdef CONFIG_PM_SLEEP
203 /*
204  * tegra_sleep_cpu_finish(unsigned long int)
205  *
206  * enters suspend in LP2 by turning off the mmu and jumping to
207  * tegra?_tear_down_cpu
208  */
209 ENTRY(tegra_sleep_cpu_finish)
210         mov     r4, r0
211 #if defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
212         ldr     r0, =0x84000001
213         ldr     r1, =((1 << 16) | 4)
214         ldr     r2, =TEGRA_RESET_HANDLER_BASE
215         bl      tegra_generic_smc
216 #else
217         bl      tegra_flush_cache
218 #endif
219
220         mov     r0, r4
221         bl      tegra_cpu_exit_coherency
222
223 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
224         mov32   r1, tegra2_tear_down_cpu
225 #else
226         mov32   r1, tegra3_tear_down_cpu
227 #endif
228         add     r1, r1, r0
229         mov     r11, #1
230         b       tegra_turn_off_mmu
231 ENDPROC(tegra_sleep_cpu_finish)
232
233 /*
234  * tegra_turn_off_mmu
235  *
236  * r0 = v2p
237  * r1 = physical address to jump to with mmu off
238  * r11 = L2 disable/flush
239  */
240 ENTRY(tegra_turn_off_mmu)
241         /*
242          * change page table pointer to tegra_pgd_phys, so that IRAM
243          * and MMU shut-off will be mapped virtual == physical
244          */
245 #if defined(CONFIG_ARM_LPAE)
246         mrrc    p15, 0, r3, r8, c2      @ TTB 0
247         ldr     r2, tegra_pgd_phys_address
248         ldrd    r2, r3, [r2]
249         bic     r8, r8, #0xFF           @ clear base_addr[40:32] from TTB 0
250         orr     r8, r8, r3              @ load new base_addr[40:32] into TTB 0
251         mov     r3, #0
252         mcr     p15, 0, r3, c13, c0, 1  @ reserved context
253         isb
254         mcrr    p15, 0, r2, r8, c2      @ TTB 0
255 #else
256         mrc     p15, 0, r2, c2, c0, 0   @ TTB 0
257         mov32   r3, ~PAGE_MASK
258         and     r2, r2, r3
259         ldr     r3, tegra_pgd_phys_address
260         ldr     r3, [r3]
261         orr     r3, r3, r2
262         mov     r2, #0
263         mcr     p15, 0, r2, c13, c0, 1  @ reserved context
264         isb
265         mcr     p15, 0, r3, c2, c0, 0   @ TTB 0
266 #endif
267         isb
268
269         mcr     p15, 0, r2, c8, c3, 0   @ invalidate TLB
270         mcr     p15, 0, r2, c7, c5, 6   @ flush BTAC
271         mcr     p15, 0, r2, c7, c5, 0   @ flush instruction cache
272         dsb
273         isb
274
275         mov32   r3, tegra_shut_off_mmu
276         add     r3, r3, r0
277         mov     r0, r1
278         mov     pc, r3
279 ENDPROC(tegra_turn_off_mmu)
280
281 tegra_pgd_phys_address:
282         .word   tegra_pgd_phys
283
284 /*
285  * tegra_shut_off_mmu
286  *
287  * r0 = physical address to jump to with mmu off
288  * r11 = L2 disable/flush
289  *
290  * called with VA=PA mapping
291  * turns off MMU, icache, dcache and branch prediction
292  */
293         .align  L1_CACHE_SHIFT
294 tegra_shut_off_mmu:
295         mrc     p15, 0, r3, c1, c0, 0
296         movw    r2, #CR_I | CR_Z | CR_C | CR_M
297         bic     r3, r3, r2
298         dsb
299         mcr     p15, 0, r3, c1, c0, 0
300         isb
301 #if defined(CONFIG_CACHE_L2X0) && \
302                 !defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
303         tst     r11, #1
304         beq     2f
305         mov32   r1, TEGRA_ARM_PL310_BASE
306 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
307         /* need to flush the L2 */
308         ldr     r2, [r1, #L2X0_AUX_CTRL]
309         tst     r2, #(1 << 16)                  @ associativity
310         mov     r2, #0xff
311         orrne   r2, #0xff00
312         str     r2, [r1, #L2X0_CLEAN_INV_WAY]
313 1:      ldr     r3, [r1, #L2X0_CLEAN_INV_WAY]
314         tst     r3, r2
315         bne     1b
316 #endif /* CONFIG_ARCH_TEGRA_14x_SOC */
317         /* Sync and disable L2 */
318         mov     r2, #0
319         str     r2, [r1, #L2X0_CACHE_SYNC]
320         str     r2, [r1, #L2X0_CTRL]
321 #endif /* CONFIG_CACHE_L2X0 && !CONFIG_TEGRA_USE_SECURE_KERNEL */
322 2:      mov     pc, r0
323
324 /*
325  * tegra_cpu_clk32k
326  *
327  * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
328  */
329 ENTRY(tegra_cpu_pllp)
330         /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
331         mov32   r5, TEGRA_CLK_RESET_BASE
332         mov     r0, #(2 << 28)                  @ burst policy = run mode
333         orr     r0, r0, #(4 << 4)               @ use PLLP in run mode burst
334         str     r0, [r5, #CLK_RESET_CCLK_BURST]
335         mov     r0, #0
336         str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
337         mov     pc, lr
338 ENDPROC(tegra_cpu_pllp)
339 #endif
340
341 #if defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
342 /*
343  * tegra_generic_smc
344  *
345  * r0 = smc type
346  * r1 = smc subtype
347  * r2 = argument passed to smc
348  *
349  * issues SMC (secure monitor call) instruction with
350  * the specified parameters.
351  */
352 ENTRY(tegra_generic_smc)
353         mov     r3, #0
354         dsb
355         smc     #0
356 restart:
357         ldr     r3, =0xFFFFFFFD
358         cmp     r0, r3
359         bne     done
360         mov     r0, #(60 << 24)
361         dsb
362         smc     #0
363         b       restart
364 done:
365         mov     pc, lr
366 ENDPROC(tegra_generic_smc)
367 #endif