Merge tag 'usb-serial-5.15-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / arm / mach-tegra / sleep-tegra20.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
4  * Copyright (c) 2011, Google, Inc.
5  *
6  * Author: Colin Cross <ccross@android.com>
7  *         Gary King <gking@nvidia.com>
8  */
9
10 #include <linux/linkage.h>
11
12 #include <soc/tegra/flowctrl.h>
13
14 #include <asm/assembler.h>
15 #include <asm/proc-fns.h>
16 #include <asm/cp15.h>
17 #include <asm/cache.h>
18
19 #include "irammap.h"
20 #include "reset.h"
21 #include "sleep.h"
22
23 #define EMC_CFG                         0xc
24 #define EMC_ADR_CFG                     0x10
25 #define EMC_NOP                         0xdc
26 #define EMC_SELF_REF                    0xe0
27 #define EMC_REQ_CTRL                    0x2b0
28 #define EMC_EMC_STATUS                  0x2b4
29
30 #define CLK_RESET_CCLK_BURST            0x20
31 #define CLK_RESET_CCLK_DIVIDER          0x24
32 #define CLK_RESET_SCLK_BURST            0x28
33 #define CLK_RESET_SCLK_DIVIDER          0x2c
34 #define CLK_RESET_PLLC_BASE             0x80
35 #define CLK_RESET_PLLM_BASE             0x90
36 #define CLK_RESET_PLLP_BASE             0xa0
37
38 #define APB_MISC_XM2CFGCPADCTRL         0x8c8
39 #define APB_MISC_XM2CFGDPADCTRL         0x8cc
40 #define APB_MISC_XM2CLKCFGPADCTRL       0x8d0
41 #define APB_MISC_XM2COMPPADCTRL         0x8d4
42 #define APB_MISC_XM2VTTGENPADCTRL       0x8d8
43 #define APB_MISC_XM2CFGCPADCTRL2        0x8e4
44 #define APB_MISC_XM2CFGDPADCTRL2        0x8e8
45
46 #define PLLC_STORE_MASK                 (1 << 0)
47 #define PLLM_STORE_MASK                 (1 << 1)
48 #define PLLP_STORE_MASK                 (1 << 2)
49
50 .macro test_pll_state, rd, test_mask
51         ldr     \rd, tegra_pll_state
52         tst     \rd, #\test_mask
53 .endm
54
55 .macro store_pll_state, rd, tmp, r_car_base, pll_base, pll_mask
56         ldr     \rd, [\r_car_base, #\pll_base]
57         tst     \rd, #(1 << 30)
58         ldr     \rd, tegra_pll_state
59         biceq   \rd, \rd, #\pll_mask
60         orrne   \rd, \rd, #\pll_mask
61         adr     \tmp, tegra_pll_state
62         str     \rd, [\tmp]
63 .endm
64
65 .macro pll_enable, rd, r_car_base, pll_base, test_mask
66         test_pll_state \rd, \test_mask
67         beq     1f
68
69         ldr     \rd, [\r_car_base, #\pll_base]
70         tst     \rd, #(1 << 30)
71         orreq   \rd, \rd, #(1 << 30)
72         streq   \rd, [\r_car_base, #\pll_base]
73 1:
74 .endm
75
76 .macro emc_device_mask, rd, base
77         ldr     \rd, [\base, #EMC_ADR_CFG]
78         tst     \rd, #(0x3 << 24)
79         moveq   \rd, #(0x1 << 8)                @ just 1 device
80         movne   \rd, #(0x3 << 8)                @ 2 devices
81 .endm
82
83 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
84 /*
85  * tegra20_hotplug_shutdown(void)
86  *
87  * puts the current cpu in reset
88  * should never return
89  */
90 ENTRY(tegra20_hotplug_shutdown)
91         /* Put this CPU down */
92         cpu_id  r0
93         bl      tegra20_cpu_shutdown
94         ret     lr                      @ should never get here
95 ENDPROC(tegra20_hotplug_shutdown)
96
97 /*
98  * tegra20_cpu_shutdown(int cpu)
99  *
100  * r0 is cpu to reset
101  *
102  * puts the specified CPU in wait-for-event mode on the flow controller
103  * and puts the CPU in reset
104  * can be called on the current cpu or another cpu
105  * if called on the current cpu, does not return
106  * MUST NOT BE CALLED FOR CPU 0.
107  *
108  * corrupts r0-r3, r12
109  */
110 ENTRY(tegra20_cpu_shutdown)
111         cmp     r0, #0
112         reteq   lr                      @ must not be called for CPU 0
113
114         cpu_to_halt_reg r1, r0
115         ldr     r3, =TEGRA_FLOW_CTRL_VIRT
116         mov     r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
117         str     r2, [r3, r1]            @ put flow controller in wait event mode
118         ldr     r2, [r3, r1]
119         isb
120         dsb
121         movw    r1, 0x1011
122         mov     r1, r1, lsl r0
123         ldr     r3, =TEGRA_CLK_RESET_VIRT
124         str     r1, [r3, #0x340]        @ put slave CPU in reset
125         isb
126         dsb
127         cpu_id  r3
128         cmp     r3, r0
129         beq     .
130         ret     lr
131 ENDPROC(tegra20_cpu_shutdown)
132 #endif
133
134 #ifdef CONFIG_PM_SLEEP
135 /*
136  * tegra20_sleep_core_finish(unsigned long v2p)
137  *
138  * Enters suspend in LP0 or LP1 by turning off the mmu and jumping to
139  * tegra20_tear_down_core in IRAM
140  */
141 ENTRY(tegra20_sleep_core_finish)
142         mov     r4, r0
143         /* Flush, disable the L1 data cache and exit SMP */
144         mov     r0, #TEGRA_FLUSH_CACHE_ALL
145         bl      tegra_disable_clean_inv_dcache
146         mov     r0, r4
147
148         mov32   r3, tegra_shut_off_mmu
149         add     r3, r3, r0
150
151         mov32   r0, tegra20_tear_down_core
152         mov32   r1, tegra20_iram_start
153         sub     r0, r0, r1
154         mov32   r1, TEGRA_IRAM_LPx_RESUME_AREA
155         add     r0, r0, r1
156
157         ret     r3
158 ENDPROC(tegra20_sleep_core_finish)
159
160 /*
161  * tegra20_tear_down_cpu
162  *
163  * Switches the CPU cluster to PLL-P and enters sleep.
164  */
165 ENTRY(tegra20_tear_down_cpu)
166         bl      tegra_switch_cpu_to_pllp
167         b       tegra20_enter_sleep
168 ENDPROC(tegra20_tear_down_cpu)
169
170 /* START OF ROUTINES COPIED TO IRAM */
171         .align L1_CACHE_SHIFT
172         .globl tegra20_iram_start
173 tegra20_iram_start:
174
175 /*
176  * tegra20_lp1_reset
177  *
178  * reset vector for LP1 restore; copied into IRAM during suspend.
179  * Brings the system back up to a safe staring point (SDRAM out of
180  * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
181  * system clock running on the same PLL that it suspended at), and
182  * jumps to tegra_resume to restore virtual addressing and PLLX.
183  * The physical address of tegra_resume expected to be stored in
184  * PMC_SCRATCH41.
185  *
186  * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
187  */
188 ENTRY(tegra20_lp1_reset)
189         /*
190          * The CPU and system bus are running at 32KHz and executing from
191          * IRAM when this code is executed; immediately switch to CLKM and
192          * enable PLLM, PLLP, PLLC.
193          */
194         mov32   r0, TEGRA_CLK_RESET_BASE
195
196         mov     r1, #(1 << 28)
197         str     r1, [r0, #CLK_RESET_SCLK_BURST]
198         str     r1, [r0, #CLK_RESET_CCLK_BURST]
199         mov     r1, #0
200         str     r1, [r0, #CLK_RESET_CCLK_DIVIDER]
201         str     r1, [r0, #CLK_RESET_SCLK_DIVIDER]
202
203         pll_enable r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
204         pll_enable r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
205         pll_enable r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
206
207         adr     r2, tegra20_sdram_pad_address
208         adr     r4, tegra20_sdram_pad_save
209         mov     r5, #0
210
211         ldr     r6, tegra20_sdram_pad_size
212 padload:
213         ldr     r7, [r2, r5]            @ r7 is the addr in the pad_address
214
215         ldr     r1, [r4, r5]
216         str     r1, [r7]                @ restore the value in pad_save
217
218         add     r5, r5, #4
219         cmp     r6, r5
220         bne     padload
221
222 padload_done:
223         /* 255uS delay for PLL stabilization */
224         mov32   r7, TEGRA_TMRUS_BASE
225         ldr     r1, [r7]
226         add     r1, r1, #0xff
227         wait_until r1, r7, r9
228
229         adr     r4, tegra20_sclk_save
230         ldr     r4, [r4]
231         str     r4, [r0, #CLK_RESET_SCLK_BURST]
232         mov32   r4, ((1 << 28) | (4))   @ burst policy is PLLP
233         str     r4, [r0, #CLK_RESET_CCLK_BURST]
234
235         mov32   r0, TEGRA_EMC_BASE
236         ldr     r1, [r0, #EMC_CFG]
237         bic     r1, r1, #(1 << 31)      @ disable DRAM_CLK_STOP
238         str     r1, [r0, #EMC_CFG]
239
240         mov     r1, #0
241         str     r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
242         mov     r1, #1
243         str     r1, [r0, #EMC_NOP]
244         str     r1, [r0, #EMC_NOP]
245
246         emc_device_mask r1, r0
247
248 exit_selfrefresh_loop:
249         ldr     r2, [r0, #EMC_EMC_STATUS]
250         ands    r2, r2, r1
251         bne     exit_selfrefresh_loop
252
253         mov     r1, #0                  @ unstall all transactions
254         str     r1, [r0, #EMC_REQ_CTRL]
255
256         mov32   r0, TEGRA_PMC_BASE
257         ldr     r0, [r0, #PMC_SCRATCH41]
258         ret     r0                      @ jump to tegra_resume
259 ENDPROC(tegra20_lp1_reset)
260
261 /*
262  * tegra20_tear_down_core
263  *
264  * copied into and executed from IRAM
265  * puts memory in self-refresh for LP0 and LP1
266  */
267 tegra20_tear_down_core:
268         bl      tegra20_sdram_self_refresh
269         bl      tegra20_switch_cpu_to_clk32k
270         b       tegra20_enter_sleep
271
272 /*
273  * tegra20_switch_cpu_to_clk32k
274  *
275  * In LP0 and LP1 all PLLs will be turned off. Switch the CPU and system clock
276  * to the 32KHz clock.
277  */
278 tegra20_switch_cpu_to_clk32k:
279         /*
280          * start by switching to CLKM to safely disable PLLs, then switch to
281          * CLKS.
282          */
283         mov     r0, #(1 << 28)
284         str     r0, [r5, #CLK_RESET_SCLK_BURST]
285         str     r0, [r5, #CLK_RESET_CCLK_BURST]
286         mov     r0, #0
287         str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
288         str     r0, [r5, #CLK_RESET_SCLK_DIVIDER]
289
290         /* 2uS delay delay between changing SCLK and disabling PLLs */
291         mov32   r7, TEGRA_TMRUS_BASE
292         ldr     r1, [r7]
293         add     r1, r1, #2
294         wait_until r1, r7, r9
295
296         store_pll_state r0, r1, r5, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
297         store_pll_state r0, r1, r5, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
298         store_pll_state r0, r1, r5, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
299
300         /* disable PLLM, PLLP and PLLC */
301         ldr     r0, [r5, #CLK_RESET_PLLM_BASE]
302         bic     r0, r0, #(1 << 30)
303         str     r0, [r5, #CLK_RESET_PLLM_BASE]
304         ldr     r0, [r5, #CLK_RESET_PLLP_BASE]
305         bic     r0, r0, #(1 << 30)
306         str     r0, [r5, #CLK_RESET_PLLP_BASE]
307         ldr     r0, [r5, #CLK_RESET_PLLC_BASE]
308         bic     r0, r0, #(1 << 30)
309         str     r0, [r5, #CLK_RESET_PLLC_BASE]
310
311         /* switch to CLKS */
312         mov     r0, #0  /* brust policy = 32KHz */
313         str     r0, [r5, #CLK_RESET_SCLK_BURST]
314
315         ret     lr
316
317 /*
318  * tegra20_enter_sleep
319  *
320  * uses flow controller to enter sleep state
321  * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
322  * executes from SDRAM with target state is LP2
323  */
324 tegra20_enter_sleep:
325         mov32   r6, TEGRA_FLOW_CTRL_BASE
326
327         mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
328         orr     r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
329         cpu_id  r1
330         cpu_to_halt_reg r1, r1
331         str     r0, [r6, r1]
332         dsb
333         ldr     r0, [r6, r1] /* memory barrier */
334
335 halted:
336         dsb
337         wfe     /* CPU should be power gated here */
338         isb
339         b       halted
340
341 /*
342  * tegra20_sdram_self_refresh
343  *
344  * called with MMU off and caches disabled
345  * puts sdram in self refresh
346  * must be executed from IRAM
347  */
348 tegra20_sdram_self_refresh:
349         mov32   r1, TEGRA_EMC_BASE      @ r1 reserved for emc base addr
350
351         mov     r2, #3
352         str     r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests
353
354 emcidle:
355         ldr     r2, [r1, #EMC_EMC_STATUS]
356         tst     r2, #4
357         beq     emcidle
358
359         mov     r2, #1
360         str     r2, [r1, #EMC_SELF_REF]
361
362         emc_device_mask r2, r1
363
364 emcself:
365         ldr     r3, [r1, #EMC_EMC_STATUS]
366         and     r3, r3, r2
367         cmp     r3, r2
368         bne     emcself                 @ loop until DDR in self-refresh
369
370         adr     r2, tegra20_sdram_pad_address
371         adr     r3, tegra20_sdram_pad_safe
372         adr     r4, tegra20_sdram_pad_save
373         mov     r5, #0
374
375         ldr     r6, tegra20_sdram_pad_size
376 padsave:
377         ldr     r0, [r2, r5]            @ r0 is the addr in the pad_address
378
379         ldr     r1, [r0]
380         str     r1, [r4, r5]            @ save the content of the addr
381
382         ldr     r1, [r3, r5]
383         str     r1, [r0]                @ set the save val to the addr
384
385         add     r5, r5, #4
386         cmp     r6, r5
387         bne     padsave
388 padsave_done:
389
390         mov32   r5, TEGRA_CLK_RESET_BASE
391         ldr     r0, [r5, #CLK_RESET_SCLK_BURST]
392         adr     r2, tegra20_sclk_save
393         str     r0, [r2]
394         dsb
395         ret     lr
396
397 tegra20_sdram_pad_address:
398         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL
399         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL
400         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2CLKCFGPADCTRL
401         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2COMPPADCTRL
402         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2VTTGENPADCTRL
403         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL2
404         .word   TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL2
405
406 tegra20_sdram_pad_size:
407         .word   tegra20_sdram_pad_size - tegra20_sdram_pad_address
408
409 tegra20_sdram_pad_safe:
410         .word   0x8
411         .word   0x8
412         .word   0x0
413         .word   0x8
414         .word   0x5500
415         .word   0x08080040
416         .word   0x0
417
418 tegra20_sclk_save:
419         .word   0x0
420
421 tegra20_sdram_pad_save:
422         .rept (tegra20_sdram_pad_size - tegra20_sdram_pad_address) / 4
423         .long   0
424         .endr
425
426 tegra_pll_state:
427         .word   0x0
428
429         .ltorg
430 /* dummy symbol for end of IRAM */
431         .align L1_CACHE_SHIFT
432         .globl tegra20_iram_end
433 tegra20_iram_end:
434         b       .
435 #endif