]> asedeno.scripts.mit.edu Git - linux.git/blob - arch/arm/mach-at91/pm_suspend.S
Merge tag 'trace-v5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux.git] / arch / arm / mach-at91 / pm_suspend.S
1 /*
2  * arch/arm/mach-at91/pm_slow_clock.S
3  *
4  *  Copyright (C) 2006 Savin Zlobec
5  *
6  * AT91SAM9 support:
7  *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  */
14 #include <linux/linkage.h>
15 #include <linux/clk/at91_pmc.h>
16 #include "pm.h"
17 #include "generated/at91_pm_data-offsets.h"
18
19 #define SRAMC_SELF_FRESH_ACTIVE         0x01
20 #define SRAMC_SELF_FRESH_EXIT           0x00
21
22 pmc     .req    r0
23 tmp1    .req    r4
24 tmp2    .req    r5
25
26 /*
27  * Wait until master clock is ready (after switching master clock source)
28  */
29         .macro wait_mckrdy
30 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
31         tst     tmp1, #AT91_PMC_MCKRDY
32         beq     1b
33         .endm
34
35 /*
36  * Wait until master oscillator has stabilized.
37  */
38         .macro wait_moscrdy
39 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
40         tst     tmp1, #AT91_PMC_MOSCS
41         beq     1b
42         .endm
43
44 /*
45  * Wait for main oscillator selection is done
46  */
47         .macro wait_moscsels
48 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
49         tst     tmp1, #AT91_PMC_MOSCSELS
50         beq     1b
51         .endm
52
53 /*
54  * Put the processor to enter the idle state
55  */
56         .macro at91_cpu_idle
57
58 #if defined(CONFIG_CPU_V7)
59         mov     tmp1, #AT91_PMC_PCK
60         str     tmp1, [pmc, #AT91_PMC_SCDR]
61
62         dsb
63
64         wfi             @ Wait For Interrupt
65 #else
66         mcr     p15, 0, tmp1, c7, c0, 4
67 #endif
68
69         .endm
70
71         .text
72
73         .arm
74
75 /*
76  * void at91_suspend_sram_fn(struct at91_pm_data*)
77  * @input param:
78  *      @r0: base address of struct at91_pm_data
79  */
80 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
81         .align 3
82 ENTRY(at91_pm_suspend_in_sram)
83         /* Save registers on stack */
84         stmfd   sp!, {r4 - r12, lr}
85
86         /* Drain write buffer */
87         mov     tmp1, #0
88         mcr     p15, 0, tmp1, c7, c10, 4
89
90         ldr     tmp1, [r0, #PM_DATA_PMC]
91         str     tmp1, .pmc_base
92         ldr     tmp1, [r0, #PM_DATA_RAMC0]
93         str     tmp1, .sramc_base
94         ldr     tmp1, [r0, #PM_DATA_RAMC1]
95         str     tmp1, .sramc1_base
96         ldr     tmp1, [r0, #PM_DATA_MEMCTRL]
97         str     tmp1, .memtype
98         ldr     tmp1, [r0, #PM_DATA_MODE]
99         str     tmp1, .pm_mode
100         /* Both ldrne below are here to preload their address in the TLB */
101         ldr     tmp1, [r0, #PM_DATA_SHDWC]
102         str     tmp1, .shdwc
103         cmp     tmp1, #0
104         ldrne   tmp2, [tmp1, #0]
105         ldr     tmp1, [r0, #PM_DATA_SFRBU]
106         str     tmp1, .sfr
107         cmp     tmp1, #0
108         ldrne   tmp2, [tmp1, #0x10]
109
110         /* Active the self-refresh mode */
111         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
112         bl      at91_sramc_self_refresh
113
114         ldr     r0, .pm_mode
115         cmp     r0, #AT91_PM_STANDBY
116         beq     standby
117         cmp     r0, #AT91_PM_BACKUP
118         beq     backup_mode
119
120         bl      at91_ulp_mode
121         b       exit_suspend
122
123 standby:
124         /* Wait for interrupt */
125         ldr     pmc, .pmc_base
126         at91_cpu_idle
127         b       exit_suspend
128
129 backup_mode:
130         bl      at91_backup_mode
131         b       exit_suspend
132
133 exit_suspend:
134         /* Exit the self-refresh mode */
135         mov     r0, #SRAMC_SELF_FRESH_EXIT
136         bl      at91_sramc_self_refresh
137
138         /* Restore registers, and return */
139         ldmfd   sp!, {r4 - r12, pc}
140 ENDPROC(at91_pm_suspend_in_sram)
141
142 ENTRY(at91_backup_mode)
143         /* Switch the master clock source to slow clock. */
144         ldr     pmc, .pmc_base
145         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
146         bic     tmp1, tmp1, #AT91_PMC_CSS
147         str     tmp1, [pmc, #AT91_PMC_MCKR]
148
149         wait_mckrdy
150
151         /*BUMEN*/
152         ldr     r0, .sfr
153         mov     tmp1, #0x1
154         str     tmp1, [r0, #0x10]
155
156         /* Shutdown */
157         ldr     r0, .shdwc
158         mov     tmp1, #0xA5000000
159         add     tmp1, tmp1, #0x1
160         str     tmp1, [r0, #0]
161 ENDPROC(at91_backup_mode)
162
163 .macro at91_pm_ulp0_mode
164         ldr     pmc, .pmc_base
165
166         /* Turn off the crystal oscillator */
167         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
168         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
169         orr     tmp1, tmp1, #AT91_PMC_KEY
170         str     tmp1, [pmc, #AT91_CKGR_MOR]
171
172         /* Save RC oscillator state */
173         ldr     tmp1, [pmc, #AT91_PMC_SR]
174         str     tmp1, .saved_osc_status
175         tst     tmp1, #AT91_PMC_MOSCRCS
176         bne     1f
177
178         /* Turn off RC oscillator */
179         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
180         bic     tmp1, tmp1, #AT91_PMC_MOSCRCEN
181         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
182         orr     tmp1, tmp1, #AT91_PMC_KEY
183         str     tmp1, [pmc, #AT91_CKGR_MOR]
184
185         /* Wait main RC disabled done */
186 2:      ldr     tmp1, [pmc, #AT91_PMC_SR]
187         tst     tmp1, #AT91_PMC_MOSCRCS
188         bne     2b
189
190         /* Wait for interrupt */
191 1:      at91_cpu_idle
192
193         /* Restore RC oscillator state */
194         ldr     tmp1, .saved_osc_status
195         tst     tmp1, #AT91_PMC_MOSCRCS
196         beq     4f
197
198         /* Turn on RC oscillator */
199         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
200         orr     tmp1, tmp1, #AT91_PMC_MOSCRCEN
201         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
202         orr     tmp1, tmp1, #AT91_PMC_KEY
203         str     tmp1, [pmc, #AT91_CKGR_MOR]
204
205         /* Wait main RC stabilization */
206 3:      ldr     tmp1, [pmc, #AT91_PMC_SR]
207         tst     tmp1, #AT91_PMC_MOSCRCS
208         beq     3b
209
210         /* Turn on the crystal oscillator */
211 4:      ldr     tmp1, [pmc, #AT91_CKGR_MOR]
212         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
213         orr     tmp1, tmp1, #AT91_PMC_KEY
214         str     tmp1, [pmc, #AT91_CKGR_MOR]
215
216         wait_moscrdy
217 .endm
218
219 /**
220  * Note: This procedure only applies on the platform which uses
221  * the external crystal oscillator as a main clock source.
222  */
223 .macro at91_pm_ulp1_mode
224         ldr     pmc, .pmc_base
225
226         /* Save RC oscillator state and check if it is enabled. */
227         ldr     tmp1, [pmc, #AT91_PMC_SR]
228         str     tmp1, .saved_osc_status
229         tst     tmp1, #AT91_PMC_MOSCRCS
230         bne     2f
231
232         /* Enable RC oscillator */
233         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
234         orr     tmp1, tmp1, #AT91_PMC_MOSCRCEN
235         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
236         orr     tmp1, tmp1, #AT91_PMC_KEY
237         str     tmp1, [pmc, #AT91_CKGR_MOR]
238
239         /* Wait main RC stabilization */
240 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
241         tst     tmp1, #AT91_PMC_MOSCRCS
242         beq     1b
243
244         /* Switch the main clock source to 12-MHz RC oscillator */
245 2:      ldr     tmp1, [pmc, #AT91_CKGR_MOR]
246         bic     tmp1, tmp1, #AT91_PMC_MOSCSEL
247         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
248         orr     tmp1, tmp1, #AT91_PMC_KEY
249         str     tmp1, [pmc, #AT91_CKGR_MOR]
250
251         wait_moscsels
252
253         /* Disable the crystal oscillator */
254         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
255         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
256         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
257         orr     tmp1, tmp1, #AT91_PMC_KEY
258         str     tmp1, [pmc, #AT91_CKGR_MOR]
259
260         /* Switch the master clock source to main clock */
261         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
262         bic     tmp1, tmp1, #AT91_PMC_CSS
263         orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
264         str     tmp1, [pmc, #AT91_PMC_MCKR]
265
266         wait_mckrdy
267
268         /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
269         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
270         orr     tmp1, tmp1, #AT91_PMC_WAITMODE
271         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
272         orr     tmp1, tmp1, #AT91_PMC_KEY
273         str     tmp1, [pmc, #AT91_CKGR_MOR]
274
275         wait_mckrdy
276
277         /* Enable the crystal oscillator */
278         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
279         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
280         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
281         orr     tmp1, tmp1, #AT91_PMC_KEY
282         str     tmp1, [pmc, #AT91_CKGR_MOR]
283
284         wait_moscrdy
285
286         /* Switch the master clock source to slow clock */
287         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
288         bic     tmp1, tmp1, #AT91_PMC_CSS
289         str     tmp1, [pmc, #AT91_PMC_MCKR]
290
291         wait_mckrdy
292
293         /* Switch main clock source to crystal oscillator */
294         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
295         orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
296         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
297         orr     tmp1, tmp1, #AT91_PMC_KEY
298         str     tmp1, [pmc, #AT91_CKGR_MOR]
299
300         wait_moscsels
301
302         /* Switch the master clock source to main clock */
303         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
304         bic     tmp1, tmp1, #AT91_PMC_CSS
305         orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
306         str     tmp1, [pmc, #AT91_PMC_MCKR]
307
308         wait_mckrdy
309
310         /* Restore RC oscillator state */
311         ldr     tmp1, .saved_osc_status
312         tst     tmp1, #AT91_PMC_MOSCRCS
313         bne     3f
314
315         /* Disable RC oscillator */
316         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
317         bic     tmp1, tmp1, #AT91_PMC_MOSCRCEN
318         bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
319         orr     tmp1, tmp1, #AT91_PMC_KEY
320         str     tmp1, [pmc, #AT91_CKGR_MOR]
321
322         /* Wait RC oscillator disable done */
323 4:      ldr     tmp1, [pmc, #AT91_PMC_SR]
324         tst     tmp1, #AT91_PMC_MOSCRCS
325         bne     4b
326
327 3:
328 .endm
329
330 ENTRY(at91_ulp_mode)
331         ldr     pmc, .pmc_base
332
333         /* Save Master clock setting */
334         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
335         str     tmp1, .saved_mckr
336
337         /*
338          * Set the Master clock source to slow clock
339          */
340         bic     tmp1, tmp1, #AT91_PMC_CSS
341         str     tmp1, [pmc, #AT91_PMC_MCKR]
342
343         wait_mckrdy
344
345         ldr     r0, .pm_mode
346         cmp     r0, #AT91_PM_ULP1
347         beq     ulp1_mode
348
349         at91_pm_ulp0_mode
350         b       ulp_exit
351
352 ulp1_mode:
353         at91_pm_ulp1_mode
354         b       ulp_exit
355
356 ulp_exit:
357         ldr     pmc, .pmc_base
358
359         /*
360          * Restore master clock setting
361          */
362         ldr     tmp1, .saved_mckr
363         str     tmp1, [pmc, #AT91_PMC_MCKR]
364
365         wait_mckrdy
366
367         mov     pc, lr
368 ENDPROC(at91_ulp_mode)
369
370 /*
371  * void at91_sramc_self_refresh(unsigned int is_active)
372  *
373  * @input param:
374  *      @r0: 1 - active self-refresh mode
375  *           0 - exit self-refresh mode
376  * register usage:
377  *      @r1: memory type
378  *      @r2: base address of the sram controller
379  */
380
381 ENTRY(at91_sramc_self_refresh)
382         ldr     r1, .memtype
383         ldr     r2, .sramc_base
384
385         cmp     r1, #AT91_MEMCTRL_MC
386         bne     ddrc_sf
387
388         /*
389          * at91rm9200 Memory controller
390          */
391
392          /*
393           * For exiting the self-refresh mode, do nothing,
394           * automatically exit the self-refresh mode.
395           */
396         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
397         beq     exit_sramc_sf
398
399         /* Active SDRAM self-refresh mode */
400         mov     r3, #1
401         str     r3, [r2, #AT91_MC_SDRAMC_SRR]
402         b       exit_sramc_sf
403
404 ddrc_sf:
405         cmp     r1, #AT91_MEMCTRL_DDRSDR
406         bne     sdramc_sf
407
408         /*
409          * DDR Memory controller
410          */
411         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
412         beq     ddrc_exit_sf
413
414         /* LPDDR1 --> force DDR2 mode during self-refresh */
415         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
416         str     r3, .saved_sam9_mdr
417         bic     r3, r3, #~AT91_DDRSDRC_MD
418         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
419         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
420         biceq   r3, r3, #AT91_DDRSDRC_MD
421         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
422         streq   r3, [r2, #AT91_DDRSDRC_MDR]
423
424         /* Active DDRC self-refresh mode */
425         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
426         str     r3, .saved_sam9_lpr
427         bic     r3, r3, #AT91_DDRSDRC_LPCB
428         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
429         str     r3, [r2, #AT91_DDRSDRC_LPR]
430
431         /* If using the 2nd ddr controller */
432         ldr     r2, .sramc1_base
433         cmp     r2, #0
434         beq     no_2nd_ddrc
435
436         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
437         str     r3, .saved_sam9_mdr1
438         bic     r3, r3, #~AT91_DDRSDRC_MD
439         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
440         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
441         biceq   r3, r3, #AT91_DDRSDRC_MD
442         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
443         streq   r3, [r2, #AT91_DDRSDRC_MDR]
444
445         /* Active DDRC self-refresh mode */
446         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
447         str     r3, .saved_sam9_lpr1
448         bic     r3, r3, #AT91_DDRSDRC_LPCB
449         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
450         str     r3, [r2, #AT91_DDRSDRC_LPR]
451
452 no_2nd_ddrc:
453         b       exit_sramc_sf
454
455 ddrc_exit_sf:
456         /* Restore MDR in case of LPDDR1 */
457         ldr     r3, .saved_sam9_mdr
458         str     r3, [r2, #AT91_DDRSDRC_MDR]
459         /* Restore LPR on AT91 with DDRAM */
460         ldr     r3, .saved_sam9_lpr
461         str     r3, [r2, #AT91_DDRSDRC_LPR]
462
463         /* If using the 2nd ddr controller */
464         ldr     r2, .sramc1_base
465         cmp     r2, #0
466         ldrne   r3, .saved_sam9_mdr1
467         strne   r3, [r2, #AT91_DDRSDRC_MDR]
468         ldrne   r3, .saved_sam9_lpr1
469         strne   r3, [r2, #AT91_DDRSDRC_LPR]
470
471         b       exit_sramc_sf
472
473         /*
474          * SDRAMC Memory controller
475          */
476 sdramc_sf:
477         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
478         beq     sdramc_exit_sf
479
480         /* Active SDRAMC self-refresh mode */
481         ldr     r3, [r2, #AT91_SDRAMC_LPR]
482         str     r3, .saved_sam9_lpr
483         bic     r3, r3, #AT91_SDRAMC_LPCB
484         orr     r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
485         str     r3, [r2, #AT91_SDRAMC_LPR]
486
487 sdramc_exit_sf:
488         ldr     r3, .saved_sam9_lpr
489         str     r3, [r2, #AT91_SDRAMC_LPR]
490
491 exit_sramc_sf:
492         mov     pc, lr
493 ENDPROC(at91_sramc_self_refresh)
494
495 .pmc_base:
496         .word 0
497 .sramc_base:
498         .word 0
499 .sramc1_base:
500         .word 0
501 .shdwc:
502         .word 0
503 .sfr:
504         .word 0
505 .memtype:
506         .word 0
507 .pm_mode:
508         .word 0
509 .saved_mckr:
510         .word 0
511 .saved_sam9_lpr:
512         .word 0
513 .saved_sam9_lpr1:
514         .word 0
515 .saved_sam9_mdr:
516         .word 0
517 .saved_sam9_mdr1:
518         .word 0
519 .saved_osc_status:
520         .word 0
521
522 ENTRY(at91_pm_suspend_in_sram_sz)
523         .word .-at91_pm_suspend_in_sram