xref: /openbmc/linux/arch/arm/mach-at91/pm_suspend.S (revision c606970d)
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#define	SRAMC_SELF_FRESH_ACTIVE		0x01
16#define	SRAMC_SELF_FRESH_EXIT		0x00
17
18pmc	.req	r0
19tmp1	.req	r4
20tmp2	.req	r5
21tmp3	.req	r6
22
23/*
24 * Wait until master clock is ready (after switching master clock source)
25 */
26	.macro wait_mckrdy
271:	ldr	tmp1, [pmc, #AT91_PMC_SR]
28	tst	tmp1, #AT91_PMC_MCKRDY
29	beq	1b
30	.endm
31
32/*
33 * Wait until master oscillator has stabilized.
34 */
35	.macro wait_moscrdy
361:	ldr	tmp1, [pmc, #AT91_PMC_SR]
37	tst	tmp1, #AT91_PMC_MOSCS
38	beq	1b
39	.endm
40
41/*
42 * Wait for main oscillator selection is done
43 */
44	.macro wait_moscsels
451:	ldr	tmp1, [pmc, #AT91_PMC_SR]
46	tst	tmp1, #AT91_PMC_MOSCSELS
47	beq	1b
48	.endm
49
50/*
51 * Put the processor to enter the idle state
52 */
53	.macro at91_cpu_idle
54
55#if defined(CONFIG_CPU_V7)
56	mov	tmp1, #AT91_PMC_PCK
57	str	tmp1, [pmc, #AT91_PMC_SCDR]
58
59	dsb
60
61	wfi		@ Wait For Interrupt
62#else
63	mcr	p15, 0, tmp1, c7, c0, 4
64#endif
65
66	.endm
67
68	.text
69
70	.arm
71
72/*
73 * void at91_suspend_sram_fn(struct at91_pm_data*)
74 * @input param:
75 * 	@r0: base address of struct at91_pm_data
76 */
77/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
78	.align 3
79ENTRY(at91_pm_suspend_in_sram)
80	/* Save registers on stack */
81	stmfd	sp!, {r4 - r12, lr}
82
83	/* Drain write buffer */
84	mov	tmp1, #0
85	mcr	p15, 0, tmp1, c7, c10, 4
86
87	ldr	tmp1, [r0, #PM_DATA_PMC]
88	str	tmp1, .pmc_base
89	ldr	tmp1, [r0, #PM_DATA_RAMC0]
90	str	tmp1, .sramc_base
91	ldr	tmp1, [r0, #PM_DATA_RAMC1]
92	str	tmp1, .sramc1_base
93	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
94	str	tmp1, .memtype
95	ldr	tmp1, [r0, #PM_DATA_MODE]
96	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
101	/* Both ldrne below are here to preload their address in the TLB */
102	ldr	tmp1, [r0, #PM_DATA_SHDWC]
103	str	tmp1, .shdwc
104	cmp	tmp1, #0
105	ldrne	tmp2, [tmp1, #0]
106	ldr	tmp1, [r0, #PM_DATA_SFRBU]
107	str	tmp1, .sfrbu
108	cmp	tmp1, #0
109	ldrne	tmp2, [tmp1, #0x10]
110
111	/* Active the self-refresh mode */
112	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
113	bl	at91_sramc_self_refresh
114
115	ldr	r0, .pm_mode
116	cmp	r0, #AT91_PM_STANDBY
117	beq	standby
118	cmp	r0, #AT91_PM_BACKUP
119	beq	backup_mode
120
121	bl	at91_ulp_mode
122	b	exit_suspend
123
124standby:
125	/* Wait for interrupt */
126	ldr	pmc, .pmc_base
127	at91_cpu_idle
128	b	exit_suspend
129
130backup_mode:
131	bl	at91_backup_mode
132	b	exit_suspend
133
134exit_suspend:
135	/* Exit the self-refresh mode */
136	mov	r0, #SRAMC_SELF_FRESH_EXIT
137	bl	at91_sramc_self_refresh
138
139	/* Restore registers, and return */
140	ldmfd	sp!, {r4 - r12, pc}
141ENDPROC(at91_pm_suspend_in_sram)
142
143ENTRY(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
153	/*BUMEN*/
154	ldr	r0, .sfrbu
155	mov	tmp1, #0x1
156	str	tmp1, [r0, #0x10]
157
158	/* Shutdown */
159	ldr	r0, .shdwc
160	mov	tmp1, #0xA5000000
161	add	tmp1, tmp1, #0x1
162	str	tmp1, [r0, #0]
163ENDPROC(at91_backup_mode)
164
165.macro at91_pm_ulp0_mode
166	ldr	pmc, .pmc_base
167	ldr	tmp2, .pm_mode
168	ldr	tmp3, .mckr_offset
169
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
1820:
183	/* Turn off the crystal oscillator */
184	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
185	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
186	orr	tmp1, tmp1, #AT91_PMC_KEY
187	str	tmp1, [pmc, #AT91_CKGR_MOR]
188
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 */
2032:	ldr	tmp1, [pmc, #AT91_PMC_SR]
204	tst	tmp1, #AT91_PMC_MOSCRCS
205	bne	2b
206
207	/* Wait for interrupt */
2081:	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
2215:	/* 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 */
2343:	ldr	tmp1, [pmc, #AT91_PMC_SR]
235	tst	tmp1, #AT91_PMC_MOSCRCS
236	beq	3b
237
238	/* Turn on the crystal oscillator */
2394:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
240	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
241	orr	tmp1, tmp1, #AT91_PMC_KEY
242	str	tmp1, [pmc, #AT91_CKGR_MOR]
243
244	wait_moscrdy
2456:
246.endm
247
248/**
249 * Note: This procedure only applies on the platform which uses
250 * the external crystal oscillator as a main clock source.
251 */
252.macro at91_pm_ulp1_mode
253	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 */
2701:	ldr	tmp1, [pmc, #AT91_PMC_SR]
271	tst	tmp1, #AT91_PMC_MOSCRCS
272	beq	1b
273
274	/* Switch the main clock source to 12-MHz RC oscillator */
2752:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
276	bic	tmp1, tmp1, #AT91_PMC_MOSCSEL
277	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
278	orr	tmp1, tmp1, #AT91_PMC_KEY
279	str	tmp1, [pmc, #AT91_CKGR_MOR]
280
281	wait_moscsels
282
283	/* Disable the crystal oscillator */
284	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
285	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
286	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
287	orr	tmp1, tmp1, #AT91_PMC_KEY
288	str	tmp1, [pmc, #AT91_CKGR_MOR]
289
290	/* Switch the master clock source to main clock */
291	ldr	tmp1, [pmc, tmp2]
292	bic	tmp1, tmp1, #AT91_PMC_CSS
293	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
294	str	tmp1, [pmc, tmp2]
295
296	wait_mckrdy
297
298	/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
299	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
300	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
301	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
302	orr	tmp1, tmp1, #AT91_PMC_KEY
303	str	tmp1, [pmc, #AT91_CKGR_MOR]
304
305	/* Quirk for SAM9X60's PMC */
306	nop
307	nop
308
309	wait_mckrdy
310
311	/* Enable the crystal oscillator */
312	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
313	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
314	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
315	orr	tmp1, tmp1, #AT91_PMC_KEY
316	str	tmp1, [pmc, #AT91_CKGR_MOR]
317
318	wait_moscrdy
319
320	/* Switch the master clock source to slow clock */
321	ldr	tmp1, [pmc, tmp2]
322	bic	tmp1, tmp1, #AT91_PMC_CSS
323	str	tmp1, [pmc, tmp2]
324
325	wait_mckrdy
326
327	/* Switch main clock source to crystal oscillator */
328	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
329	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
330	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
331	orr	tmp1, tmp1, #AT91_PMC_KEY
332	str	tmp1, [pmc, #AT91_CKGR_MOR]
333
334	wait_moscsels
335
336	/* Switch the master clock source to main clock */
337	ldr	tmp1, [pmc, tmp2]
338	bic	tmp1, tmp1, #AT91_PMC_CSS
339	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
340	str	tmp1, [pmc, tmp2]
341
342	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 */
3574:	ldr	tmp1, [pmc, #AT91_PMC_SR]
358	tst	tmp1, #AT91_PMC_MOSCRCS
359	bne	4b
360
3613:
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
4201:	/* 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]
4282:
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. */
4793:	ldr	tmp1, [pmc, #AT91_PMC_PLL_ISR0]
480	tst	tmp1, #0x1
481	beq	3b
482	b	2f
483#endif
484
485	/* Restore PLLA setting */
4864:	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
4941:	ldr	tmp1, [pmc, #AT91_PMC_SR]
495	tst	tmp1, #AT91_PMC_LOCKA
496	beq	1b
4972:
498.endm
499
500ENTRY(at91_ulp_mode)
501	ldr	pmc, .pmc_base
502	ldr	tmp2, .mckr_offset
503	ldr	tmp3, .pm_mode
504
505	/* Save Master clock setting */
506	ldr	tmp1, [pmc, tmp2]
507	str	tmp1, .saved_mckr
508
509	/*
510	 * Set master clock source to:
511	 * - MAINCK if using ULP0 fast variant
512	 * - slow clock, otherwise
513	 */
514	bic	tmp1, tmp1, #AT91_PMC_CSS
515	cmp	tmp3, #AT91_PM_ULP0_FAST
516	bne	save_mck
517	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
518save_mck:
519	str	tmp1, [pmc, tmp2]
520
521	wait_mckrdy
522
523	at91_plla_disable
524
525	cmp	tmp3, #AT91_PM_ULP1
526	beq	ulp1_mode
527
528	at91_pm_ulp0_mode
529	b	ulp_exit
530
531ulp1_mode:
532	at91_pm_ulp1_mode
533	b	ulp_exit
534
535ulp_exit:
536	ldr	pmc, .pmc_base
537
538	at91_plla_enable
539
540	/*
541	 * Restore master clock setting
542	 */
543	ldr	tmp1, .mckr_offset
544	ldr	tmp2, .saved_mckr
545	str	tmp2, [pmc, tmp1]
546
547	wait_mckrdy
548
549	mov	pc, lr
550ENDPROC(at91_ulp_mode)
551
552/*
553 * void at91_sramc_self_refresh(unsigned int is_active)
554 *
555 * @input param:
556 *	@r0: 1 - active self-refresh mode
557 *	     0 - exit self-refresh mode
558 * register usage:
559 * 	@r1: memory type
560 *	@r2: base address of the sram controller
561 */
562
563ENTRY(at91_sramc_self_refresh)
564	ldr	r1, .memtype
565	ldr	r2, .sramc_base
566
567	cmp	r1, #AT91_MEMCTRL_MC
568	bne	ddrc_sf
569
570	/*
571	 * at91rm9200 Memory controller
572	 */
573
574	 /*
575	  * For exiting the self-refresh mode, do nothing,
576	  * automatically exit the self-refresh mode.
577	  */
578	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
579	beq	exit_sramc_sf
580
581	/* Active SDRAM self-refresh mode */
582	mov	r3, #1
583	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
584	b	exit_sramc_sf
585
586ddrc_sf:
587	cmp	r1, #AT91_MEMCTRL_DDRSDR
588	bne	sdramc_sf
589
590	/*
591	 * DDR Memory controller
592	 */
593	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
594	beq	ddrc_exit_sf
595
596	/* LPDDR1 --> force DDR2 mode during self-refresh */
597	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
598	str	r3, .saved_sam9_mdr
599	bic	r3, r3, #~AT91_DDRSDRC_MD
600	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
601	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
602	biceq	r3, r3, #AT91_DDRSDRC_MD
603	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
604	streq	r3, [r2, #AT91_DDRSDRC_MDR]
605
606	/* Active DDRC self-refresh mode */
607	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
608	str	r3, .saved_sam9_lpr
609	bic	r3, r3, #AT91_DDRSDRC_LPCB
610	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
611	str	r3, [r2, #AT91_DDRSDRC_LPR]
612
613	/* If using the 2nd ddr controller */
614	ldr	r2, .sramc1_base
615	cmp	r2, #0
616	beq	no_2nd_ddrc
617
618	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
619	str	r3, .saved_sam9_mdr1
620	bic	r3, r3, #~AT91_DDRSDRC_MD
621	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
622	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
623	biceq	r3, r3, #AT91_DDRSDRC_MD
624	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
625	streq	r3, [r2, #AT91_DDRSDRC_MDR]
626
627	/* Active DDRC self-refresh mode */
628	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
629	str	r3, .saved_sam9_lpr1
630	bic	r3, r3, #AT91_DDRSDRC_LPCB
631	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
632	str	r3, [r2, #AT91_DDRSDRC_LPR]
633
634no_2nd_ddrc:
635	b	exit_sramc_sf
636
637ddrc_exit_sf:
638	/* Restore MDR in case of LPDDR1 */
639	ldr	r3, .saved_sam9_mdr
640	str	r3, [r2, #AT91_DDRSDRC_MDR]
641	/* Restore LPR on AT91 with DDRAM */
642	ldr	r3, .saved_sam9_lpr
643	str	r3, [r2, #AT91_DDRSDRC_LPR]
644
645	/* If using the 2nd ddr controller */
646	ldr	r2, .sramc1_base
647	cmp	r2, #0
648	ldrne	r3, .saved_sam9_mdr1
649	strne	r3, [r2, #AT91_DDRSDRC_MDR]
650	ldrne	r3, .saved_sam9_lpr1
651	strne	r3, [r2, #AT91_DDRSDRC_LPR]
652
653	b	exit_sramc_sf
654
655	/*
656	 * SDRAMC Memory controller
657	 */
658sdramc_sf:
659	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
660	beq	sdramc_exit_sf
661
662	/* Active SDRAMC self-refresh mode */
663	ldr	r3, [r2, #AT91_SDRAMC_LPR]
664	str	r3, .saved_sam9_lpr
665	bic	r3, r3, #AT91_SDRAMC_LPCB
666	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
667	str	r3, [r2, #AT91_SDRAMC_LPR]
668
669sdramc_exit_sf:
670	ldr	r3, .saved_sam9_lpr
671	str	r3, [r2, #AT91_SDRAMC_LPR]
672
673exit_sramc_sf:
674	mov	pc, lr
675ENDPROC(at91_sramc_self_refresh)
676
677.pmc_base:
678	.word 0
679.sramc_base:
680	.word 0
681.sramc1_base:
682	.word 0
683.shdwc:
684	.word 0
685.sfrbu:
686	.word 0
687.memtype:
688	.word 0
689.pm_mode:
690	.word 0
691.mckr_offset:
692	.word 0
693.pmc_version:
694	.word 0
695.saved_mckr:
696	.word 0
697.saved_pllar:
698	.word 0
699.saved_sam9_lpr:
700	.word 0
701.saved_sam9_lpr1:
702	.word 0
703.saved_sam9_mdr:
704	.word 0
705.saved_sam9_mdr1:
706	.word 0
707.saved_osc_status:
708	.word 0
709
710ENTRY(at91_pm_suspend_in_sram_sz)
711	.word .-at91_pm_suspend_in_sram
712