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
18 pmc .req r0
19 tmp1 .req r4
20 tmp2 .req r5
21
22
23
24
25 .macro wait_mckrdy
26 1: ldr tmp1, [pmc, #AT91_PMC_SR]
27 tst tmp1, #AT91_PMC_MCKRDY
28 beq 1b
29 .endm
30
31
32
33
34 .macro wait_moscrdy
35 1: ldr tmp1, [pmc, #AT91_PMC_SR]
36 tst tmp1, #AT91_PMC_MOSCS
37 beq 1b
38 .endm
39
40
41
42
43 .macro wait_moscsels
44 1: ldr tmp1, [pmc, #AT91_PMC_SR]
45 tst tmp1, #AT91_PMC_MOSCSELS
46 beq 1b
47 .endm
48
49
50
51
52 .macro at91_cpu_idle
53
54 #if defined(CONFIG_CPU_V7)
55 mov tmp1, #AT91_PMC_PCK
56 str tmp1, [pmc, #AT91_PMC_SCDR]
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
78 ENTRY(at91_pm_suspend_in_sram)
79
80 stmfd sp!, {r4 - r12, lr}
81
82
83 mov tmp1, #0
84 mcr p15, 0, tmp1, c7, c10, 4
85
86 ldr tmp1, [r0, #PM_DATA_PMC]
87 str tmp1, .pmc_base
88 ldr tmp1, [r0, #PM_DATA_RAMC0]
89 str tmp1, .sramc_base
90 ldr tmp1, [r0, #PM_DATA_RAMC1]
91 str tmp1, .sramc1_base
92 ldr tmp1, [r0, #PM_DATA_MEMCTRL]
93 str tmp1, .memtype
94 ldr tmp1, [r0, #PM_DATA_MODE]
95 str tmp1, .pm_mode
96
97 ldr tmp1, [r0, #PM_DATA_SHDWC]
98 str tmp1, .shdwc
99 cmp tmp1, #0
100 ldrne tmp2, [tmp1, #0]
101 ldr tmp1, [r0, #PM_DATA_SFRBU]
102 str tmp1, .sfr
103 cmp tmp1, #0
104 ldrne tmp2, [tmp1, #0x10]
105
106
107 mov r0, #SRAMC_SELF_FRESH_ACTIVE
108 bl at91_sramc_self_refresh
109
110 ldr r0, .pm_mode
111 cmp r0, #AT91_PM_STANDBY
112 beq standby
113 cmp r0, #AT91_PM_BACKUP
114 beq backup_mode
115
116 bl at91_ulp_mode
117 b exit_suspend
118
119 standby:
120
121 ldr pmc, .pmc_base
122 at91_cpu_idle
123 b exit_suspend
124
125 backup_mode:
126 bl at91_backup_mode
127 b exit_suspend
128
129 exit_suspend:
130
131 mov r0, #SRAMC_SELF_FRESH_EXIT
132 bl at91_sramc_self_refresh
133
134
135 ldmfd sp!, {r4 - r12, pc}
136 ENDPROC(at91_pm_suspend_in_sram)
137
138 ENTRY(at91_backup_mode)
139
140 ldr pmc, .pmc_base
141 ldr tmp1, [pmc, #AT91_PMC_MCKR]
142 bic tmp1, tmp1, #AT91_PMC_CSS
143 str tmp1, [pmc, #AT91_PMC_MCKR]
144
145 wait_mckrdy
146
147
148 ldr r0, .sfr
149 mov tmp1, #0x1
150 str tmp1, [r0, #0x10]
151
152
153 ldr r0, .shdwc
154 mov tmp1, #0xA5000000
155 add tmp1, tmp1, #0x1
156 str tmp1, [r0, #0]
157 ENDPROC(at91_backup_mode)
158
159 .macro at91_pm_ulp0_mode
160 ldr pmc, .pmc_base
161
162
163 ldr tmp1, [pmc, #AT91_CKGR_MOR]
164 bic tmp1, tmp1, #AT91_PMC_MOSCEN
165 orr tmp1, tmp1, #AT91_PMC_KEY
166 str tmp1, [pmc, #AT91_CKGR_MOR]
167
168
169 ldr tmp1, [pmc, #AT91_PMC_SR]
170 str tmp1, .saved_osc_status
171 tst tmp1, #AT91_PMC_MOSCRCS
172 bne 1f
173
174
175 ldr tmp1, [pmc, #AT91_CKGR_MOR]
176 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
177 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
178 orr tmp1, tmp1, #AT91_PMC_KEY
179 str tmp1, [pmc, #AT91_CKGR_MOR]
180
181
182 2: ldr tmp1, [pmc, #AT91_PMC_SR]
183 tst tmp1, #AT91_PMC_MOSCRCS
184 bne 2b
185
186
187 1: at91_cpu_idle
188
189
190 ldr tmp1, .saved_osc_status
191 tst tmp1, #AT91_PMC_MOSCRCS
192 beq 4f
193
194
195 ldr tmp1, [pmc, #AT91_CKGR_MOR]
196 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
197 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
198 orr tmp1, tmp1, #AT91_PMC_KEY
199 str tmp1, [pmc, #AT91_CKGR_MOR]
200
201
202 3: ldr tmp1, [pmc, #AT91_PMC_SR]
203 tst tmp1, #AT91_PMC_MOSCRCS
204 beq 3b
205
206
207 4: ldr tmp1, [pmc, #AT91_CKGR_MOR]
208 orr tmp1, tmp1, #AT91_PMC_MOSCEN
209 orr tmp1, tmp1, #AT91_PMC_KEY
210 str tmp1, [pmc, #AT91_CKGR_MOR]
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, #AT91_PMC_SR]
224 str tmp1, .saved_osc_status
225 tst tmp1, #AT91_PMC_MOSCRCS
226 bne 2f
227
228
229 ldr tmp1, [pmc, #AT91_CKGR_MOR]
230 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
231 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
232 orr tmp1, tmp1, #AT91_PMC_KEY
233 str tmp1, [pmc, #AT91_CKGR_MOR]
234
235
236 1: ldr tmp1, [pmc, #AT91_PMC_SR]
237 tst tmp1, #AT91_PMC_MOSCRCS
238 beq 1b
239
240
241 2: ldr tmp1, [pmc, #AT91_CKGR_MOR]
242 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
243 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
244 orr tmp1, tmp1, #AT91_PMC_KEY
245 str tmp1, [pmc, #AT91_CKGR_MOR]
246
247 wait_moscsels
248
249
250 ldr tmp1, [pmc, #AT91_CKGR_MOR]
251 bic tmp1, tmp1, #AT91_PMC_MOSCEN
252 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
253 orr tmp1, tmp1, #AT91_PMC_KEY
254 str tmp1, [pmc, #AT91_CKGR_MOR]
255
256
257 ldr tmp1, [pmc, #AT91_PMC_MCKR]
258 bic tmp1, tmp1, #AT91_PMC_CSS
259 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
260 str tmp1, [pmc, #AT91_PMC_MCKR]
261
262 wait_mckrdy
263
264
265 ldr tmp1, [pmc, #AT91_CKGR_MOR]
266 orr tmp1, tmp1, #AT91_PMC_WAITMODE
267 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
268 orr tmp1, tmp1, #AT91_PMC_KEY
269 str tmp1, [pmc, #AT91_CKGR_MOR]
270
271 wait_mckrdy
272
273
274 ldr tmp1, [pmc, #AT91_CKGR_MOR]
275 orr tmp1, tmp1, #AT91_PMC_MOSCEN
276 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
277 orr tmp1, tmp1, #AT91_PMC_KEY
278 str tmp1, [pmc, #AT91_CKGR_MOR]
279
280 wait_moscrdy
281
282
283 ldr tmp1, [pmc, #AT91_PMC_MCKR]
284 bic tmp1, tmp1, #AT91_PMC_CSS
285 str tmp1, [pmc, #AT91_PMC_MCKR]
286
287 wait_mckrdy
288
289
290 ldr tmp1, [pmc, #AT91_CKGR_MOR]
291 orr tmp1, tmp1, #AT91_PMC_MOSCSEL
292 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
293 orr tmp1, tmp1, #AT91_PMC_KEY
294 str tmp1, [pmc, #AT91_CKGR_MOR]
295
296 wait_moscsels
297
298
299 ldr tmp1, [pmc, #AT91_PMC_MCKR]
300 bic tmp1, tmp1, #AT91_PMC_CSS
301 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
302 str tmp1, [pmc, #AT91_PMC_MCKR]
303
304 wait_mckrdy
305
306
307 ldr tmp1, .saved_osc_status
308 tst tmp1, #AT91_PMC_MOSCRCS
309 bne 3f
310
311
312 ldr tmp1, [pmc, #AT91_CKGR_MOR]
313 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
314 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
315 orr tmp1, tmp1, #AT91_PMC_KEY
316 str tmp1, [pmc, #AT91_CKGR_MOR]
317
318
319 4: ldr tmp1, [pmc, #AT91_PMC_SR]
320 tst tmp1, #AT91_PMC_MOSCRCS
321 bne 4b
322
323 3:
324 .endm
325
326 ENTRY(at91_ulp_mode)
327 ldr pmc, .pmc_base
328
329
330 ldr tmp1, [pmc, #AT91_PMC_MCKR]
331 str tmp1, .saved_mckr
332
333
334
335
336 bic tmp1, tmp1, #AT91_PMC_CSS
337 str tmp1, [pmc, #AT91_PMC_MCKR]
338
339 wait_mckrdy
340
341 ldr r0, .pm_mode
342 cmp r0, #AT91_PM_ULP1
343 beq ulp1_mode
344
345 at91_pm_ulp0_mode
346 b ulp_exit
347
348 ulp1_mode:
349 at91_pm_ulp1_mode
350 b ulp_exit
351
352 ulp_exit:
353 ldr pmc, .pmc_base
354
355
356
357
358 ldr tmp1, .saved_mckr
359 str tmp1, [pmc, #AT91_PMC_MCKR]
360
361 wait_mckrdy
362
363 mov pc, lr
364 ENDPROC(at91_ulp_mode)
365
366
367
368
369
370
371
372
373
374
375
376
377 ENTRY(at91_sramc_self_refresh)
378 ldr r1, .memtype
379 ldr r2, .sramc_base
380
381 cmp r1, #AT91_MEMCTRL_MC
382 bne ddrc_sf
383
384
385
386
387
388
389
390
391
392 tst r0, #SRAMC_SELF_FRESH_ACTIVE
393 beq exit_sramc_sf
394
395
396 mov r3, #1
397 str r3, [r2, #AT91_MC_SDRAMC_SRR]
398 b exit_sramc_sf
399
400 ddrc_sf:
401 cmp r1, #AT91_MEMCTRL_DDRSDR
402 bne sdramc_sf
403
404
405
406
407 tst r0, #SRAMC_SELF_FRESH_ACTIVE
408 beq ddrc_exit_sf
409
410
411 ldr r3, [r2, #AT91_DDRSDRC_MDR]
412 str r3, .saved_sam9_mdr
413 bic r3, r3, #~AT91_DDRSDRC_MD
414 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
415 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
416 biceq r3, r3, #AT91_DDRSDRC_MD
417 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
418 streq r3, [r2, #AT91_DDRSDRC_MDR]
419
420
421 ldr r3, [r2, #AT91_DDRSDRC_LPR]
422 str r3, .saved_sam9_lpr
423 bic r3, r3, #AT91_DDRSDRC_LPCB
424 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
425 str r3, [r2, #AT91_DDRSDRC_LPR]
426
427
428 ldr r2, .sramc1_base
429 cmp r2, #0
430 beq no_2nd_ddrc
431
432 ldr r3, [r2, #AT91_DDRSDRC_MDR]
433 str r3, .saved_sam9_mdr1
434 bic r3, r3, #~AT91_DDRSDRC_MD
435 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
436 ldreq r3, [r2, #AT91_DDRSDRC_MDR]
437 biceq r3, r3, #AT91_DDRSDRC_MD
438 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
439 streq r3, [r2, #AT91_DDRSDRC_MDR]
440
441
442 ldr r3, [r2, #AT91_DDRSDRC_LPR]
443 str r3, .saved_sam9_lpr1
444 bic r3, r3, #AT91_DDRSDRC_LPCB
445 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
446 str r3, [r2, #AT91_DDRSDRC_LPR]
447
448 no_2nd_ddrc:
449 b exit_sramc_sf
450
451 ddrc_exit_sf:
452
453 ldr r3, .saved_sam9_mdr
454 str r3, [r2, #AT91_DDRSDRC_MDR]
455
456 ldr r3, .saved_sam9_lpr
457 str r3, [r2, #AT91_DDRSDRC_LPR]
458
459
460 ldr r2, .sramc1_base
461 cmp r2, #0
462 ldrne r3, .saved_sam9_mdr1
463 strne r3, [r2, #AT91_DDRSDRC_MDR]
464 ldrne r3, .saved_sam9_lpr1
465 strne r3, [r2, #AT91_DDRSDRC_LPR]
466
467 b exit_sramc_sf
468
469
470
471
472 sdramc_sf:
473 tst r0, #SRAMC_SELF_FRESH_ACTIVE
474 beq sdramc_exit_sf
475
476
477 ldr r3, [r2, #AT91_SDRAMC_LPR]
478 str r3, .saved_sam9_lpr
479 bic r3, r3, #AT91_SDRAMC_LPCB
480 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
481 str r3, [r2, #AT91_SDRAMC_LPR]
482
483 sdramc_exit_sf:
484 ldr r3, .saved_sam9_lpr
485 str r3, [r2, #AT91_SDRAMC_LPR]
486
487 exit_sramc_sf:
488 mov pc, lr
489 ENDPROC(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
518 ENTRY(at91_pm_suspend_in_sram_sz)
519 .word .-at91_pm_suspend_in_sram