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