xref: /linux/arch/arm/mach-at91/pm_suspend.S (revision b91217d9124f7cef7d0f699f7ff6ea96423f29f8)
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
22pmc	.req	r0
23tmp1	.req	r4
24tmp2	.req	r5
25tmp3	.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
411:	mov	r7, #AT91_PMC_MCKRDY
422:	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
541:	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
651:	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
134sr_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
146sr_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
171sr_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
238sr_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
248sr_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
267sr_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
278sr_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
329sr_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
375sr_ena_no_2nd_ddrc:
376	b	sr_ena_exit
377
378	/*
379	 * SDRAMC Memory controller
380	 */
381sr_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
392sr_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
420sr_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
443sdramc_exit_sf:
444	/* SDRAMC Memory controller */
445	ldr	r3, .saved_sam9_lpr
446	str	r3, [r2, #AT91_SDRAMC_LPR]
447
448sr_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
4710:
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 */
4922:	ldr	tmp1, [pmc, #AT91_PMC_SR]
493	tst	tmp1, #AT91_PMC_MOSCRCS
494	bne	2b
495
496	/* Wait for interrupt */
4971:	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
5135:	/* 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 */
5263:	ldr	tmp1, [pmc, #AT91_PMC_SR]
527	tst	tmp1, #AT91_PMC_MOSCRCS
528	beq	3b
529
530	/* Turn on the crystal oscillator */
5314:	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
5376:
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 */
5631:	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 */
5682:	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 */
6504:	ldr	tmp1, [pmc, #AT91_PMC_SR]
651	tst	tmp1, #AT91_PMC_MOSCRCS
652	bne	4b
653
6543:
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
7171:	/* 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]
7252:
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. */
7763:	ldr	tmp1, [pmc, #AT91_PMC_PLL_ISR0]
777	tst	tmp1, #0x1
778	beq	3b
779	b	2f
780#endif
781
782	/* Restore PLLA setting */
7834:	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
7911:	ldr	tmp1, [pmc, #AT91_PMC_SR]
792	tst	tmp1, #AT91_PMC_LOCKA
793	beq	1b
7942:
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
809e_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
817e_save_mck1:
818	cmp	tmp1, #1
819	bne	e_save_mck2
820	str	tmp2, .saved_mck1
821	b	e_ps
822
823e_save_mck2:
824	cmp	tmp1, #2
825	bne	e_save_mck3
826	str	tmp2, .saved_mck2
827	b	e_ps
828
829e_save_mck3:
830	cmp	tmp1, #3
831	bne	e_save_mck4
832	str	tmp2, .saved_mck3
833	b	e_ps
834
835e_save_mck4:
836	cmp	tmp1, #4
837	bne	e_save_mck5
838	str	tmp2, .saved_mck4
839	b	e_ps
840
841e_save_mck5:
842	cmp	tmp1, #5
843	bne	e_save_mck6
844	str	tmp2, .saved_mck5
845	b	e_ps
846
847e_save_mck6:
848	cmp	tmp1, #6
849	bne	e_save_mck7
850	str	tmp2, .saved_mck6
851	b	e_ps
852
853e_save_mck7:
854	cmp	tmp1, #7
855	bne	e_save_mck8
856	str	tmp2, .saved_mck7
857	b	e_ps
858
859e_save_mck8:
860	cmp	tmp1, #8
861	bne	e_save_mck9
862	str	tmp2, .saved_mck8
863	b	e_ps
864
865e_save_mck9:
866	str	tmp2, .saved_mck9
867
868e_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
881e_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
897r_loop:
898	cmp	tmp1, tmp2
899	bgt	r_done
900
901r_save_mck1:
902	cmp	tmp1, #1
903	bne	r_save_mck2
904	ldr	tmp2, .saved_mck1
905	b	r_ps
906
907r_save_mck2:
908	cmp	tmp1, #2
909	bne	r_save_mck3
910	ldr	tmp2, .saved_mck2
911	b	r_ps
912
913r_save_mck3:
914	cmp	tmp1, #3
915	bne	r_save_mck4
916	ldr	tmp2, .saved_mck3
917	b	r_ps
918
919r_save_mck4:
920	cmp	tmp1, #4
921	bne	r_save_mck5
922	ldr	tmp2, .saved_mck4
923	b	r_ps
924
925r_save_mck5:
926	cmp	tmp1, #5
927	bne	r_save_mck6
928	ldr	tmp2, .saved_mck5
929	b	r_ps
930
931r_save_mck6:
932	cmp	tmp1, #6
933	bne	r_save_mck7
934	ldr	tmp2, .saved_mck6
935	b	r_ps
936
937r_save_mck7:
938	cmp	tmp1, #7
939	bne	r_save_mck8
940	ldr	tmp2, .saved_mck7
941	b	r_ps
942
943r_save_mck8:
944	cmp	tmp1, #8
945	bne	r_save_mck9
946	ldr	tmp2, .saved_mck8
947	b	r_ps
948
949r_save_mck9:
950	ldr	tmp2, .saved_mck9
951
952r_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
971r_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
995save_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
1010ulp1_mode:
1011	at91_pm_ulp1_mode
1012	b	ulp_exit
1013
1014ulp_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. */
10491:	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
1068ENTRY(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
1142standby:
1143	/* Wait for interrupt */
1144	ldr	pmc, .pmc_base
1145	at91_cpu_idle
1146	b	exit_suspend
1147
1148backup_mode:
1149	at91_backup_mode
1150
1151exit_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}
1157ENDPROC(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
1220ENTRY(at91_pm_suspend_in_sram_sz)
1221	.word .-at91_pm_suspend_in_sram
1222