Merge tag 'for-linus-4.12b-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.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 until PLLA has locked.
46  */
47         .macro wait_pllalock
48 1:      ldr     tmp1, [pmc, #AT91_PMC_SR]
49         tst     tmp1, #AT91_PMC_LOCKA
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
101         /* Active the self-refresh mode */
102         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
103         bl      at91_sramc_self_refresh
104
105         ldr     r0, .pm_mode
106         tst     r0, #AT91_PM_SLOW_CLOCK
107         beq     skip_disable_main_clock
108
109         ldr     pmc, .pmc_base
110
111         /* Save Master clock setting */
112         ldr     tmp1, [pmc, #AT91_PMC_MCKR]
113         str     tmp1, .saved_mckr
114
115         /*
116          * Set the Master clock source to slow clock
117          */
118         bic     tmp1, tmp1, #AT91_PMC_CSS
119         str     tmp1, [pmc, #AT91_PMC_MCKR]
120
121         wait_mckrdy
122
123         /* Save PLLA setting and disable it */
124         ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
125         str     tmp1, .saved_pllar
126
127         mov     tmp1, #AT91_PMC_PLLCOUNT
128         orr     tmp1, tmp1, #(1 << 29)          /* bit 29 always set */
129         str     tmp1, [pmc, #AT91_CKGR_PLLAR]
130
131         /* Turn off the main oscillator */
132         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
133         bic     tmp1, tmp1, #AT91_PMC_MOSCEN
134         orr     tmp1, tmp1, #AT91_PMC_KEY
135         str     tmp1, [pmc, #AT91_CKGR_MOR]
136
137 skip_disable_main_clock:
138         ldr     pmc, .pmc_base
139
140         /* Wait for interrupt */
141         at91_cpu_idle
142
143         ldr     r0, .pm_mode
144         tst     r0, #AT91_PM_SLOW_CLOCK
145         beq     skip_enable_main_clock
146
147         ldr     pmc, .pmc_base
148
149         /* Turn on the main oscillator */
150         ldr     tmp1, [pmc, #AT91_CKGR_MOR]
151         orr     tmp1, tmp1, #AT91_PMC_MOSCEN
152         orr     tmp1, tmp1, #AT91_PMC_KEY
153         str     tmp1, [pmc, #AT91_CKGR_MOR]
154
155         wait_moscrdy
156
157         /* Restore PLLA setting */
158         ldr     tmp1, .saved_pllar
159         str     tmp1, [pmc, #AT91_CKGR_PLLAR]
160
161         tst     tmp1, #(AT91_PMC_MUL &  0xff0000)
162         bne     3f
163         tst     tmp1, #(AT91_PMC_MUL & ~0xff0000)
164         beq     4f
165 3:
166         wait_pllalock
167 4:
168
169         /*
170          * Restore master clock setting
171          */
172         ldr     tmp1, .saved_mckr
173         str     tmp1, [pmc, #AT91_PMC_MCKR]
174
175         wait_mckrdy
176
177 skip_enable_main_clock:
178         /* Exit the self-refresh mode */
179         mov     r0, #SRAMC_SELF_FRESH_EXIT
180         bl      at91_sramc_self_refresh
181
182         /* Restore registers, and return */
183         ldmfd   sp!, {r4 - r12, pc}
184 ENDPROC(at91_pm_suspend_in_sram)
185
186 /*
187  * void at91_sramc_self_refresh(unsigned int is_active)
188  *
189  * @input param:
190  *      @r0: 1 - active self-refresh mode
191  *           0 - exit self-refresh mode
192  * register usage:
193  *      @r1: memory type
194  *      @r2: base address of the sram controller
195  */
196
197 ENTRY(at91_sramc_self_refresh)
198         ldr     r1, .memtype
199         ldr     r2, .sramc_base
200
201         cmp     r1, #AT91_MEMCTRL_MC
202         bne     ddrc_sf
203
204         /*
205          * at91rm9200 Memory controller
206          */
207
208          /*
209           * For exiting the self-refresh mode, do nothing,
210           * automatically exit the self-refresh mode.
211           */
212         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
213         beq     exit_sramc_sf
214
215         /* Active SDRAM self-refresh mode */
216         mov     r3, #1
217         str     r3, [r2, #AT91_MC_SDRAMC_SRR]
218         b       exit_sramc_sf
219
220 ddrc_sf:
221         cmp     r1, #AT91_MEMCTRL_DDRSDR
222         bne     sdramc_sf
223
224         /*
225          * DDR Memory controller
226          */
227         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
228         beq     ddrc_exit_sf
229
230         /* LPDDR1 --> force DDR2 mode during self-refresh */
231         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
232         str     r3, .saved_sam9_mdr
233         bic     r3, r3, #~AT91_DDRSDRC_MD
234         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
235         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
236         biceq   r3, r3, #AT91_DDRSDRC_MD
237         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
238         streq   r3, [r2, #AT91_DDRSDRC_MDR]
239
240         /* Active DDRC self-refresh mode */
241         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
242         str     r3, .saved_sam9_lpr
243         bic     r3, r3, #AT91_DDRSDRC_LPCB
244         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
245         str     r3, [r2, #AT91_DDRSDRC_LPR]
246
247         /* If using the 2nd ddr controller */
248         ldr     r2, .sramc1_base
249         cmp     r2, #0
250         beq     no_2nd_ddrc
251
252         ldr     r3, [r2, #AT91_DDRSDRC_MDR]
253         str     r3, .saved_sam9_mdr1
254         bic     r3, r3, #~AT91_DDRSDRC_MD
255         cmp     r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
256         ldreq   r3, [r2, #AT91_DDRSDRC_MDR]
257         biceq   r3, r3, #AT91_DDRSDRC_MD
258         orreq   r3, r3, #AT91_DDRSDRC_MD_DDR2
259         streq   r3, [r2, #AT91_DDRSDRC_MDR]
260
261         /* Active DDRC self-refresh mode */
262         ldr     r3, [r2, #AT91_DDRSDRC_LPR]
263         str     r3, .saved_sam9_lpr1
264         bic     r3, r3, #AT91_DDRSDRC_LPCB
265         orr     r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
266         str     r3, [r2, #AT91_DDRSDRC_LPR]
267
268 no_2nd_ddrc:
269         b       exit_sramc_sf
270
271 ddrc_exit_sf:
272         /* Restore MDR in case of LPDDR1 */
273         ldr     r3, .saved_sam9_mdr
274         str     r3, [r2, #AT91_DDRSDRC_MDR]
275         /* Restore LPR on AT91 with DDRAM */
276         ldr     r3, .saved_sam9_lpr
277         str     r3, [r2, #AT91_DDRSDRC_LPR]
278
279         /* If using the 2nd ddr controller */
280         ldr     r2, .sramc1_base
281         cmp     r2, #0
282         ldrne   r3, .saved_sam9_mdr1
283         strne   r3, [r2, #AT91_DDRSDRC_MDR]
284         ldrne   r3, .saved_sam9_lpr1
285         strne   r3, [r2, #AT91_DDRSDRC_LPR]
286
287         b       exit_sramc_sf
288
289         /*
290          * SDRAMC Memory controller
291          */
292 sdramc_sf:
293         tst     r0, #SRAMC_SELF_FRESH_ACTIVE
294         beq     sdramc_exit_sf
295
296         /* Active SDRAMC self-refresh mode */
297         ldr     r3, [r2, #AT91_SDRAMC_LPR]
298         str     r3, .saved_sam9_lpr
299         bic     r3, r3, #AT91_SDRAMC_LPCB
300         orr     r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
301         str     r3, [r2, #AT91_SDRAMC_LPR]
302
303 sdramc_exit_sf:
304         ldr     r3, .saved_sam9_lpr
305         str     r3, [r2, #AT91_SDRAMC_LPR]
306
307 exit_sramc_sf:
308         mov     pc, lr
309 ENDPROC(at91_sramc_self_refresh)
310
311 .pmc_base:
312         .word 0
313 .sramc_base:
314         .word 0
315 .sramc1_base:
316         .word 0
317 .memtype:
318         .word 0
319 .pm_mode:
320         .word 0
321 .saved_mckr:
322         .word 0
323 .saved_pllar:
324         .word 0
325 .saved_sam9_lpr:
326         .word 0
327 .saved_sam9_lpr1:
328         .word 0
329 .saved_sam9_mdr:
330         .word 0
331 .saved_sam9_mdr1:
332         .word 0
333
334 ENTRY(at91_pm_suspend_in_sram_sz)
335         .word .-at91_pm_suspend_in_sram