hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/arm/mach-at91/pm_suspend.S
....@@ -1,3 +1,4 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * arch/arm/mach-at91/pm_slow_clock.S
34 *
....@@ -5,16 +6,11 @@
56 *
67 * AT91SAM9 support:
78 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
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
- *
139 */
1410 #include <linux/linkage.h>
1511 #include <linux/clk/at91_pmc.h>
1612 #include "pm.h"
17
-#include "generated/at91_pm_data-offsets.h"
13
+#include "pm_data-offsets.h"
1814
1915 #define SRAMC_SELF_FRESH_ACTIVE 0x01
2016 #define SRAMC_SELF_FRESH_EXIT 0x00
....@@ -22,6 +18,7 @@
2218 pmc .req r0
2319 tmp1 .req r4
2420 tmp2 .req r5
21
+tmp3 .req r6
2522
2623 /*
2724 * Wait until master clock is ready (after switching master clock source)
....@@ -47,15 +44,6 @@
4744 .macro wait_moscsels
4845 1: ldr tmp1, [pmc, #AT91_PMC_SR]
4946 tst tmp1, #AT91_PMC_MOSCSELS
50
- beq 1b
51
- .endm
52
-
53
-/*
54
- * Wait until PLLA has locked.
55
- */
56
- .macro wait_pllalock
57
-1: ldr tmp1, [pmc, #AT91_PMC_SR]
58
- tst tmp1, #AT91_PMC_LOCKA
5947 beq 1b
6048 .endm
6149
....@@ -106,13 +94,17 @@
10694 str tmp1, .memtype
10795 ldr tmp1, [r0, #PM_DATA_MODE]
10896 str tmp1, .pm_mode
97
+ ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
98
+ str tmp1, .mckr_offset
99
+ ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
100
+ str tmp1, .pmc_version
109101 /* Both ldrne below are here to preload their address in the TLB */
110102 ldr tmp1, [r0, #PM_DATA_SHDWC]
111103 str tmp1, .shdwc
112104 cmp tmp1, #0
113105 ldrne tmp2, [tmp1, #0]
114106 ldr tmp1, [r0, #PM_DATA_SFRBU]
115
- str tmp1, .sfr
107
+ str tmp1, .sfrbu
116108 cmp tmp1, #0
117109 ldrne tmp2, [tmp1, #0x10]
118110
....@@ -149,8 +141,17 @@
149141 ENDPROC(at91_pm_suspend_in_sram)
150142
151143 ENTRY(at91_backup_mode)
144
+ /* Switch the master clock source to slow clock. */
145
+ ldr pmc, .pmc_base
146
+ ldr tmp2, .mckr_offset
147
+ ldr tmp1, [pmc, tmp2]
148
+ bic tmp1, tmp1, #AT91_PMC_CSS
149
+ str tmp1, [pmc, tmp2]
150
+
151
+ wait_mckrdy
152
+
152153 /*BUMEN*/
153
- ldr r0, .sfr
154
+ ldr r0, .sfrbu
154155 mov tmp1, #0x1
155156 str tmp1, [r0, #0x10]
156157
....@@ -163,23 +164,85 @@
163164
164165 .macro at91_pm_ulp0_mode
165166 ldr pmc, .pmc_base
167
+ ldr tmp2, .pm_mode
168
+ ldr tmp3, .mckr_offset
166169
170
+ /* Check if ULP0 fast variant has been requested. */
171
+ cmp tmp2, #AT91_PM_ULP0_FAST
172
+ bne 0f
173
+
174
+ /* Set highest prescaler for power saving */
175
+ ldr tmp1, [pmc, tmp3]
176
+ bic tmp1, tmp1, #AT91_PMC_PRES
177
+ orr tmp1, tmp1, #AT91_PMC_PRES_64
178
+ str tmp1, [pmc, tmp3]
179
+ wait_mckrdy
180
+ b 1f
181
+
182
+0:
167183 /* Turn off the crystal oscillator */
168184 ldr tmp1, [pmc, #AT91_CKGR_MOR]
169185 bic tmp1, tmp1, #AT91_PMC_MOSCEN
170186 orr tmp1, tmp1, #AT91_PMC_KEY
171187 str tmp1, [pmc, #AT91_CKGR_MOR]
172188
189
+ /* Save RC oscillator state */
190
+ ldr tmp1, [pmc, #AT91_PMC_SR]
191
+ str tmp1, .saved_osc_status
192
+ tst tmp1, #AT91_PMC_MOSCRCS
193
+ bne 1f
194
+
195
+ /* Turn off RC oscillator */
196
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
197
+ bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
198
+ bic tmp1, tmp1, #AT91_PMC_KEY_MASK
199
+ orr tmp1, tmp1, #AT91_PMC_KEY
200
+ str tmp1, [pmc, #AT91_CKGR_MOR]
201
+
202
+ /* Wait main RC disabled done */
203
+2: ldr tmp1, [pmc, #AT91_PMC_SR]
204
+ tst tmp1, #AT91_PMC_MOSCRCS
205
+ bne 2b
206
+
173207 /* Wait for interrupt */
174
- at91_cpu_idle
208
+1: at91_cpu_idle
209
+
210
+ /* Check if ULP0 fast variant has been requested. */
211
+ cmp tmp2, #AT91_PM_ULP0_FAST
212
+ bne 5f
213
+
214
+ /* Set lowest prescaler for fast resume. */
215
+ ldr tmp1, [pmc, tmp3]
216
+ bic tmp1, tmp1, #AT91_PMC_PRES
217
+ str tmp1, [pmc, tmp3]
218
+ wait_mckrdy
219
+ b 6f
220
+
221
+5: /* Restore RC oscillator state */
222
+ ldr tmp1, .saved_osc_status
223
+ tst tmp1, #AT91_PMC_MOSCRCS
224
+ beq 4f
225
+
226
+ /* Turn on RC oscillator */
227
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
228
+ orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
229
+ bic tmp1, tmp1, #AT91_PMC_KEY_MASK
230
+ orr tmp1, tmp1, #AT91_PMC_KEY
231
+ str tmp1, [pmc, #AT91_CKGR_MOR]
232
+
233
+ /* Wait main RC stabilization */
234
+3: ldr tmp1, [pmc, #AT91_PMC_SR]
235
+ tst tmp1, #AT91_PMC_MOSCRCS
236
+ beq 3b
175237
176238 /* Turn on the crystal oscillator */
177
- ldr tmp1, [pmc, #AT91_CKGR_MOR]
239
+4: ldr tmp1, [pmc, #AT91_CKGR_MOR]
178240 orr tmp1, tmp1, #AT91_PMC_MOSCEN
179241 orr tmp1, tmp1, #AT91_PMC_KEY
180242 str tmp1, [pmc, #AT91_CKGR_MOR]
181243
182244 wait_moscrdy
245
+6:
183246 .endm
184247
185248 /**
....@@ -188,9 +251,28 @@
188251 */
189252 .macro at91_pm_ulp1_mode
190253 ldr pmc, .pmc_base
254
+ ldr tmp2, .mckr_offset
255
+
256
+ /* Save RC oscillator state and check if it is enabled. */
257
+ ldr tmp1, [pmc, #AT91_PMC_SR]
258
+ str tmp1, .saved_osc_status
259
+ tst tmp1, #AT91_PMC_MOSCRCS
260
+ bne 2f
261
+
262
+ /* Enable RC oscillator */
263
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
264
+ orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
265
+ bic tmp1, tmp1, #AT91_PMC_KEY_MASK
266
+ orr tmp1, tmp1, #AT91_PMC_KEY
267
+ str tmp1, [pmc, #AT91_CKGR_MOR]
268
+
269
+ /* Wait main RC stabilization */
270
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
271
+ tst tmp1, #AT91_PMC_MOSCRCS
272
+ beq 1b
191273
192274 /* Switch the main clock source to 12-MHz RC oscillator */
193
- ldr tmp1, [pmc, #AT91_CKGR_MOR]
275
+2: ldr tmp1, [pmc, #AT91_CKGR_MOR]
194276 bic tmp1, tmp1, #AT91_PMC_MOSCSEL
195277 bic tmp1, tmp1, #AT91_PMC_KEY_MASK
196278 orr tmp1, tmp1, #AT91_PMC_KEY
....@@ -206,10 +288,10 @@
206288 str tmp1, [pmc, #AT91_CKGR_MOR]
207289
208290 /* Switch the master clock source to main clock */
209
- ldr tmp1, [pmc, #AT91_PMC_MCKR]
291
+ ldr tmp1, [pmc, tmp2]
210292 bic tmp1, tmp1, #AT91_PMC_CSS
211293 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
212
- str tmp1, [pmc, #AT91_PMC_MCKR]
294
+ str tmp1, [pmc, tmp2]
213295
214296 wait_mckrdy
215297
....@@ -236,9 +318,9 @@
236318 wait_moscrdy
237319
238320 /* Switch the master clock source to slow clock */
239
- ldr tmp1, [pmc, #AT91_PMC_MCKR]
321
+ ldr tmp1, [pmc, tmp2]
240322 bic tmp1, tmp1, #AT91_PMC_CSS
241
- str tmp1, [pmc, #AT91_PMC_MCKR]
323
+ str tmp1, [pmc, tmp2]
242324
243325 wait_mckrdy
244326
....@@ -252,39 +334,195 @@
252334 wait_moscsels
253335
254336 /* Switch the master clock source to main clock */
255
- ldr tmp1, [pmc, #AT91_PMC_MCKR]
337
+ ldr tmp1, [pmc, tmp2]
256338 bic tmp1, tmp1, #AT91_PMC_CSS
257339 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
258
- str tmp1, [pmc, #AT91_PMC_MCKR]
340
+ str tmp1, [pmc, tmp2]
259341
260342 wait_mckrdy
343
+
344
+ /* Restore RC oscillator state */
345
+ ldr tmp1, .saved_osc_status
346
+ tst tmp1, #AT91_PMC_MOSCRCS
347
+ bne 3f
348
+
349
+ /* Disable RC oscillator */
350
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
351
+ bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
352
+ bic tmp1, tmp1, #AT91_PMC_KEY_MASK
353
+ orr tmp1, tmp1, #AT91_PMC_KEY
354
+ str tmp1, [pmc, #AT91_CKGR_MOR]
355
+
356
+ /* Wait RC oscillator disable done */
357
+4: ldr tmp1, [pmc, #AT91_PMC_SR]
358
+ tst tmp1, #AT91_PMC_MOSCRCS
359
+ bne 4b
360
+
361
+3:
362
+.endm
363
+
364
+.macro at91_plla_disable
365
+ /* Save PLLA setting and disable it */
366
+ ldr tmp1, .pmc_version
367
+ cmp tmp1, #AT91_PMC_V1
368
+ beq 1f
369
+
370
+#ifdef CONFIG_SOC_SAM9X60
371
+ /* Save PLLA settings. */
372
+ ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]
373
+ bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
374
+ str tmp2, [pmc, #AT91_PMC_PLL_UPDT]
375
+
376
+ /* save div. */
377
+ mov tmp1, #0
378
+ ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
379
+ bic tmp2, tmp2, #0xffffff00
380
+ orr tmp1, tmp1, tmp2
381
+
382
+ /* save mul. */
383
+ ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
384
+ bic tmp2, tmp2, #0xffffff
385
+ orr tmp1, tmp1, tmp2
386
+ str tmp1, .saved_pllar
387
+
388
+ /* step 2. */
389
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
390
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
391
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
392
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
393
+
394
+ /* step 3. */
395
+ ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
396
+ bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
397
+ orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
398
+ str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
399
+
400
+ /* step 4. */
401
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
402
+ orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
403
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
404
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
405
+
406
+ /* step 5. */
407
+ ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
408
+ bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
409
+ str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
410
+
411
+ /* step 7. */
412
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
413
+ orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
414
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
415
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
416
+
417
+ b 2f
418
+#endif
419
+
420
+1: /* Save PLLA setting and disable it */
421
+ ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
422
+ str tmp1, .saved_pllar
423
+
424
+ /* Disable PLLA. */
425
+ mov tmp1, #AT91_PMC_PLLCOUNT
426
+ orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
427
+ str tmp1, [pmc, #AT91_CKGR_PLLAR]
428
+2:
429
+.endm
430
+
431
+.macro at91_plla_enable
432
+ ldr tmp2, .saved_pllar
433
+ ldr tmp3, .pmc_version
434
+ cmp tmp3, #AT91_PMC_V1
435
+ beq 4f
436
+
437
+#ifdef CONFIG_SOC_SAM9X60
438
+ /* step 1. */
439
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
440
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
441
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
442
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
443
+
444
+ /* step 2. */
445
+ ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA
446
+ str tmp1, [pmc, #AT91_PMC_PLL_ACR]
447
+
448
+ /* step 3. */
449
+ ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
450
+ mov tmp3, tmp2
451
+ bic tmp3, tmp3, #0xffffff
452
+ orr tmp1, tmp1, tmp3
453
+ str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
454
+
455
+ /* step 8. */
456
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
457
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
458
+ orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
459
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
460
+
461
+ /* step 9. */
462
+ ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
463
+ orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
464
+ orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
465
+ orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
466
+ bic tmp1, tmp1, #0xff
467
+ mov tmp3, tmp2
468
+ bic tmp3, tmp3, #0xffffff00
469
+ orr tmp1, tmp1, tmp3
470
+ str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
471
+
472
+ /* step 10. */
473
+ ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
474
+ orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
475
+ bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
476
+ str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
477
+
478
+ /* step 11. */
479
+3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]
480
+ tst tmp1, #0x1
481
+ beq 3b
482
+ b 2f
483
+#endif
484
+
485
+ /* Restore PLLA setting */
486
+4: str tmp2, [pmc, #AT91_CKGR_PLLAR]
487
+
488
+ /* Enable PLLA. */
489
+ tst tmp2, #(AT91_PMC_MUL & 0xff0000)
490
+ bne 1f
491
+ tst tmp2, #(AT91_PMC_MUL & ~0xff0000)
492
+ beq 2f
493
+
494
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
495
+ tst tmp1, #AT91_PMC_LOCKA
496
+ beq 1b
497
+2:
261498 .endm
262499
263500 ENTRY(at91_ulp_mode)
264501 ldr pmc, .pmc_base
502
+ ldr tmp2, .mckr_offset
503
+ ldr tmp3, .pm_mode
265504
266505 /* Save Master clock setting */
267
- ldr tmp1, [pmc, #AT91_PMC_MCKR]
506
+ ldr tmp1, [pmc, tmp2]
268507 str tmp1, .saved_mckr
269508
270509 /*
271
- * Set the Master clock source to slow clock
510
+ * Set master clock source to:
511
+ * - MAINCK if using ULP0 fast variant
512
+ * - slow clock, otherwise
272513 */
273514 bic tmp1, tmp1, #AT91_PMC_CSS
274
- str tmp1, [pmc, #AT91_PMC_MCKR]
515
+ cmp tmp3, #AT91_PM_ULP0_FAST
516
+ bne save_mck
517
+ orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
518
+save_mck:
519
+ str tmp1, [pmc, tmp2]
275520
276521 wait_mckrdy
277522
278
- /* Save PLLA setting and disable it */
279
- ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
280
- str tmp1, .saved_pllar
523
+ at91_plla_disable
281524
282
- mov tmp1, #AT91_PMC_PLLCOUNT
283
- orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
284
- str tmp1, [pmc, #AT91_CKGR_PLLAR]
285
-
286
- ldr r0, .pm_mode
287
- cmp r0, #AT91_PM_ULP1
525
+ cmp tmp3, #AT91_PM_ULP1
288526 beq ulp1_mode
289527
290528 at91_pm_ulp0_mode
....@@ -297,23 +535,14 @@
297535 ulp_exit:
298536 ldr pmc, .pmc_base
299537
300
- /* Restore PLLA setting */
301
- ldr tmp1, .saved_pllar
302
- str tmp1, [pmc, #AT91_CKGR_PLLAR]
303
-
304
- tst tmp1, #(AT91_PMC_MUL & 0xff0000)
305
- bne 3f
306
- tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
307
- beq 4f
308
-3:
309
- wait_pllalock
310
-4:
538
+ at91_plla_enable
311539
312540 /*
313541 * Restore master clock setting
314542 */
315
- ldr tmp1, .saved_mckr
316
- str tmp1, [pmc, #AT91_PMC_MCKR]
543
+ ldr tmp1, .mckr_offset
544
+ ldr tmp2, .saved_mckr
545
+ str tmp2, [pmc, tmp1]
317546
318547 wait_mckrdy
319548
....@@ -453,11 +682,15 @@
453682 .word 0
454683 .shdwc:
455684 .word 0
456
-.sfr:
685
+.sfrbu:
457686 .word 0
458687 .memtype:
459688 .word 0
460689 .pm_mode:
690
+ .word 0
691
+.mckr_offset:
692
+ .word 0
693
+.pmc_version:
461694 .word 0
462695 .saved_mckr:
463696 .word 0
....@@ -471,6 +704,8 @@
471704 .word 0
472705 .saved_sam9_mdr1:
473706 .word 0
707
+.saved_osc_status:
708
+ .word 0
474709
475710 ENTRY(at91_pm_suspend_in_sram_sz)
476711 .word .-at91_pm_suspend_in_sram