]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - 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
CommitLineData
eaad2db0
AV
1/*
2 * arch/arm/mach-at91/pm_slow_clock.S
3 *
4 * Copyright (C) 2006 Savin Zlobec
5 *
6 * AT91SAM9 support:
8c9290ae 7 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
eaad2db0
AV
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 */
eaad2db0 14#include <linux/linkage.h>
2edb90ae 15#include <linux/clk/at91_pmc.h>
23be4be5 16#include "pm.h"
65cc1a59 17#include "generated/at91_pm_data-offsets.h"
eaad2db0 18
0ab285c2
WY
19#define SRAMC_SELF_FRESH_ACTIVE 0x01
20#define SRAMC_SELF_FRESH_EXIT 0x00
21
8ff12ad3 22pmc .req r0
fb7e197b
JCPV
23tmp1 .req r4
24tmp2 .req r5
eaad2db0
AV
25
26/*
27 * Wait until master clock is ready (after switching master clock source)
28 */
29 .macro wait_mckrdy
ad4a38d2 301: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 31 tst tmp1, #AT91_PMC_MCKRDY
eaad2db0 32 beq 1b
eaad2db0
AV
33 .endm
34
35/*
36 * Wait until master oscillator has stabilized.
37 */
38 .macro wait_moscrdy
ad4a38d2 391: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 40 tst tmp1, #AT91_PMC_MOSCS
eaad2db0 41 beq 1b
eaad2db0
AV
42 .endm
43
44/*
45 * Wait until PLLA has locked.
46 */
47 .macro wait_pllalock
ad4a38d2 481: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 49 tst tmp1, #AT91_PMC_LOCKA
eaad2db0 50 beq 1b
eaad2db0
AV
51 .endm
52
20567658
WY
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
eaad2db0
AV
71 .text
72
e7b848d7
WY
73 .arm
74
5726a8b9 75/*
65cc1a59 76 * void at91_suspend_sram_fn(struct at91_pm_data*)
5726a8b9 77 * @input param:
65cc1a59 78 * @r0: base address of struct at91_pm_data
fb7e197b 79 */
5fcf8d1a
PD
80/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
81 .align 3
5726a8b9 82ENTRY(at91_pm_suspend_in_sram)
eaad2db0 83 /* Save registers on stack */
fb7e197b 84 stmfd sp!, {r4 - r12, lr}
eaad2db0 85
eaad2db0 86 /* Drain write buffer */
0dcfed14
JCPV
87 mov tmp1, #0
88 mcr p15, 0, tmp1, c7, c10, 4
eaad2db0 89
65cc1a59
AB
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
24a0f5c5
AB
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]
fb7e197b 109
0ab285c2
WY
110 /* Active the self-refresh mode */
111 mov r0, #SRAMC_SELF_FRESH_ACTIVE
112 bl at91_sramc_self_refresh
fb7e197b 113
23be4be5 114 ldr r0, .pm_mode
24a0f5c5
AB
115 cmp r0, #AT91_PM_SLOW_CLOCK
116 beq slow_clock
117 cmp r0, #AT91_PM_BACKUP
118 beq backup_mode
23be4be5 119
24a0f5c5
AB
120 /* Wait for interrupt */
121 ldr pmc, .pmc_base
122 at91_cpu_idle
123 b exit_suspend
124
125slow_clock:
126 bl at91_slowck_mode
127 b exit_suspend
128backup_mode:
129 bl at91_backup_mode
130 b exit_suspend
131
132exit_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}
139ENDPROC(at91_pm_suspend_in_sram)
140
141ENTRY(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]
152ENDPROC(at91_backup_mode)
153
154ENTRY(at91_slowck_mode)
0ab285c2 155 ldr pmc, .pmc_base
eaad2db0 156
eaad2db0 157 /* Save Master clock setting */
b5514952 158 ldr tmp1, [pmc, #AT91_PMC_MCKR]
0dcfed14 159 str tmp1, .saved_mckr
eaad2db0
AV
160
161 /*
162 * Set the Master clock source to slow clock
163 */
0dcfed14 164 bic tmp1, tmp1, #AT91_PMC_CSS
b5514952 165 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
166
167 wait_mckrdy
168
eaad2db0 169 /* Save PLLA setting and disable it */
b5514952 170 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
0dcfed14 171 str tmp1, .saved_pllar
eaad2db0 172
0dcfed14
JCPV
173 mov tmp1, #AT91_PMC_PLLCOUNT
174 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
b5514952 175 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 176
eaad2db0 177 /* Turn off the main oscillator */
b5514952 178 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 179 bic tmp1, tmp1, #AT91_PMC_MOSCEN
5957457a 180 orr tmp1, tmp1, #AT91_PMC_KEY
b5514952 181 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
182
183 /* Wait for interrupt */
20567658 184 at91_cpu_idle
eaad2db0
AV
185
186 /* Turn on the main oscillator */
b5514952 187 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 188 orr tmp1, tmp1, #AT91_PMC_MOSCEN
5957457a 189 orr tmp1, tmp1, #AT91_PMC_KEY
b5514952 190 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
191
192 wait_moscrdy
193
eaad2db0 194 /* Restore PLLA setting */
0dcfed14 195 ldr tmp1, .saved_pllar
b5514952 196 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 197
0dcfed14 198 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 199 bne 3f
0dcfed14 200 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
201 beq 4f
2023:
eaad2db0 203 wait_pllalock
9823f1a8 2044:
eaad2db0 205
eaad2db0
AV
206 /*
207 * Restore master clock setting
208 */
0ab285c2 209 ldr tmp1, .saved_mckr
b5514952 210 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
211
212 wait_mckrdy
213
24a0f5c5
AB
214 mov pc, lr
215ENDPROC(at91_slowck_mode)
0ab285c2
WY
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
228ENTRY(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
fb7e197b
JCPV
235 /*
236 * at91rm9200 Memory controller
fb7e197b 237 */
0ab285c2
WY
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
d7d45f25 248 str r3, [r2, #AT91_MC_SDRAMC_SRR]
0ab285c2
WY
249 b exit_sramc_sf
250
251ddrc_sf:
252 cmp r1, #AT91_MEMCTRL_DDRSDR
253 bne sdramc_sf
fb7e197b
JCPV
254
255 /*
0ab285c2 256 * DDR Memory controller
fb7e197b 257 */
0ab285c2
WY
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
299no_2nd_ddrc:
300 b exit_sramc_sf
301
302ddrc_exit_sf:
02f513a0 303 /* Restore MDR in case of LPDDR1 */
0ab285c2
WY
304 ldr r3, .saved_sam9_mdr
305 str r3, [r2, #AT91_DDRSDRC_MDR]
7dca3343 306 /* Restore LPR on AT91 with DDRAM */
0ab285c2
WY
307 ldr r3, .saved_sam9_lpr
308 str r3, [r2, #AT91_DDRSDRC_LPR]
7dca3343 309
0ab285c2
WY
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]
7dca3343 317
0ab285c2 318 b exit_sramc_sf
fb7e197b
JCPV
319
320 /*
321 * SDRAMC Memory controller
322 */
0ab285c2
WY
323sdramc_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
334sdramc_exit_sf:
335 ldr r3, .saved_sam9_lpr
336 str r3, [r2, #AT91_SDRAMC_LPR]
337
338exit_sramc_sf:
339 mov pc, lr
340ENDPROC(at91_sramc_self_refresh)
341
342.pmc_base:
343 .word 0
344.sramc_base:
345 .word 0
346.sramc1_base:
347 .word 0
24a0f5c5
AB
348.shdwc:
349 .word 0
350.sfr:
351 .word 0
0ab285c2
WY
352.memtype:
353 .word 0
23be4be5
WY
354.pm_mode:
355 .word 0
eaad2db0
AV
356.saved_mckr:
357 .word 0
eaad2db0
AV
358.saved_pllar:
359 .word 0
eaad2db0
AV
360.saved_sam9_lpr:
361 .word 0
7dca3343
NF
362.saved_sam9_lpr1:
363 .word 0
02f513a0
PR
364.saved_sam9_mdr:
365 .word 0
02f513a0
PR
366.saved_sam9_mdr1:
367 .word 0
368
5726a8b9
WY
369ENTRY(at91_pm_suspend_in_sram_sz)
370 .word .-at91_pm_suspend_in_sram