xref: /openbmc/linux/arch/arm/mach-at91/pm_suspend.S (revision 4b0aaacee51eb6592a03fdefd5ce97558518e291)
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	/*BUMEN*/
153	ldr	r0, .sfr
154	mov	tmp1, #0x1
155	str	tmp1, [r0, #0x10]
156
157	/* Shutdown */
158	ldr	r0, .shdwc
159	mov	tmp1, #0xA5000000
160	add	tmp1, tmp1, #0x1
161	str	tmp1, [r0, #0]
162ENDPROC(at91_backup_mode)
163
164.macro at91_pm_ulp0_mode
165	ldr	pmc, .pmc_base
166
167	/* Turn off the crystal oscillator */
168	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
169	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
170	orr	tmp1, tmp1, #AT91_PMC_KEY
171	str	tmp1, [pmc, #AT91_CKGR_MOR]
172
173	/* Wait for interrupt */
174	at91_cpu_idle
175
176	/* Turn on the crystal oscillator */
177	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
178	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
179	orr	tmp1, tmp1, #AT91_PMC_KEY
180	str	tmp1, [pmc, #AT91_CKGR_MOR]
181
182	wait_moscrdy
183.endm
184
185/**
186 * Note: This procedure only applies on the platform which uses
187 * the external crystal oscillator as a main clock source.
188 */
189.macro at91_pm_ulp1_mode
190	ldr	pmc, .pmc_base
191
192	/* Switch the main clock source to 12-MHz RC oscillator */
193	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
194	bic	tmp1, tmp1, #AT91_PMC_MOSCSEL
195	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
196	orr	tmp1, tmp1, #AT91_PMC_KEY
197	str	tmp1, [pmc, #AT91_CKGR_MOR]
198
199	wait_moscsels
200
201	/* Disable the crystal oscillator */
202	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
203	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
204	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
205	orr	tmp1, tmp1, #AT91_PMC_KEY
206	str	tmp1, [pmc, #AT91_CKGR_MOR]
207
208	/* Switch the master clock source to main clock */
209	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
210	bic	tmp1, tmp1, #AT91_PMC_CSS
211	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
212	str	tmp1, [pmc, #AT91_PMC_MCKR]
213
214	wait_mckrdy
215
216	/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
217	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
218	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
219	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
220	orr	tmp1, tmp1, #AT91_PMC_KEY
221	str	tmp1, [pmc, #AT91_CKGR_MOR]
222
223	wait_mckrdy
224
225	/* Enable the crystal oscillator */
226	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
227	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
228	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
229	orr	tmp1, tmp1, #AT91_PMC_KEY
230	str	tmp1, [pmc, #AT91_CKGR_MOR]
231
232	wait_moscrdy
233
234	/* Switch the master clock source to slow clock */
235	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
236	bic	tmp1, tmp1, #AT91_PMC_CSS
237	str	tmp1, [pmc, #AT91_PMC_MCKR]
238
239	wait_mckrdy
240
241	/* Switch main clock source to crystal oscillator */
242	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
243	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
244	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
245	orr	tmp1, tmp1, #AT91_PMC_KEY
246	str	tmp1, [pmc, #AT91_CKGR_MOR]
247
248	wait_moscsels
249
250	/* Switch the master clock source to main clock */
251	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
252	bic	tmp1, tmp1, #AT91_PMC_CSS
253	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
254	str	tmp1, [pmc, #AT91_PMC_MCKR]
255
256	wait_mckrdy
257.endm
258
259ENTRY(at91_ulp_mode)
260	ldr	pmc, .pmc_base
261
262	/* Save Master clock setting */
263	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
264	str	tmp1, .saved_mckr
265
266	/*
267	 * Set the Master clock source to slow clock
268	 */
269	bic	tmp1, tmp1, #AT91_PMC_CSS
270	str	tmp1, [pmc, #AT91_PMC_MCKR]
271
272	wait_mckrdy
273
274	/* Save PLLA setting and disable it */
275	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
276	str	tmp1, .saved_pllar
277
278	mov	tmp1, #AT91_PMC_PLLCOUNT
279	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
280	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
281
282	ldr	r0, .pm_mode
283	cmp	r0, #AT91_PM_ULP1
284	beq	ulp1_mode
285
286	at91_pm_ulp0_mode
287	b	ulp_exit
288
289ulp1_mode:
290	at91_pm_ulp1_mode
291	b	ulp_exit
292
293ulp_exit:
294	ldr	pmc, .pmc_base
295
296	/* Restore PLLA setting */
297	ldr	tmp1, .saved_pllar
298	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
299
300	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
301	bne	3f
302	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
303	beq	4f
3043:
305	wait_pllalock
3064:
307
308	/*
309	 * Restore master clock setting
310	 */
311	ldr	tmp1, .saved_mckr
312	str	tmp1, [pmc, #AT91_PMC_MCKR]
313
314	wait_mckrdy
315
316	mov	pc, lr
317ENDPROC(at91_ulp_mode)
318
319/*
320 * void at91_sramc_self_refresh(unsigned int is_active)
321 *
322 * @input param:
323 *	@r0: 1 - active self-refresh mode
324 *	     0 - exit self-refresh mode
325 * register usage:
326 * 	@r1: memory type
327 *	@r2: base address of the sram controller
328 */
329
330ENTRY(at91_sramc_self_refresh)
331	ldr	r1, .memtype
332	ldr	r2, .sramc_base
333
334	cmp	r1, #AT91_MEMCTRL_MC
335	bne	ddrc_sf
336
337	/*
338	 * at91rm9200 Memory controller
339	 */
340
341	 /*
342	  * For exiting the self-refresh mode, do nothing,
343	  * automatically exit the self-refresh mode.
344	  */
345	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
346	beq	exit_sramc_sf
347
348	/* Active SDRAM self-refresh mode */
349	mov	r3, #1
350	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
351	b	exit_sramc_sf
352
353ddrc_sf:
354	cmp	r1, #AT91_MEMCTRL_DDRSDR
355	bne	sdramc_sf
356
357	/*
358	 * DDR Memory controller
359	 */
360	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
361	beq	ddrc_exit_sf
362
363	/* LPDDR1 --> force DDR2 mode during self-refresh */
364	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
365	str	r3, .saved_sam9_mdr
366	bic	r3, r3, #~AT91_DDRSDRC_MD
367	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
368	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
369	biceq	r3, r3, #AT91_DDRSDRC_MD
370	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
371	streq	r3, [r2, #AT91_DDRSDRC_MDR]
372
373	/* Active DDRC self-refresh mode */
374	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
375	str	r3, .saved_sam9_lpr
376	bic	r3, r3, #AT91_DDRSDRC_LPCB
377	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
378	str	r3, [r2, #AT91_DDRSDRC_LPR]
379
380	/* If using the 2nd ddr controller */
381	ldr	r2, .sramc1_base
382	cmp	r2, #0
383	beq	no_2nd_ddrc
384
385	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
386	str	r3, .saved_sam9_mdr1
387	bic	r3, r3, #~AT91_DDRSDRC_MD
388	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
389	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
390	biceq	r3, r3, #AT91_DDRSDRC_MD
391	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
392	streq	r3, [r2, #AT91_DDRSDRC_MDR]
393
394	/* Active DDRC self-refresh mode */
395	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
396	str	r3, .saved_sam9_lpr1
397	bic	r3, r3, #AT91_DDRSDRC_LPCB
398	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
399	str	r3, [r2, #AT91_DDRSDRC_LPR]
400
401no_2nd_ddrc:
402	b	exit_sramc_sf
403
404ddrc_exit_sf:
405	/* Restore MDR in case of LPDDR1 */
406	ldr	r3, .saved_sam9_mdr
407	str	r3, [r2, #AT91_DDRSDRC_MDR]
408	/* Restore LPR on AT91 with DDRAM */
409	ldr	r3, .saved_sam9_lpr
410	str	r3, [r2, #AT91_DDRSDRC_LPR]
411
412	/* If using the 2nd ddr controller */
413	ldr	r2, .sramc1_base
414	cmp	r2, #0
415	ldrne	r3, .saved_sam9_mdr1
416	strne	r3, [r2, #AT91_DDRSDRC_MDR]
417	ldrne	r3, .saved_sam9_lpr1
418	strne	r3, [r2, #AT91_DDRSDRC_LPR]
419
420	b	exit_sramc_sf
421
422	/*
423	 * SDRAMC Memory controller
424	 */
425sdramc_sf:
426	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
427	beq	sdramc_exit_sf
428
429	/* Active SDRAMC self-refresh mode */
430	ldr	r3, [r2, #AT91_SDRAMC_LPR]
431	str	r3, .saved_sam9_lpr
432	bic	r3, r3, #AT91_SDRAMC_LPCB
433	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
434	str	r3, [r2, #AT91_SDRAMC_LPR]
435
436sdramc_exit_sf:
437	ldr	r3, .saved_sam9_lpr
438	str	r3, [r2, #AT91_SDRAMC_LPR]
439
440exit_sramc_sf:
441	mov	pc, lr
442ENDPROC(at91_sramc_self_refresh)
443
444.pmc_base:
445	.word 0
446.sramc_base:
447	.word 0
448.sramc1_base:
449	.word 0
450.shdwc:
451	.word 0
452.sfr:
453	.word 0
454.memtype:
455	.word 0
456.pm_mode:
457	.word 0
458.saved_mckr:
459	.word 0
460.saved_pllar:
461	.word 0
462.saved_sam9_lpr:
463	.word 0
464.saved_sam9_lpr1:
465	.word 0
466.saved_sam9_mdr:
467	.word 0
468.saved_sam9_mdr1:
469	.word 0
470
471ENTRY(at91_pm_suspend_in_sram_sz)
472	.word .-at91_pm_suspend_in_sram
473