xref: /openbmc/linux/arch/arm/mach-at91/pm_suspend.S (revision 74a22e8f)
1/*
2 * arch/arm/mach-at91/pm_slow_clock.S
3 *
4 *  Copyright (C) 2006 Savin Zlobec
5 *
6 * AT91SAM9 support:
7 *  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 *
13 */
14#include <linux/linkage.h>
15#include <linux/clk/at91_pmc.h>
16#include "pm.h"
17#include "generated/at91_pm_data-offsets.h"
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
25
26/*
27 * Wait until master clock is ready (after switching master clock source)
28 */
29	.macro wait_mckrdy
301:	ldr	tmp1, [pmc, #AT91_PMC_SR]
31	tst	tmp1, #AT91_PMC_MCKRDY
32	beq	1b
33	.endm
34
35/*
36 * Wait until master oscillator has stabilized.
37 */
38	.macro wait_moscrdy
391:	ldr	tmp1, [pmc, #AT91_PMC_SR]
40	tst	tmp1, #AT91_PMC_MOSCS
41	beq	1b
42	.endm
43
44/*
45 * Wait for main oscillator selection is done
46 */
47	.macro wait_moscsels
481:	ldr	tmp1, [pmc, #AT91_PMC_SR]
49	tst	tmp1, #AT91_PMC_MOSCSELS
50	beq	1b
51	.endm
52
53/*
54 * Put the processor to enter the idle state
55 */
56	.macro at91_cpu_idle
57
58#if defined(CONFIG_CPU_V7)
59	mov	tmp1, #AT91_PMC_PCK
60	str	tmp1, [pmc, #AT91_PMC_SCDR]
61
62	dsb
63
64	wfi		@ Wait For Interrupt
65#else
66	mcr	p15, 0, tmp1, c7, c0, 4
67#endif
68
69	.endm
70
71	.text
72
73	.arm
74
75/*
76 * void at91_suspend_sram_fn(struct at91_pm_data*)
77 * @input param:
78 * 	@r0: base address of struct at91_pm_data
79 */
80/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
81	.align 3
82ENTRY(at91_pm_suspend_in_sram)
83	/* Save registers on stack */
84	stmfd	sp!, {r4 - r12, lr}
85
86	/* Drain write buffer */
87	mov	tmp1, #0
88	mcr	p15, 0, tmp1, c7, c10, 4
89
90	ldr	tmp1, [r0, #PM_DATA_PMC]
91	str	tmp1, .pmc_base
92	ldr	tmp1, [r0, #PM_DATA_RAMC0]
93	str	tmp1, .sramc_base
94	ldr	tmp1, [r0, #PM_DATA_RAMC1]
95	str	tmp1, .sramc1_base
96	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
97	str	tmp1, .memtype
98	ldr	tmp1, [r0, #PM_DATA_MODE]
99	str	tmp1, .pm_mode
100	/* Both ldrne below are here to preload their address in the TLB */
101	ldr	tmp1, [r0, #PM_DATA_SHDWC]
102	str	tmp1, .shdwc
103	cmp	tmp1, #0
104	ldrne	tmp2, [tmp1, #0]
105	ldr	tmp1, [r0, #PM_DATA_SFRBU]
106	str	tmp1, .sfr
107	cmp	tmp1, #0
108	ldrne	tmp2, [tmp1, #0x10]
109
110	/* Active the self-refresh mode */
111	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
112	bl	at91_sramc_self_refresh
113
114	ldr	r0, .pm_mode
115	cmp	r0, #AT91_PM_STANDBY
116	beq	standby
117	cmp	r0, #AT91_PM_BACKUP
118	beq	backup_mode
119
120	bl	at91_ulp_mode
121	b	exit_suspend
122
123standby:
124	/* Wait for interrupt */
125	ldr	pmc, .pmc_base
126	at91_cpu_idle
127	b	exit_suspend
128
129backup_mode:
130	bl	at91_backup_mode
131	b	exit_suspend
132
133exit_suspend:
134	/* Exit the self-refresh mode */
135	mov	r0, #SRAMC_SELF_FRESH_EXIT
136	bl	at91_sramc_self_refresh
137
138	/* Restore registers, and return */
139	ldmfd	sp!, {r4 - r12, pc}
140ENDPROC(at91_pm_suspend_in_sram)
141
142ENTRY(at91_backup_mode)
143	/* Switch the master clock source to slow clock. */
144	ldr	pmc, .pmc_base
145	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
146	bic	tmp1, tmp1, #AT91_PMC_CSS
147	str	tmp1, [pmc, #AT91_PMC_MCKR]
148
149	wait_mckrdy
150
151	/*BUMEN*/
152	ldr	r0, .sfr
153	mov	tmp1, #0x1
154	str	tmp1, [r0, #0x10]
155
156	/* Shutdown */
157	ldr	r0, .shdwc
158	mov	tmp1, #0xA5000000
159	add	tmp1, tmp1, #0x1
160	str	tmp1, [r0, #0]
161ENDPROC(at91_backup_mode)
162
163.macro at91_pm_ulp0_mode
164	ldr	pmc, .pmc_base
165
166	/* Turn off the crystal oscillator */
167	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
168	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
169	orr	tmp1, tmp1, #AT91_PMC_KEY
170	str	tmp1, [pmc, #AT91_CKGR_MOR]
171
172	/* Save RC oscillator state */
173	ldr	tmp1, [pmc, #AT91_PMC_SR]
174	str	tmp1, .saved_osc_status
175	tst	tmp1, #AT91_PMC_MOSCRCS
176	bne	1f
177
178	/* Turn off RC oscillator */
179	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
180	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
181	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
182	orr	tmp1, tmp1, #AT91_PMC_KEY
183	str	tmp1, [pmc, #AT91_CKGR_MOR]
184
185	/* Wait main RC disabled done */
1862:	ldr	tmp1, [pmc, #AT91_PMC_SR]
187	tst	tmp1, #AT91_PMC_MOSCRCS
188	bne	2b
189
190	/* Wait for interrupt */
1911:	at91_cpu_idle
192
193	/* Restore RC oscillator state */
194	ldr	tmp1, .saved_osc_status
195	tst	tmp1, #AT91_PMC_MOSCRCS
196	beq	4f
197
198	/* Turn on RC oscillator */
199	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
200	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
201	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
202	orr	tmp1, tmp1, #AT91_PMC_KEY
203	str	tmp1, [pmc, #AT91_CKGR_MOR]
204
205	/* Wait main RC stabilization */
2063:	ldr	tmp1, [pmc, #AT91_PMC_SR]
207	tst	tmp1, #AT91_PMC_MOSCRCS
208	beq	3b
209
210	/* Turn on the crystal oscillator */
2114:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
212	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
213	orr	tmp1, tmp1, #AT91_PMC_KEY
214	str	tmp1, [pmc, #AT91_CKGR_MOR]
215
216	wait_moscrdy
217.endm
218
219/**
220 * Note: This procedure only applies on the platform which uses
221 * the external crystal oscillator as a main clock source.
222 */
223.macro at91_pm_ulp1_mode
224	ldr	pmc, .pmc_base
225
226	/* Save RC oscillator state and check if it is enabled. */
227	ldr	tmp1, [pmc, #AT91_PMC_SR]
228	str	tmp1, .saved_osc_status
229	tst	tmp1, #AT91_PMC_MOSCRCS
230	bne	2f
231
232	/* Enable RC oscillator */
233	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
234	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
235	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
236	orr	tmp1, tmp1, #AT91_PMC_KEY
237	str	tmp1, [pmc, #AT91_CKGR_MOR]
238
239	/* Wait main RC stabilization */
2401:	ldr	tmp1, [pmc, #AT91_PMC_SR]
241	tst	tmp1, #AT91_PMC_MOSCRCS
242	beq	1b
243
244	/* Switch the main clock source to 12-MHz RC oscillator */
2452:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
246	bic	tmp1, tmp1, #AT91_PMC_MOSCSEL
247	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
248	orr	tmp1, tmp1, #AT91_PMC_KEY
249	str	tmp1, [pmc, #AT91_CKGR_MOR]
250
251	wait_moscsels
252
253	/* Disable the crystal oscillator */
254	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
255	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
256	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
257	orr	tmp1, tmp1, #AT91_PMC_KEY
258	str	tmp1, [pmc, #AT91_CKGR_MOR]
259
260	/* Switch the master clock source to main clock */
261	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
262	bic	tmp1, tmp1, #AT91_PMC_CSS
263	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
264	str	tmp1, [pmc, #AT91_PMC_MCKR]
265
266	wait_mckrdy
267
268	/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
269	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
270	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
271	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
272	orr	tmp1, tmp1, #AT91_PMC_KEY
273	str	tmp1, [pmc, #AT91_CKGR_MOR]
274
275	wait_mckrdy
276
277	/* Enable the crystal oscillator */
278	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
279	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
280	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
281	orr	tmp1, tmp1, #AT91_PMC_KEY
282	str	tmp1, [pmc, #AT91_CKGR_MOR]
283
284	wait_moscrdy
285
286	/* Switch the master clock source to slow clock */
287	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
288	bic	tmp1, tmp1, #AT91_PMC_CSS
289	str	tmp1, [pmc, #AT91_PMC_MCKR]
290
291	wait_mckrdy
292
293	/* Switch main clock source to crystal oscillator */
294	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
295	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
296	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
297	orr	tmp1, tmp1, #AT91_PMC_KEY
298	str	tmp1, [pmc, #AT91_CKGR_MOR]
299
300	wait_moscsels
301
302	/* Switch the master clock source to main clock */
303	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
304	bic	tmp1, tmp1, #AT91_PMC_CSS
305	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
306	str	tmp1, [pmc, #AT91_PMC_MCKR]
307
308	wait_mckrdy
309
310	/* Restore RC oscillator state */
311	ldr	tmp1, .saved_osc_status
312	tst	tmp1, #AT91_PMC_MOSCRCS
313	bne	3f
314
315	/* Disable RC oscillator */
316	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
317	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
318	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
319	orr	tmp1, tmp1, #AT91_PMC_KEY
320	str	tmp1, [pmc, #AT91_CKGR_MOR]
321
322	/* Wait RC oscillator disable done */
3234:	ldr	tmp1, [pmc, #AT91_PMC_SR]
324	tst	tmp1, #AT91_PMC_MOSCRCS
325	bne	4b
326
3273:
328.endm
329
330ENTRY(at91_ulp_mode)
331	ldr	pmc, .pmc_base
332
333	/* Save Master clock setting */
334	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
335	str	tmp1, .saved_mckr
336
337	/*
338	 * Set the Master clock source to slow clock
339	 */
340	bic	tmp1, tmp1, #AT91_PMC_CSS
341	str	tmp1, [pmc, #AT91_PMC_MCKR]
342
343	wait_mckrdy
344
345	ldr	r0, .pm_mode
346	cmp	r0, #AT91_PM_ULP1
347	beq	ulp1_mode
348
349	at91_pm_ulp0_mode
350	b	ulp_exit
351
352ulp1_mode:
353	at91_pm_ulp1_mode
354	b	ulp_exit
355
356ulp_exit:
357	ldr	pmc, .pmc_base
358
359	/*
360	 * Restore master clock setting
361	 */
362	ldr	tmp1, .saved_mckr
363	str	tmp1, [pmc, #AT91_PMC_MCKR]
364
365	wait_mckrdy
366
367	mov	pc, lr
368ENDPROC(at91_ulp_mode)
369
370/*
371 * void at91_sramc_self_refresh(unsigned int is_active)
372 *
373 * @input param:
374 *	@r0: 1 - active self-refresh mode
375 *	     0 - exit self-refresh mode
376 * register usage:
377 * 	@r1: memory type
378 *	@r2: base address of the sram controller
379 */
380
381ENTRY(at91_sramc_self_refresh)
382	ldr	r1, .memtype
383	ldr	r2, .sramc_base
384
385	cmp	r1, #AT91_MEMCTRL_MC
386	bne	ddrc_sf
387
388	/*
389	 * at91rm9200 Memory controller
390	 */
391
392	 /*
393	  * For exiting the self-refresh mode, do nothing,
394	  * automatically exit the self-refresh mode.
395	  */
396	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
397	beq	exit_sramc_sf
398
399	/* Active SDRAM self-refresh mode */
400	mov	r3, #1
401	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
402	b	exit_sramc_sf
403
404ddrc_sf:
405	cmp	r1, #AT91_MEMCTRL_DDRSDR
406	bne	sdramc_sf
407
408	/*
409	 * DDR Memory controller
410	 */
411	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
412	beq	ddrc_exit_sf
413
414	/* LPDDR1 --> force DDR2 mode during self-refresh */
415	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
416	str	r3, .saved_sam9_mdr
417	bic	r3, r3, #~AT91_DDRSDRC_MD
418	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
419	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
420	biceq	r3, r3, #AT91_DDRSDRC_MD
421	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
422	streq	r3, [r2, #AT91_DDRSDRC_MDR]
423
424	/* Active DDRC self-refresh mode */
425	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
426	str	r3, .saved_sam9_lpr
427	bic	r3, r3, #AT91_DDRSDRC_LPCB
428	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
429	str	r3, [r2, #AT91_DDRSDRC_LPR]
430
431	/* If using the 2nd ddr controller */
432	ldr	r2, .sramc1_base
433	cmp	r2, #0
434	beq	no_2nd_ddrc
435
436	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
437	str	r3, .saved_sam9_mdr1
438	bic	r3, r3, #~AT91_DDRSDRC_MD
439	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
440	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
441	biceq	r3, r3, #AT91_DDRSDRC_MD
442	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
443	streq	r3, [r2, #AT91_DDRSDRC_MDR]
444
445	/* Active DDRC self-refresh mode */
446	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
447	str	r3, .saved_sam9_lpr1
448	bic	r3, r3, #AT91_DDRSDRC_LPCB
449	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
450	str	r3, [r2, #AT91_DDRSDRC_LPR]
451
452no_2nd_ddrc:
453	b	exit_sramc_sf
454
455ddrc_exit_sf:
456	/* Restore MDR in case of LPDDR1 */
457	ldr	r3, .saved_sam9_mdr
458	str	r3, [r2, #AT91_DDRSDRC_MDR]
459	/* Restore LPR on AT91 with DDRAM */
460	ldr	r3, .saved_sam9_lpr
461	str	r3, [r2, #AT91_DDRSDRC_LPR]
462
463	/* If using the 2nd ddr controller */
464	ldr	r2, .sramc1_base
465	cmp	r2, #0
466	ldrne	r3, .saved_sam9_mdr1
467	strne	r3, [r2, #AT91_DDRSDRC_MDR]
468	ldrne	r3, .saved_sam9_lpr1
469	strne	r3, [r2, #AT91_DDRSDRC_LPR]
470
471	b	exit_sramc_sf
472
473	/*
474	 * SDRAMC Memory controller
475	 */
476sdramc_sf:
477	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
478	beq	sdramc_exit_sf
479
480	/* Active SDRAMC self-refresh mode */
481	ldr	r3, [r2, #AT91_SDRAMC_LPR]
482	str	r3, .saved_sam9_lpr
483	bic	r3, r3, #AT91_SDRAMC_LPCB
484	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
485	str	r3, [r2, #AT91_SDRAMC_LPR]
486
487sdramc_exit_sf:
488	ldr	r3, .saved_sam9_lpr
489	str	r3, [r2, #AT91_SDRAMC_LPR]
490
491exit_sramc_sf:
492	mov	pc, lr
493ENDPROC(at91_sramc_self_refresh)
494
495.pmc_base:
496	.word 0
497.sramc_base:
498	.word 0
499.sramc1_base:
500	.word 0
501.shdwc:
502	.word 0
503.sfr:
504	.word 0
505.memtype:
506	.word 0
507.pm_mode:
508	.word 0
509.saved_mckr:
510	.word 0
511.saved_sam9_lpr:
512	.word 0
513.saved_sam9_lpr1:
514	.word 0
515.saved_sam9_mdr:
516	.word 0
517.saved_sam9_mdr1:
518	.word 0
519.saved_osc_status:
520	.word 0
521
522ENTRY(at91_pm_suspend_in_sram_sz)
523	.word .-at91_pm_suspend_in_sram
524