1
2
3
4
5
6
7
8
9
10#include <linux/linkage.h>
11#include <linux/clk/at91_pmc.h>
12#include "pm.h"
13#include "pm_data-offsets.h"
14
15#define SRAMC_SELF_FRESH_ACTIVE 0x01
16#define SRAMC_SELF_FRESH_EXIT 0x00
17
18pmc .req r0
19tmp1 .req r4
20tmp2 .req r5
21
22
23
24
25 .macro wait_mckrdy
261: ldr tmp1, [pmc,
27 tst tmp1,
28 beq 1b
29 .endm
30
31
32
33
34 .macro wait_moscrdy
351: ldr tmp1, [pmc,
36 tst tmp1,
37 beq 1b
38 .endm
39
40
41
42
43 .macro wait_moscsels
441: ldr tmp1, [pmc,
45 tst tmp1,
46 beq 1b
47 .endm
48
49
50
51
52 .macro at91_cpu_idle
53
54
55 mov tmp1,
56 str tmp1, [pmc,
57
58 dsb
59
60 wfi @ Wait For Interrupt
61#else
62 mcr p15, 0, tmp1, c7, c0, 4
63#endif
64
65 .endm
66
67 .text
68
69 .arm
70
71
72
73
74
75
76
77 .align 3
78ENTRY(at91_pm_suspend_in_sram)
79
80 stmfd sp!, {r4 - r12, lr}
81
82
83 mov tmp1,
84 mcr p15, 0, tmp1, c7, c10, 4
85
86 ldr tmp1, [r0,
87 str tmp1, .pmc_base
88 ldr tmp1, [r0,
89 str tmp1, .sramc_base
90 ldr tmp1, [r0,
91 str tmp1, .sramc1_base
92 ldr tmp1, [r0,
93 str tmp1, .memtype
94 ldr tmp1, [r0,
95 str tmp1, .pm_mode
96
97 ldr tmp1, [r0,
98 str tmp1, .shdwc
99 cmp tmp1,
100 ldrne tmp2, [tmp1,
101 ldr tmp1, [r0,
102 str tmp1, .sfr
103 cmp tmp1,
104 ldrne tmp2, [tmp1,
105
106
107 mov r0,
108 bl at91_sramc_self_refresh
109
110 ldr r0, .pm_mode
111 cmp r0,
112 beq standby
113 cmp r0,
114 beq backup_mode
115
116 bl at91_ulp_mode
117 b exit_suspend
118
119standby:
120
121 ldr pmc, .pmc_base
122 at91_cpu_idle
123 b exit_suspend
124
125backup_mode:
126 bl at91_backup_mode
127 b exit_suspend
128
129exit_suspend:
130
131 mov r0,
132 bl at91_sramc_self_refresh
133
134
135 ldmfd sp!, {r4 - r12, pc}
136ENDPROC(at91_pm_suspend_in_sram)
137
138ENTRY(at91_backup_mode)
139
140 ldr pmc, .pmc_base
141 ldr tmp1, [pmc,
142 bic tmp1, tmp1,
143 str tmp1, [pmc,
144
145 wait_mckrdy
146
147
148 ldr r0, .sfr
149 mov tmp1,
150 str tmp1, [r0,
151
152
153 ldr r0, .shdwc
154 mov tmp1,
155 add tmp1, tmp1,
156 str tmp1, [r0,
157ENDPROC(at91_backup_mode)
158
159.macro at91_pm_ulp0_mode
160 ldr pmc, .pmc_base
161
162
163 ldr tmp1, [pmc,
164 bic tmp1, tmp1,
165 orr tmp1, tmp1,
166 str tmp1, [pmc,
167
168
169 ldr tmp1, [pmc,
170 str tmp1, .saved_osc_status
171 tst tmp1,
172 bne 1f
173
174
175 ldr tmp1, [pmc,
176 bic tmp1, tmp1,
177 bic tmp1, tmp1,
178 orr tmp1, tmp1,
179 str tmp1, [pmc,
180
181
1822: ldr tmp1, [pmc,
183 tst tmp1,
184 bne 2b
185
186
1871: at91_cpu_idle
188
189
190 ldr tmp1, .saved_osc_status
191 tst tmp1,
192 beq 4f
193
194
195 ldr tmp1, [pmc,
196 orr tmp1, tmp1,
197 bic tmp1, tmp1,
198 orr tmp1, tmp1,
199 str tmp1, [pmc,
200
201
2023: ldr tmp1, [pmc,
203 tst tmp1,
204 beq 3b
205
206
2074: ldr tmp1, [pmc,
208 orr tmp1, tmp1,
209 orr tmp1, tmp1,
210 str tmp1, [pmc,
211
212 wait_moscrdy
213.endm
214
215
216
217
218
219.macro at91_pm_ulp1_mode
220 ldr pmc, .pmc_base
221
222
223 ldr tmp1, [pmc,
224 str tmp1, .saved_osc_status
225 tst tmp1,
226 bne 2f
227
228
229 ldr tmp1, [pmc,
230 orr tmp1, tmp1,
231 bic tmp1, tmp1,
232 orr tmp1, tmp1,
233 str tmp1, [pmc,
234
235
2361: ldr tmp1, [pmc,
237 tst tmp1,
238 beq 1b
239
240
2412: ldr tmp1, [pmc,
242 bic tmp1, tmp1,
243 bic tmp1, tmp1,
244 orr tmp1, tmp1,
245 str tmp1, [pmc,
246
247 wait_moscsels
248
249
250 ldr tmp1, [pmc,
251 bic tmp1, tmp1,
252 bic tmp1, tmp1,
253 orr tmp1, tmp1,
254 str tmp1, [pmc,
255
256
257 ldr tmp1, [pmc,
258 bic tmp1, tmp1,
259 orr tmp1, tmp1,
260 str tmp1, [pmc,
261
262 wait_mckrdy
263
264
265 ldr tmp1, [pmc,
266 orr tmp1, tmp1,
267 bic tmp1, tmp1,
268 orr tmp1, tmp1,
269 str tmp1, [pmc,
270
271 wait_mckrdy
272
273
274 ldr tmp1, [pmc,
275 orr tmp1, tmp1,
276 bic tmp1, tmp1,
277 orr tmp1, tmp1,
278 str tmp1, [pmc,
279
280 wait_moscrdy
281
282
283 ldr tmp1, [pmc,
284 bic tmp1, tmp1,
285 str tmp1, [pmc,
286
287 wait_mckrdy
288
289
290 ldr tmp1, [pmc,
291 orr tmp1, tmp1,
292 bic tmp1, tmp1,
293 orr tmp1, tmp1,
294 str tmp1, [pmc,
295
296 wait_moscsels
297
298
299 ldr tmp1, [pmc,
300 bic tmp1, tmp1,
301 orr tmp1, tmp1,
302 str tmp1, [pmc,
303
304 wait_mckrdy
305
306
307 ldr tmp1, .saved_osc_status
308 tst tmp1,
309 bne 3f
310
311
312 ldr tmp1, [pmc,
313 bic tmp1, tmp1,
314 bic tmp1, tmp1,
315 orr tmp1, tmp1,
316 str tmp1, [pmc,
317
318
3194: ldr tmp1, [pmc,
320 tst tmp1,
321 bne 4b
322
3233:
324.endm
325
326ENTRY(at91_ulp_mode)
327 ldr pmc, .pmc_base
328
329
330 ldr tmp1, [pmc,
331 str tmp1, .saved_mckr
332
333
334
335
336 bic tmp1, tmp1,
337 str tmp1, [pmc,
338
339 wait_mckrdy
340
341 ldr r0, .pm_mode
342 cmp r0,
343 beq ulp1_mode
344
345 at91_pm_ulp0_mode
346 b ulp_exit
347
348ulp1_mode:
349 at91_pm_ulp1_mode
350 b ulp_exit
351
352ulp_exit:
353 ldr pmc, .pmc_base
354
355
356
357
358 ldr tmp1, .saved_mckr
359 str tmp1, [pmc,
360
361 wait_mckrdy
362
363 mov pc, lr
364ENDPROC(at91_ulp_mode)
365
366
367
368
369
370
371
372
373
374
375
376
377ENTRY(at91_sramc_self_refresh)
378 ldr r1, .memtype
379 ldr r2, .sramc_base
380
381 cmp r1,
382 bne ddrc_sf
383
384
385
386
387
388
389
390
391
392 tst r0,
393 beq exit_sramc_sf
394
395
396 mov r3,
397 str r3, [r2,
398 b exit_sramc_sf
399
400ddrc_sf:
401 cmp r1,
402 bne sdramc_sf
403
404
405
406
407 tst r0,
408 beq ddrc_exit_sf
409
410
411 ldr r3, [r2,
412 str r3, .saved_sam9_mdr
413 bic r3, r3,
414 cmp r3,
415 ldreq r3, [r2,
416 biceq r3, r3,
417 orreq r3, r3,
418 streq r3, [r2,
419
420
421 ldr r3, [r2,
422 str r3, .saved_sam9_lpr
423 bic r3, r3,
424 orr r3, r3,
425 str r3, [r2,
426
427
428 ldr r2, .sramc1_base
429 cmp r2,
430 beq no_2nd_ddrc
431
432 ldr r3, [r2,
433 str r3, .saved_sam9_mdr1
434 bic r3, r3,
435 cmp r3,
436 ldreq r3, [r2,
437 biceq r3, r3,
438 orreq r3, r3,
439 streq r3, [r2,
440
441
442 ldr r3, [r2,
443 str r3, .saved_sam9_lpr1
444 bic r3, r3,
445 orr r3, r3,
446 str r3, [r2,
447
448no_2nd_ddrc:
449 b exit_sramc_sf
450
451ddrc_exit_sf:
452
453 ldr r3, .saved_sam9_mdr
454 str r3, [r2,
455
456 ldr r3, .saved_sam9_lpr
457 str r3, [r2,
458
459
460 ldr r2, .sramc1_base
461 cmp r2,
462 ldrne r3, .saved_sam9_mdr1
463 strne r3, [r2,
464 ldrne r3, .saved_sam9_lpr1
465 strne r3, [r2,
466
467 b exit_sramc_sf
468
469
470
471
472sdramc_sf:
473 tst r0,
474 beq sdramc_exit_sf
475
476
477 ldr r3, [r2,
478 str r3, .saved_sam9_lpr
479 bic r3, r3,
480 orr r3, r3,
481 str r3, [r2,
482
483sdramc_exit_sf:
484 ldr r3, .saved_sam9_lpr
485 str r3, [r2,
486
487exit_sramc_sf:
488 mov pc, lr
489ENDPROC(at91_sramc_self_refresh)
490
491.pmc_base:
492 .word 0
493.sramc_base:
494 .word 0
495.sramc1_base:
496 .word 0
497.shdwc:
498 .word 0
499.sfr:
500 .word 0
501.memtype:
502 .word 0
503.pm_mode:
504 .word 0
505.saved_mckr:
506 .word 0
507.saved_sam9_lpr:
508 .word 0
509.saved_sam9_lpr1:
510 .word 0
511.saved_sam9_mdr:
512 .word 0
513.saved_sam9_mdr1:
514 .word 0
515.saved_osc_status:
516 .word 0
517
518ENTRY(at91_pm_suspend_in_sram_sz)
519 .word .-at91_pm_suspend_in_sram
520