1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * arch/arm/mach-at91/pm_slow_clock.S |
4 | * |
5 | * Copyright (C) 2006 Savin Zlobec |
6 | * |
7 | * AT91SAM9 support: |
8 | * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee> |
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 | #ifdef CONFIG_CPU_V7 |
16 | .arch armv7-a |
17 | #endif |
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 | tmp3 .req r6 |
26 | |
27 | /* |
28 | * Wait until master clock is ready (after switching master clock source) |
29 | * |
30 | * @r_mckid: register holding master clock identifier |
31 | * |
32 | * Side effects: overwrites r7, r8 |
33 | */ |
34 | .macro wait_mckrdy r_mckid |
35 | #ifdef CONFIG_SOC_SAMA7 |
36 | cmp \r_mckid, #0 |
37 | beq 1f |
38 | mov r7, #AT91_PMC_MCKXRDY |
39 | b 2f |
40 | #endif |
41 | 1: mov r7, #AT91_PMC_MCKRDY |
42 | 2: ldr r8, [pmc, #AT91_PMC_SR] |
43 | and r8, r7 |
44 | cmp r8, r7 |
45 | bne 2b |
46 | .endm |
47 | |
48 | /* |
49 | * Wait until master oscillator has stabilized. |
50 | * |
51 | * Side effects: overwrites r7 |
52 | */ |
53 | .macro wait_moscrdy |
54 | 1: ldr r7, [pmc, #AT91_PMC_SR] |
55 | tst r7, #AT91_PMC_MOSCS |
56 | beq 1b |
57 | .endm |
58 | |
59 | /* |
60 | * Wait for main oscillator selection is done |
61 | * |
62 | * Side effects: overwrites r7 |
63 | */ |
64 | .macro wait_moscsels |
65 | 1: ldr r7, [pmc, #AT91_PMC_SR] |
66 | tst r7, #AT91_PMC_MOSCSELS |
67 | beq 1b |
68 | .endm |
69 | |
70 | /* |
71 | * Put the processor to enter the idle state |
72 | * |
73 | * Side effects: overwrites r7 |
74 | */ |
75 | .macro at91_cpu_idle |
76 | |
77 | #if defined(CONFIG_CPU_V7) |
78 | mov r7, #AT91_PMC_PCK |
79 | str r7, [pmc, #AT91_PMC_SCDR] |
80 | |
81 | dsb |
82 | |
83 | wfi @ Wait For Interrupt |
84 | #else |
85 | mcr p15, 0, tmp1, c7, c0, 4 |
86 | #endif |
87 | |
88 | .endm |
89 | |
90 | /** |
91 | * Set state for 2.5V low power regulator |
92 | * @ena: 0 - disable regulator |
93 | * 1 - enable regulator |
94 | * |
95 | * Side effects: overwrites r7, r8, r9, r10 |
96 | */ |
97 | .macro at91_2_5V_reg_set_low_power ena |
98 | #ifdef CONFIG_SOC_SAMA7 |
99 | ldr r7, .sfrbu |
100 | mov r8, #\ena |
101 | ldr r9, [r7, #AT91_SFRBU_25LDOCR] |
102 | orr r9, r9, #AT91_SFRBU_25LDOCR_LP |
103 | cmp r8, #1 |
104 | beq lp_done_\ena |
105 | bic r9, r9, #AT91_SFRBU_25LDOCR_LP |
106 | lp_done_\ena: |
107 | ldr r10, =AT91_SFRBU_25LDOCR_LDOANAKEY |
108 | orr r9, r9, r10 |
109 | str r9, [r7, #AT91_SFRBU_25LDOCR] |
110 | #endif |
111 | .endm |
112 | |
113 | .macro at91_backup_set_lpm reg |
114 | #ifdef CONFIG_SOC_SAMA7 |
115 | orr \reg, \reg, #0x200000 |
116 | #endif |
117 | .endm |
118 | |
119 | .text |
120 | |
121 | .arm |
122 | |
123 | #ifdef CONFIG_SOC_SAMA7 |
124 | /** |
125 | * Enable self-refresh |
126 | * |
127 | * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7 |
128 | */ |
129 | .macro at91_sramc_self_refresh_ena |
130 | ldr r2, .sramc_base |
131 | ldr r3, .sramc_phy_base |
132 | ldr r7, .pm_mode |
133 | |
134 | dsb |
135 | |
136 | /* Disable all AXI ports. */ |
137 | ldr tmp1, [r2, #UDDRC_PCTRL_0] |
138 | bic tmp1, tmp1, #0x1 |
139 | str tmp1, [r2, #UDDRC_PCTRL_0] |
140 | |
141 | ldr tmp1, [r2, #UDDRC_PCTRL_1] |
142 | bic tmp1, tmp1, #0x1 |
143 | str tmp1, [r2, #UDDRC_PCTRL_1] |
144 | |
145 | ldr tmp1, [r2, #UDDRC_PCTRL_2] |
146 | bic tmp1, tmp1, #0x1 |
147 | str tmp1, [r2, #UDDRC_PCTRL_2] |
148 | |
149 | ldr tmp1, [r2, #UDDRC_PCTRL_3] |
150 | bic tmp1, tmp1, #0x1 |
151 | str tmp1, [r2, #UDDRC_PCTRL_3] |
152 | |
153 | ldr tmp1, [r2, #UDDRC_PCTRL_4] |
154 | bic tmp1, tmp1, #0x1 |
155 | str tmp1, [r2, #UDDRC_PCTRL_4] |
156 | |
157 | sr_ena_1: |
158 | /* Wait for all ports to disable. */ |
159 | ldr tmp1, [r2, #UDDRC_PSTAT] |
160 | ldr tmp2, =UDDRC_PSTAT_ALL_PORTS |
161 | tst tmp1, tmp2 |
162 | bne sr_ena_1 |
163 | |
164 | /* Switch to self-refresh. */ |
165 | ldr tmp1, [r2, #UDDRC_PWRCTL] |
166 | orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW |
167 | str tmp1, [r2, #UDDRC_PWRCTL] |
168 | |
169 | sr_ena_2: |
170 | /* Wait for self-refresh enter. */ |
171 | ldr tmp1, [r2, #UDDRC_STAT] |
172 | bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK |
173 | cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW |
174 | bne sr_ena_2 |
175 | |
176 | /* Disable DX DLLs for non-backup modes. */ |
177 | cmp r7, #AT91_PM_BACKUP |
178 | beq sr_ena_3 |
179 | |
180 | /* Do not soft reset the AC DLL. */ |
181 | ldr tmp1, [r3, DDR3PHY_ACDLLCR] |
182 | bic tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST |
183 | str tmp1, [r3, DDR3PHY_ACDLLCR] |
184 | |
185 | /* Disable DX DLLs. */ |
186 | ldr tmp1, [r3, #DDR3PHY_DX0DLLCR] |
187 | orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS |
188 | str tmp1, [r3, #DDR3PHY_DX0DLLCR] |
189 | |
190 | ldr tmp1, [r3, #DDR3PHY_DX1DLLCR] |
191 | orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS |
192 | str tmp1, [r3, #DDR3PHY_DX1DLLCR] |
193 | |
194 | sr_ena_3: |
195 | /* Power down DDR PHY data receivers. */ |
196 | ldr tmp1, [r3, #DDR3PHY_DXCCR] |
197 | orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR |
198 | str tmp1, [r3, #DDR3PHY_DXCCR] |
199 | |
200 | /* Power down ADDR/CMD IO. */ |
201 | ldr tmp1, [r3, #DDR3PHY_ACIOCR] |
202 | orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD |
203 | orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 |
204 | orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 |
205 | str tmp1, [r3, #DDR3PHY_ACIOCR] |
206 | |
207 | /* Power down ODT. */ |
208 | ldr tmp1, [r3, #DDR3PHY_DSGCR] |
209 | orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 |
210 | str tmp1, [r3, #DDR3PHY_DSGCR] |
211 | .endm |
212 | |
213 | /** |
214 | * Disable self-refresh |
215 | * |
216 | * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3 |
217 | */ |
218 | .macro at91_sramc_self_refresh_dis |
219 | ldr r2, .sramc_base |
220 | ldr r3, .sramc_phy_base |
221 | |
222 | /* Power up DDR PHY data receivers. */ |
223 | ldr tmp1, [r3, #DDR3PHY_DXCCR] |
224 | bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR |
225 | str tmp1, [r3, #DDR3PHY_DXCCR] |
226 | |
227 | /* Power up the output of CK and CS pins. */ |
228 | ldr tmp1, [r3, #DDR3PHY_ACIOCR] |
229 | bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD |
230 | bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 |
231 | bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 |
232 | str tmp1, [r3, #DDR3PHY_ACIOCR] |
233 | |
234 | /* Power up ODT. */ |
235 | ldr tmp1, [r3, #DDR3PHY_DSGCR] |
236 | bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 |
237 | str tmp1, [r3, #DDR3PHY_DSGCR] |
238 | |
239 | /* Enable DX DLLs. */ |
240 | ldr tmp1, [r3, #DDR3PHY_DX0DLLCR] |
241 | bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS |
242 | str tmp1, [r3, #DDR3PHY_DX0DLLCR] |
243 | |
244 | ldr tmp1, [r3, #DDR3PHY_DX1DLLCR] |
245 | bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS |
246 | str tmp1, [r3, #DDR3PHY_DX1DLLCR] |
247 | |
248 | /* Enable quasi-dynamic programming. */ |
249 | mov tmp1, #0 |
250 | str tmp1, [r2, #UDDRC_SWCTRL] |
251 | |
252 | /* De-assert SDRAM initialization. */ |
253 | ldr tmp1, [r2, #UDDRC_DFIMISC] |
254 | bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN |
255 | str tmp1, [r2, #UDDRC_DFIMISC] |
256 | |
257 | /* Quasi-dynamic programming done. */ |
258 | mov tmp1, #UDDRC_SWCTRL_SW_DONE |
259 | str tmp1, [r2, #UDDRC_SWCTRL] |
260 | |
261 | sr_dis_1: |
262 | ldr tmp1, [r2, #UDDRC_SWSTAT] |
263 | tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK |
264 | beq sr_dis_1 |
265 | |
266 | /* DLL soft-reset + DLL lock wait + ITM reset */ |
267 | mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \ |
268 | DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST) |
269 | str tmp1, [r3, #DDR3PHY_PIR] |
270 | |
271 | sr_dis_4: |
272 | /* Wait for it. */ |
273 | ldr tmp1, [r3, #DDR3PHY_PGSR] |
274 | tst tmp1, #DDR3PHY_PGSR_IDONE |
275 | beq sr_dis_4 |
276 | |
277 | /* Enable quasi-dynamic programming. */ |
278 | mov tmp1, #0 |
279 | str tmp1, [r2, #UDDRC_SWCTRL] |
280 | |
281 | /* Assert PHY init complete enable signal. */ |
282 | ldr tmp1, [r2, #UDDRC_DFIMISC] |
283 | orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN |
284 | str tmp1, [r2, #UDDRC_DFIMISC] |
285 | |
286 | /* Programming is done. Set sw_done. */ |
287 | mov tmp1, #UDDRC_SWCTRL_SW_DONE |
288 | str tmp1, [r2, #UDDRC_SWCTRL] |
289 | |
290 | sr_dis_5: |
291 | /* Wait for it. */ |
292 | ldr tmp1, [r2, #UDDRC_SWSTAT] |
293 | tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK |
294 | beq sr_dis_5 |
295 | |
296 | /* Trigger self-refresh exit. */ |
297 | ldr tmp1, [r2, #UDDRC_PWRCTL] |
298 | bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW |
299 | str tmp1, [r2, #UDDRC_PWRCTL] |
300 | |
301 | sr_dis_6: |
302 | /* Wait for self-refresh exit done. */ |
303 | ldr tmp1, [r2, #UDDRC_STAT] |
304 | bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK |
305 | cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL |
306 | bne sr_dis_6 |
307 | |
308 | /* Enable all AXI ports. */ |
309 | ldr tmp1, [r2, #UDDRC_PCTRL_0] |
310 | orr tmp1, tmp1, #0x1 |
311 | str tmp1, [r2, #UDDRC_PCTRL_0] |
312 | |
313 | ldr tmp1, [r2, #UDDRC_PCTRL_1] |
314 | orr tmp1, tmp1, #0x1 |
315 | str tmp1, [r2, #UDDRC_PCTRL_1] |
316 | |
317 | ldr tmp1, [r2, #UDDRC_PCTRL_2] |
318 | orr tmp1, tmp1, #0x1 |
319 | str tmp1, [r2, #UDDRC_PCTRL_2] |
320 | |
321 | ldr tmp1, [r2, #UDDRC_PCTRL_3] |
322 | orr tmp1, tmp1, #0x1 |
323 | str tmp1, [r2, #UDDRC_PCTRL_3] |
324 | |
325 | ldr tmp1, [r2, #UDDRC_PCTRL_4] |
326 | orr tmp1, tmp1, #0x1 |
327 | str tmp1, [r2, #UDDRC_PCTRL_4] |
328 | |
329 | dsb |
330 | .endm |
331 | #else |
332 | /** |
333 | * Enable self-refresh |
334 | * |
335 | * register usage: |
336 | * @r1: memory type |
337 | * @r2: base address of the sram controller |
338 | * @r3: temporary |
339 | */ |
340 | .macro at91_sramc_self_refresh_ena |
341 | ldr r1, .memtype |
342 | ldr r2, .sramc_base |
343 | |
344 | cmp r1, #AT91_MEMCTRL_MC |
345 | bne sr_ena_ddrc_sf |
346 | |
347 | /* Active SDRAM self-refresh mode */ |
348 | mov r3, #1 |
349 | str r3, [r2, #AT91_MC_SDRAMC_SRR] |
350 | b sr_ena_exit |
351 | |
352 | sr_ena_ddrc_sf: |
353 | cmp r1, #AT91_MEMCTRL_DDRSDR |
354 | bne sr_ena_sdramc_sf |
355 | |
356 | /* |
357 | * DDR Memory controller |
358 | */ |
359 | |
360 | /* LPDDR1 --> force DDR2 mode during self-refresh */ |
361 | ldr r3, [r2, #AT91_DDRSDRC_MDR] |
362 | str r3, .saved_sam9_mdr |
363 | bic r3, r3, #~AT91_DDRSDRC_MD |
364 | cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR |
365 | ldreq r3, [r2, #AT91_DDRSDRC_MDR] |
366 | biceq r3, r3, #AT91_DDRSDRC_MD |
367 | orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 |
368 | streq r3, [r2, #AT91_DDRSDRC_MDR] |
369 | |
370 | /* Active DDRC self-refresh mode */ |
371 | ldr r3, [r2, #AT91_DDRSDRC_LPR] |
372 | str r3, .saved_sam9_lpr |
373 | bic r3, r3, #AT91_DDRSDRC_LPCB |
374 | orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH |
375 | str r3, [r2, #AT91_DDRSDRC_LPR] |
376 | |
377 | /* If using the 2nd ddr controller */ |
378 | ldr r2, .sramc1_base |
379 | cmp r2, #0 |
380 | beq sr_ena_no_2nd_ddrc |
381 | |
382 | ldr r3, [r2, #AT91_DDRSDRC_MDR] |
383 | str r3, .saved_sam9_mdr1 |
384 | bic r3, r3, #~AT91_DDRSDRC_MD |
385 | cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR |
386 | ldreq r3, [r2, #AT91_DDRSDRC_MDR] |
387 | biceq r3, r3, #AT91_DDRSDRC_MD |
388 | orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 |
389 | streq r3, [r2, #AT91_DDRSDRC_MDR] |
390 | |
391 | /* Active DDRC self-refresh mode */ |
392 | ldr r3, [r2, #AT91_DDRSDRC_LPR] |
393 | str r3, .saved_sam9_lpr1 |
394 | bic r3, r3, #AT91_DDRSDRC_LPCB |
395 | orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH |
396 | str r3, [r2, #AT91_DDRSDRC_LPR] |
397 | |
398 | sr_ena_no_2nd_ddrc: |
399 | b sr_ena_exit |
400 | |
401 | /* |
402 | * SDRAMC Memory controller |
403 | */ |
404 | sr_ena_sdramc_sf: |
405 | /* Active SDRAMC self-refresh mode */ |
406 | ldr r3, [r2, #AT91_SDRAMC_LPR] |
407 | str r3, .saved_sam9_lpr |
408 | bic r3, r3, #AT91_SDRAMC_LPCB |
409 | orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH |
410 | str r3, [r2, #AT91_SDRAMC_LPR] |
411 | |
412 | ldr r3, .saved_sam9_lpr |
413 | str r3, [r2, #AT91_SDRAMC_LPR] |
414 | |
415 | sr_ena_exit: |
416 | .endm |
417 | |
418 | /** |
419 | * Disable self-refresh |
420 | * |
421 | * register usage: |
422 | * @r1: memory type |
423 | * @r2: base address of the sram controller |
424 | * @r3: temporary |
425 | */ |
426 | .macro at91_sramc_self_refresh_dis |
427 | ldr r1, .memtype |
428 | ldr r2, .sramc_base |
429 | |
430 | cmp r1, #AT91_MEMCTRL_MC |
431 | bne sr_dis_ddrc_exit_sf |
432 | |
433 | /* |
434 | * at91rm9200 Memory controller |
435 | */ |
436 | |
437 | /* |
438 | * For exiting the self-refresh mode, do nothing, |
439 | * automatically exit the self-refresh mode. |
440 | */ |
441 | b sr_dis_exit |
442 | |
443 | sr_dis_ddrc_exit_sf: |
444 | cmp r1, #AT91_MEMCTRL_DDRSDR |
445 | bne sdramc_exit_sf |
446 | |
447 | /* DDR Memory controller */ |
448 | |
449 | /* Restore MDR in case of LPDDR1 */ |
450 | ldr r3, .saved_sam9_mdr |
451 | str r3, [r2, #AT91_DDRSDRC_MDR] |
452 | /* Restore LPR on AT91 with DDRAM */ |
453 | ldr r3, .saved_sam9_lpr |
454 | str r3, [r2, #AT91_DDRSDRC_LPR] |
455 | |
456 | /* If using the 2nd ddr controller */ |
457 | ldr r2, .sramc1_base |
458 | cmp r2, #0 |
459 | ldrne r3, .saved_sam9_mdr1 |
460 | strne r3, [r2, #AT91_DDRSDRC_MDR] |
461 | ldrne r3, .saved_sam9_lpr1 |
462 | strne r3, [r2, #AT91_DDRSDRC_LPR] |
463 | |
464 | b sr_dis_exit |
465 | |
466 | sdramc_exit_sf: |
467 | /* SDRAMC Memory controller */ |
468 | ldr r3, .saved_sam9_lpr |
469 | str r3, [r2, #AT91_SDRAMC_LPR] |
470 | |
471 | sr_dis_exit: |
472 | .endm |
473 | #endif |
474 | |
475 | .macro at91_pm_ulp0_mode |
476 | ldr pmc, .pmc_base |
477 | ldr tmp2, .pm_mode |
478 | ldr tmp3, .mckr_offset |
479 | |
480 | /* Check if ULP0 fast variant has been requested. */ |
481 | cmp tmp2, #AT91_PM_ULP0_FAST |
482 | bne 0f |
483 | |
484 | /* Set highest prescaler for power saving */ |
485 | ldr tmp1, [pmc, tmp3] |
486 | bic tmp1, tmp1, #AT91_PMC_PRES |
487 | orr tmp1, tmp1, #AT91_PMC_PRES_64 |
488 | str tmp1, [pmc, tmp3] |
489 | |
490 | mov tmp3, #0 |
491 | wait_mckrdy tmp3 |
492 | b 1f |
493 | |
494 | 0: |
495 | /* Turn off the crystal oscillator */ |
496 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
497 | bic tmp1, tmp1, #AT91_PMC_MOSCEN |
498 | orr tmp1, tmp1, #AT91_PMC_KEY |
499 | str tmp1, [pmc, #AT91_CKGR_MOR] |
500 | |
501 | /* Save RC oscillator state */ |
502 | ldr tmp1, [pmc, #AT91_PMC_SR] |
503 | str tmp1, .saved_osc_status |
504 | tst tmp1, #AT91_PMC_MOSCRCS |
505 | bne 1f |
506 | |
507 | /* Turn off RC oscillator */ |
508 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
509 | bic tmp1, tmp1, #AT91_PMC_MOSCRCEN |
510 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
511 | orr tmp1, tmp1, #AT91_PMC_KEY |
512 | str tmp1, [pmc, #AT91_CKGR_MOR] |
513 | |
514 | /* Wait main RC disabled done */ |
515 | 2: ldr tmp1, [pmc, #AT91_PMC_SR] |
516 | tst tmp1, #AT91_PMC_MOSCRCS |
517 | bne 2b |
518 | |
519 | /* Wait for interrupt */ |
520 | 1: at91_cpu_idle |
521 | |
522 | /* Check if ULP0 fast variant has been requested. */ |
523 | cmp tmp2, #AT91_PM_ULP0_FAST |
524 | bne 5f |
525 | |
526 | /* Set lowest prescaler for fast resume. */ |
527 | ldr tmp3, .mckr_offset |
528 | ldr tmp1, [pmc, tmp3] |
529 | bic tmp1, tmp1, #AT91_PMC_PRES |
530 | str tmp1, [pmc, tmp3] |
531 | |
532 | mov tmp3, #0 |
533 | wait_mckrdy tmp3 |
534 | b 6f |
535 | |
536 | 5: /* Restore RC oscillator state */ |
537 | ldr tmp1, .saved_osc_status |
538 | tst tmp1, #AT91_PMC_MOSCRCS |
539 | beq 4f |
540 | |
541 | /* Turn on RC oscillator */ |
542 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
543 | orr tmp1, tmp1, #AT91_PMC_MOSCRCEN |
544 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
545 | orr tmp1, tmp1, #AT91_PMC_KEY |
546 | str tmp1, [pmc, #AT91_CKGR_MOR] |
547 | |
548 | /* Wait main RC stabilization */ |
549 | 3: ldr tmp1, [pmc, #AT91_PMC_SR] |
550 | tst tmp1, #AT91_PMC_MOSCRCS |
551 | beq 3b |
552 | |
553 | /* Turn on the crystal oscillator */ |
554 | 4: ldr tmp1, [pmc, #AT91_CKGR_MOR] |
555 | orr tmp1, tmp1, #AT91_PMC_MOSCEN |
556 | orr tmp1, tmp1, #AT91_PMC_KEY |
557 | str tmp1, [pmc, #AT91_CKGR_MOR] |
558 | |
559 | wait_moscrdy |
560 | 6: |
561 | .endm |
562 | |
563 | /** |
564 | * Note: This procedure only applies on the platform which uses |
565 | * the external crystal oscillator as a main clock source. |
566 | */ |
567 | .macro at91_pm_ulp1_mode |
568 | ldr pmc, .pmc_base |
569 | ldr tmp2, .mckr_offset |
570 | mov tmp3, #0 |
571 | |
572 | /* Save RC oscillator state and check if it is enabled. */ |
573 | ldr tmp1, [pmc, #AT91_PMC_SR] |
574 | str tmp1, .saved_osc_status |
575 | tst tmp1, #AT91_PMC_MOSCRCS |
576 | bne 2f |
577 | |
578 | /* Enable RC oscillator */ |
579 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
580 | orr tmp1, tmp1, #AT91_PMC_MOSCRCEN |
581 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
582 | orr tmp1, tmp1, #AT91_PMC_KEY |
583 | str tmp1, [pmc, #AT91_CKGR_MOR] |
584 | |
585 | /* Wait main RC stabilization */ |
586 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
587 | tst tmp1, #AT91_PMC_MOSCRCS |
588 | beq 1b |
589 | |
590 | /* Switch the main clock source to 12-MHz RC oscillator */ |
591 | 2: ldr tmp1, [pmc, #AT91_CKGR_MOR] |
592 | bic tmp1, tmp1, #AT91_PMC_MOSCSEL |
593 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
594 | orr tmp1, tmp1, #AT91_PMC_KEY |
595 | str tmp1, [pmc, #AT91_CKGR_MOR] |
596 | |
597 | wait_moscsels |
598 | |
599 | /* Disable the crystal oscillator */ |
600 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
601 | bic tmp1, tmp1, #AT91_PMC_MOSCEN |
602 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
603 | orr tmp1, tmp1, #AT91_PMC_KEY |
604 | str tmp1, [pmc, #AT91_CKGR_MOR] |
605 | |
606 | /* Switch the master clock source to main clock */ |
607 | ldr tmp1, [pmc, tmp2] |
608 | bic tmp1, tmp1, #AT91_PMC_CSS |
609 | orr tmp1, tmp1, #AT91_PMC_CSS_MAIN |
610 | str tmp1, [pmc, tmp2] |
611 | |
612 | wait_mckrdy tmp3 |
613 | |
614 | /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ |
615 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
616 | orr tmp1, tmp1, #AT91_PMC_WAITMODE |
617 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
618 | orr tmp1, tmp1, #AT91_PMC_KEY |
619 | str tmp1, [pmc, #AT91_CKGR_MOR] |
620 | |
621 | /* Quirk for SAM9X60's PMC */ |
622 | nop |
623 | nop |
624 | |
625 | wait_mckrdy tmp3 |
626 | |
627 | /* Enable the crystal oscillator */ |
628 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
629 | orr tmp1, tmp1, #AT91_PMC_MOSCEN |
630 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
631 | orr tmp1, tmp1, #AT91_PMC_KEY |
632 | str tmp1, [pmc, #AT91_CKGR_MOR] |
633 | |
634 | wait_moscrdy |
635 | |
636 | /* Switch the master clock source to slow clock */ |
637 | ldr tmp1, [pmc, tmp2] |
638 | bic tmp1, tmp1, #AT91_PMC_CSS |
639 | str tmp1, [pmc, tmp2] |
640 | |
641 | wait_mckrdy tmp3 |
642 | |
643 | /* Switch main clock source to crystal oscillator */ |
644 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
645 | orr tmp1, tmp1, #AT91_PMC_MOSCSEL |
646 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
647 | orr tmp1, tmp1, #AT91_PMC_KEY |
648 | str tmp1, [pmc, #AT91_CKGR_MOR] |
649 | |
650 | wait_moscsels |
651 | |
652 | /* Switch the master clock source to main clock */ |
653 | ldr tmp1, [pmc, tmp2] |
654 | bic tmp1, tmp1, #AT91_PMC_CSS |
655 | orr tmp1, tmp1, #AT91_PMC_CSS_MAIN |
656 | str tmp1, [pmc, tmp2] |
657 | |
658 | wait_mckrdy tmp3 |
659 | |
660 | /* Restore RC oscillator state */ |
661 | ldr tmp1, .saved_osc_status |
662 | tst tmp1, #AT91_PMC_MOSCRCS |
663 | bne 3f |
664 | |
665 | /* Disable RC oscillator */ |
666 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
667 | bic tmp1, tmp1, #AT91_PMC_MOSCRCEN |
668 | bic tmp1, tmp1, #AT91_PMC_KEY_MASK |
669 | orr tmp1, tmp1, #AT91_PMC_KEY |
670 | str tmp1, [pmc, #AT91_CKGR_MOR] |
671 | |
672 | /* Wait RC oscillator disable done */ |
673 | 4: ldr tmp1, [pmc, #AT91_PMC_SR] |
674 | tst tmp1, #AT91_PMC_MOSCRCS |
675 | bne 4b |
676 | |
677 | 3: |
678 | .endm |
679 | |
680 | .macro at91_plla_disable |
681 | /* Save PLLA setting and disable it */ |
682 | ldr tmp1, .pmc_version |
683 | cmp tmp1, #AT91_PMC_V1 |
684 | beq 1f |
685 | |
686 | #ifdef CONFIG_HAVE_AT91_SAM9X60_PLL |
687 | /* Save PLLA settings. */ |
688 | ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] |
689 | bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID |
690 | str tmp2, [pmc, #AT91_PMC_PLL_UPDT] |
691 | |
692 | /* save div. */ |
693 | mov tmp1, #0 |
694 | ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] |
695 | bic tmp2, tmp2, #0xffffff00 |
696 | orr tmp1, tmp1, tmp2 |
697 | |
698 | /* save mul. */ |
699 | ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] |
700 | bic tmp2, tmp2, #0xffffff |
701 | orr tmp1, tmp1, tmp2 |
702 | str tmp1, .saved_pllar |
703 | |
704 | /* step 2. */ |
705 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
706 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
707 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
708 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
709 | |
710 | /* step 3. */ |
711 | ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
712 | bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK |
713 | orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL |
714 | str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
715 | |
716 | /* step 4. */ |
717 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
718 | orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
719 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
720 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
721 | |
722 | /* step 5. */ |
723 | ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
724 | bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL |
725 | str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
726 | |
727 | /* step 7. */ |
728 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
729 | orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
730 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
731 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
732 | |
733 | b 2f |
734 | #endif |
735 | |
736 | 1: /* Save PLLA setting and disable it */ |
737 | ldr tmp1, [pmc, #AT91_CKGR_PLLAR] |
738 | str tmp1, .saved_pllar |
739 | |
740 | /* Disable PLLA. */ |
741 | mov tmp1, #AT91_PMC_PLLCOUNT |
742 | orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ |
743 | str tmp1, [pmc, #AT91_CKGR_PLLAR] |
744 | 2: |
745 | .endm |
746 | |
747 | .macro at91_plla_enable |
748 | ldr tmp2, .saved_pllar |
749 | ldr tmp3, .pmc_version |
750 | cmp tmp3, #AT91_PMC_V1 |
751 | beq 4f |
752 | |
753 | #ifdef CONFIG_HAVE_AT91_SAM9X60_PLL |
754 | /* step 1. */ |
755 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
756 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
757 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
758 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
759 | |
760 | /* step 2. */ |
761 | ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA |
762 | str tmp1, [pmc, #AT91_PMC_PLL_ACR] |
763 | |
764 | /* step 3. */ |
765 | ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] |
766 | mov tmp3, tmp2 |
767 | bic tmp3, tmp3, #0xffffff |
768 | orr tmp1, tmp1, tmp3 |
769 | str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] |
770 | |
771 | /* step 8. */ |
772 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
773 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
774 | orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
775 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
776 | |
777 | /* step 9. */ |
778 | ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
779 | orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK |
780 | orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL |
781 | orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK |
782 | bic tmp1, tmp1, #0xff |
783 | mov tmp3, tmp2 |
784 | bic tmp3, tmp3, #0xffffff00 |
785 | orr tmp1, tmp1, tmp3 |
786 | str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] |
787 | |
788 | /* step 10. */ |
789 | ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
790 | orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE |
791 | bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID |
792 | str tmp1, [pmc, #AT91_PMC_PLL_UPDT] |
793 | |
794 | /* step 11. */ |
795 | 3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] |
796 | tst tmp1, #0x1 |
797 | beq 3b |
798 | b 2f |
799 | #endif |
800 | |
801 | /* Restore PLLA setting */ |
802 | 4: str tmp2, [pmc, #AT91_CKGR_PLLAR] |
803 | |
804 | /* Enable PLLA. */ |
805 | tst tmp2, #(AT91_PMC_MUL & 0xff0000) |
806 | bne 1f |
807 | tst tmp2, #(AT91_PMC_MUL & ~0xff0000) |
808 | beq 2f |
809 | |
810 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
811 | tst tmp1, #AT91_PMC_LOCKA |
812 | beq 1b |
813 | 2: |
814 | .endm |
815 | |
816 | /** |
817 | * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock |
818 | * |
819 | * Side effects: overwrites tmp1, tmp2 |
820 | */ |
821 | .macro at91_mckx_ps_enable |
822 | #ifdef CONFIG_SOC_SAMA7 |
823 | ldr pmc, .pmc_base |
824 | |
825 | /* There are 4 MCKs we need to handle: MCK1..4 */ |
826 | mov tmp1, #1 |
827 | e_loop: cmp tmp1, #5 |
828 | beq e_done |
829 | |
830 | /* Write MCK ID to retrieve the settings. */ |
831 | str tmp1, [pmc, #AT91_PMC_MCR_V2] |
832 | ldr tmp2, [pmc, #AT91_PMC_MCR_V2] |
833 | |
834 | e_save_mck1: |
835 | cmp tmp1, #1 |
836 | bne e_save_mck2 |
837 | str tmp2, .saved_mck1 |
838 | b e_ps |
839 | |
840 | e_save_mck2: |
841 | cmp tmp1, #2 |
842 | bne e_save_mck3 |
843 | str tmp2, .saved_mck2 |
844 | b e_ps |
845 | |
846 | e_save_mck3: |
847 | cmp tmp1, #3 |
848 | bne e_save_mck4 |
849 | str tmp2, .saved_mck3 |
850 | b e_ps |
851 | |
852 | e_save_mck4: |
853 | str tmp2, .saved_mck4 |
854 | |
855 | e_ps: |
856 | /* Use CSS=MAINCK and DIV=1. */ |
857 | bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS |
858 | bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV |
859 | orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MAINCK |
860 | orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV1 |
861 | str tmp2, [pmc, #AT91_PMC_MCR_V2] |
862 | |
863 | wait_mckrdy tmp1 |
864 | |
865 | add tmp1, tmp1, #1 |
866 | b e_loop |
867 | |
868 | e_done: |
869 | #endif |
870 | .endm |
871 | |
872 | /** |
873 | * at91_mckx_ps_restore: restore MCK1..4 settings |
874 | * |
875 | * Side effects: overwrites tmp1, tmp2 |
876 | */ |
877 | .macro at91_mckx_ps_restore |
878 | #ifdef CONFIG_SOC_SAMA7 |
879 | ldr pmc, .pmc_base |
880 | |
881 | /* There are 4 MCKs we need to handle: MCK1..4 */ |
882 | mov tmp1, #1 |
883 | r_loop: cmp tmp1, #5 |
884 | beq r_done |
885 | |
886 | r_save_mck1: |
887 | cmp tmp1, #1 |
888 | bne r_save_mck2 |
889 | ldr tmp2, .saved_mck1 |
890 | b r_ps |
891 | |
892 | r_save_mck2: |
893 | cmp tmp1, #2 |
894 | bne r_save_mck3 |
895 | ldr tmp2, .saved_mck2 |
896 | b r_ps |
897 | |
898 | r_save_mck3: |
899 | cmp tmp1, #3 |
900 | bne r_save_mck4 |
901 | ldr tmp2, .saved_mck3 |
902 | b r_ps |
903 | |
904 | r_save_mck4: |
905 | ldr tmp2, .saved_mck4 |
906 | |
907 | r_ps: |
908 | /* Write MCK ID to retrieve the settings. */ |
909 | str tmp1, [pmc, #AT91_PMC_MCR_V2] |
910 | ldr tmp3, [pmc, #AT91_PMC_MCR_V2] |
911 | |
912 | /* We need to restore CSS and DIV. */ |
913 | bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS |
914 | bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV |
915 | orr tmp3, tmp3, tmp2 |
916 | bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK |
917 | orr tmp3, tmp3, tmp1 |
918 | orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD |
919 | str tmp2, [pmc, #AT91_PMC_MCR_V2] |
920 | |
921 | wait_mckrdy tmp1 |
922 | |
923 | add tmp1, tmp1, #1 |
924 | b r_loop |
925 | r_done: |
926 | #endif |
927 | .endm |
928 | |
929 | .macro at91_ulp_mode |
930 | at91_mckx_ps_enable |
931 | |
932 | ldr pmc, .pmc_base |
933 | ldr tmp2, .mckr_offset |
934 | ldr tmp3, .pm_mode |
935 | |
936 | /* Save Master clock setting */ |
937 | ldr tmp1, [pmc, tmp2] |
938 | str tmp1, .saved_mckr |
939 | |
940 | /* |
941 | * Set master clock source to: |
942 | * - MAINCK if using ULP0 fast variant |
943 | * - slow clock, otherwise |
944 | */ |
945 | bic tmp1, tmp1, #AT91_PMC_CSS |
946 | cmp tmp3, #AT91_PM_ULP0_FAST |
947 | bne save_mck |
948 | orr tmp1, tmp1, #AT91_PMC_CSS_MAIN |
949 | save_mck: |
950 | str tmp1, [pmc, tmp2] |
951 | |
952 | mov tmp3, #0 |
953 | wait_mckrdy tmp3 |
954 | |
955 | at91_plla_disable |
956 | |
957 | /* Enable low power mode for 2.5V regulator. */ |
958 | at91_2_5V_reg_set_low_power 1 |
959 | |
960 | ldr tmp3, .pm_mode |
961 | cmp tmp3, #AT91_PM_ULP1 |
962 | beq ulp1_mode |
963 | |
964 | at91_pm_ulp0_mode |
965 | b ulp_exit |
966 | |
967 | ulp1_mode: |
968 | at91_pm_ulp1_mode |
969 | b ulp_exit |
970 | |
971 | ulp_exit: |
972 | /* Disable low power mode for 2.5V regulator. */ |
973 | at91_2_5V_reg_set_low_power 0 |
974 | |
975 | ldr pmc, .pmc_base |
976 | |
977 | at91_plla_enable |
978 | |
979 | /* |
980 | * Restore master clock setting |
981 | */ |
982 | ldr tmp1, .mckr_offset |
983 | ldr tmp2, .saved_mckr |
984 | str tmp2, [pmc, tmp1] |
985 | |
986 | mov tmp3, #0 |
987 | wait_mckrdy tmp3 |
988 | |
989 | at91_mckx_ps_restore |
990 | .endm |
991 | |
992 | .macro at91_backup_mode |
993 | /* Switch the master clock source to slow clock. */ |
994 | ldr pmc, .pmc_base |
995 | ldr tmp2, .mckr_offset |
996 | ldr tmp1, [pmc, tmp2] |
997 | bic tmp1, tmp1, #AT91_PMC_CSS |
998 | str tmp1, [pmc, tmp2] |
999 | |
1000 | mov tmp3, #0 |
1001 | wait_mckrdy tmp3 |
1002 | |
1003 | /*BUMEN*/ |
1004 | ldr r0, .sfrbu |
1005 | mov tmp1, #0x1 |
1006 | str tmp1, [r0, #0x10] |
1007 | |
1008 | /* Wait for it. */ |
1009 | 1: ldr tmp1, [r0, #0x10] |
1010 | tst tmp1, #0x1 |
1011 | beq 1b |
1012 | |
1013 | /* Shutdown */ |
1014 | ldr r0, .shdwc |
1015 | mov tmp1, #0xA5000000 |
1016 | add tmp1, tmp1, #0x1 |
1017 | at91_backup_set_lpm tmp1 |
1018 | str tmp1, [r0, #0] |
1019 | .endm |
1020 | |
1021 | /* |
1022 | * void at91_suspend_sram_fn(struct at91_pm_data*) |
1023 | * @input param: |
1024 | * @r0: base address of struct at91_pm_data |
1025 | */ |
1026 | /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ |
1027 | .align 3 |
1028 | ENTRY(at91_pm_suspend_in_sram) |
1029 | /* Save registers on stack */ |
1030 | stmfd sp!, {r4 - r12, lr} |
1031 | |
1032 | /* Drain write buffer */ |
1033 | mov tmp1, #0 |
1034 | mcr p15, 0, tmp1, c7, c10, 4 |
1035 | |
1036 | /* Flush tlb. */ |
1037 | mov r4, #0 |
1038 | mcr p15, 0, r4, c8, c7, 0 |
1039 | |
1040 | ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] |
1041 | str tmp1, .mckr_offset |
1042 | ldr tmp1, [r0, #PM_DATA_PMC_VERSION] |
1043 | str tmp1, .pmc_version |
1044 | ldr tmp1, [r0, #PM_DATA_MEMCTRL] |
1045 | str tmp1, .memtype |
1046 | ldr tmp1, [r0, #PM_DATA_MODE] |
1047 | str tmp1, .pm_mode |
1048 | |
1049 | /* |
1050 | * ldrne below are here to preload their address in the TLB as access |
1051 | * to RAM may be limited while in self-refresh. |
1052 | */ |
1053 | ldr tmp1, [r0, #PM_DATA_PMC] |
1054 | str tmp1, .pmc_base |
1055 | cmp tmp1, #0 |
1056 | ldrne tmp2, [tmp1, #0] |
1057 | |
1058 | ldr tmp1, [r0, #PM_DATA_RAMC0] |
1059 | str tmp1, .sramc_base |
1060 | cmp tmp1, #0 |
1061 | ldrne tmp2, [tmp1, #0] |
1062 | |
1063 | ldr tmp1, [r0, #PM_DATA_RAMC1] |
1064 | str tmp1, .sramc1_base |
1065 | cmp tmp1, #0 |
1066 | ldrne tmp2, [tmp1, #0] |
1067 | |
1068 | #ifndef CONFIG_SOC_SAM_V4_V5 |
1069 | /* ldrne below are here to preload their address in the TLB */ |
1070 | ldr tmp1, [r0, #PM_DATA_RAMC_PHY] |
1071 | str tmp1, .sramc_phy_base |
1072 | cmp tmp1, #0 |
1073 | ldrne tmp2, [tmp1, #0] |
1074 | |
1075 | ldr tmp1, [r0, #PM_DATA_SHDWC] |
1076 | str tmp1, .shdwc |
1077 | cmp tmp1, #0 |
1078 | ldrne tmp2, [tmp1, #0] |
1079 | |
1080 | ldr tmp1, [r0, #PM_DATA_SFRBU] |
1081 | str tmp1, .sfrbu |
1082 | cmp tmp1, #0 |
1083 | ldrne tmp2, [tmp1, #0x10] |
1084 | #endif |
1085 | |
1086 | /* Active the self-refresh mode */ |
1087 | at91_sramc_self_refresh_ena |
1088 | |
1089 | ldr r0, .pm_mode |
1090 | cmp r0, #AT91_PM_STANDBY |
1091 | beq standby |
1092 | cmp r0, #AT91_PM_BACKUP |
1093 | beq backup_mode |
1094 | |
1095 | at91_ulp_mode |
1096 | b exit_suspend |
1097 | |
1098 | standby: |
1099 | /* Wait for interrupt */ |
1100 | ldr pmc, .pmc_base |
1101 | at91_cpu_idle |
1102 | b exit_suspend |
1103 | |
1104 | backup_mode: |
1105 | at91_backup_mode |
1106 | |
1107 | exit_suspend: |
1108 | /* Exit the self-refresh mode */ |
1109 | at91_sramc_self_refresh_dis |
1110 | |
1111 | /* Restore registers, and return */ |
1112 | ldmfd sp!, {r4 - r12, pc} |
1113 | ENDPROC(at91_pm_suspend_in_sram) |
1114 | |
1115 | .pmc_base: |
1116 | .word 0 |
1117 | .sramc_base: |
1118 | .word 0 |
1119 | .sramc1_base: |
1120 | .word 0 |
1121 | .sramc_phy_base: |
1122 | .word 0 |
1123 | .shdwc: |
1124 | .word 0 |
1125 | .sfrbu: |
1126 | .word 0 |
1127 | .memtype: |
1128 | .word 0 |
1129 | .pm_mode: |
1130 | .word 0 |
1131 | .mckr_offset: |
1132 | .word 0 |
1133 | .pmc_version: |
1134 | .word 0 |
1135 | .saved_mckr: |
1136 | .word 0 |
1137 | .saved_pllar: |
1138 | .word 0 |
1139 | .saved_sam9_lpr: |
1140 | .word 0 |
1141 | .saved_sam9_lpr1: |
1142 | .word 0 |
1143 | .saved_sam9_mdr: |
1144 | .word 0 |
1145 | .saved_sam9_mdr1: |
1146 | .word 0 |
1147 | .saved_osc_status: |
1148 | .word 0 |
1149 | #ifdef CONFIG_SOC_SAMA7 |
1150 | .saved_mck1: |
1151 | .word 0 |
1152 | .saved_mck2: |
1153 | .word 0 |
1154 | .saved_mck3: |
1155 | .word 0 |
1156 | .saved_mck4: |
1157 | .word 0 |
1158 | #endif |
1159 | |
1160 | ENTRY(at91_pm_suspend_in_sram_sz) |
1161 | .word .-at91_pm_suspend_in_sram |
1162 | |