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