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