xref: /openbmc/linux/arch/arm/mach-at91/pm_suspend.S (revision e2f1cf25)
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
18#define	SRAMC_SELF_FRESH_ACTIVE		0x01
19#define	SRAMC_SELF_FRESH_EXIT		0x00
20
21pmc	.req	r0
22tmp1	.req	r4
23tmp2	.req	r5
24
25/*
26 * Wait until master clock is ready (after switching master clock source)
27 */
28	.macro wait_mckrdy
291:	ldr	tmp1, [pmc, #AT91_PMC_SR]
30	tst	tmp1, #AT91_PMC_MCKRDY
31	beq	1b
32	.endm
33
34/*
35 * Wait until master oscillator has stabilized.
36 */
37	.macro wait_moscrdy
381:	ldr	tmp1, [pmc, #AT91_PMC_SR]
39	tst	tmp1, #AT91_PMC_MOSCS
40	beq	1b
41	.endm
42
43/*
44 * Wait until PLLA has locked.
45 */
46	.macro wait_pllalock
471:	ldr	tmp1, [pmc, #AT91_PMC_SR]
48	tst	tmp1, #AT91_PMC_LOCKA
49	beq	1b
50	.endm
51
52/*
53 * Put the processor to enter the idle state
54 */
55	.macro at91_cpu_idle
56
57#if defined(CONFIG_CPU_V7)
58	mov	tmp1, #AT91_PMC_PCK
59	str	tmp1, [pmc, #AT91_PMC_SCDR]
60
61	dsb
62
63	wfi		@ Wait For Interrupt
64#else
65	mcr	p15, 0, tmp1, c7, c0, 4
66#endif
67
68	.endm
69
70	.text
71
72	.arm
73
74/*
75 * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
76 *			void __iomem *ramc1, int memctrl)
77 * @input param:
78 * 	@r0: base address of AT91_PMC
79 *  	@r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
80 *	@r2: base address of second SDRAM Controller or 0 if not present
81 *	@r3: pm information
82 */
83ENTRY(at91_pm_suspend_in_sram)
84	/* Save registers on stack */
85	stmfd	sp!, {r4 - r12, lr}
86
87	/* Drain write buffer */
88	mov	tmp1, #0
89	mcr	p15, 0, tmp1, c7, c10, 4
90
91	str	r0, .pmc_base
92	str	r1, .sramc_base
93	str	r2, .sramc1_base
94
95	and	r0, r3, #AT91_PM_MEMTYPE_MASK
96	str	r0, .memtype
97
98	lsr	r0, r3, #AT91_PM_MODE_OFFSET
99	and	r0, r0, #AT91_PM_MODE_MASK
100	str	r0, .pm_mode
101
102	/* Active the self-refresh mode */
103	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
104	bl	at91_sramc_self_refresh
105
106	ldr	r0, .pm_mode
107	tst	r0, #AT91_PM_SLOW_CLOCK
108	beq	skip_disable_main_clock
109
110	ldr	pmc, .pmc_base
111
112	/* Save Master clock setting */
113	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
114	str	tmp1, .saved_mckr
115
116	/*
117	 * Set the Master clock source to slow clock
118	 */
119	bic	tmp1, tmp1, #AT91_PMC_CSS
120	str	tmp1, [pmc, #AT91_PMC_MCKR]
121
122	wait_mckrdy
123
124	/* Save PLLA setting and disable it */
125	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
126	str	tmp1, .saved_pllar
127
128	mov	tmp1, #AT91_PMC_PLLCOUNT
129	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
130	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
131
132	/* Turn off the main oscillator */
133	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
134	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
135	orr	tmp1, tmp1, #AT91_PMC_KEY
136	str	tmp1, [pmc, #AT91_CKGR_MOR]
137
138skip_disable_main_clock:
139	ldr	pmc, .pmc_base
140
141	/* Wait for interrupt */
142	at91_cpu_idle
143
144	ldr	r0, .pm_mode
145	tst	r0, #AT91_PM_SLOW_CLOCK
146	beq	skip_enable_main_clock
147
148	ldr	pmc, .pmc_base
149
150	/* Turn on the main oscillator */
151	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
152	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
153	orr	tmp1, tmp1, #AT91_PMC_KEY
154	str	tmp1, [pmc, #AT91_CKGR_MOR]
155
156	wait_moscrdy
157
158	/* Restore PLLA setting */
159	ldr	tmp1, .saved_pllar
160	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
161
162	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
163	bne	3f
164	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
165	beq	4f
1663:
167	wait_pllalock
1684:
169
170	/*
171	 * Restore master clock setting
172	 */
173	ldr	tmp1, .saved_mckr
174	str	tmp1, [pmc, #AT91_PMC_MCKR]
175
176	wait_mckrdy
177
178skip_enable_main_clock:
179	/* Exit the self-refresh mode */
180	mov	r0, #SRAMC_SELF_FRESH_EXIT
181	bl	at91_sramc_self_refresh
182
183	/* Restore registers, and return */
184	ldmfd	sp!, {r4 - r12, pc}
185ENDPROC(at91_pm_suspend_in_sram)
186
187/*
188 * void at91_sramc_self_refresh(unsigned int is_active)
189 *
190 * @input param:
191 *	@r0: 1 - active self-refresh mode
192 *	     0 - exit self-refresh mode
193 * register usage:
194 * 	@r1: memory type
195 *	@r2: base address of the sram controller
196 */
197
198ENTRY(at91_sramc_self_refresh)
199	ldr	r1, .memtype
200	ldr	r2, .sramc_base
201
202	cmp	r1, #AT91_MEMCTRL_MC
203	bne	ddrc_sf
204
205	/*
206	 * at91rm9200 Memory controller
207	 */
208
209	 /*
210	  * For exiting the self-refresh mode, do nothing,
211	  * automatically exit the self-refresh mode.
212	  */
213	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
214	beq	exit_sramc_sf
215
216	/* Active SDRAM self-refresh mode */
217	mov	r3, #1
218	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
219	b	exit_sramc_sf
220
221ddrc_sf:
222	cmp	r1, #AT91_MEMCTRL_DDRSDR
223	bne	sdramc_sf
224
225	/*
226	 * DDR Memory controller
227	 */
228	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
229	beq	ddrc_exit_sf
230
231	/* LPDDR1 --> force DDR2 mode during self-refresh */
232	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
233	str	r3, .saved_sam9_mdr
234	bic	r3, r3, #~AT91_DDRSDRC_MD
235	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
236	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
237	biceq	r3, r3, #AT91_DDRSDRC_MD
238	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
239	streq	r3, [r2, #AT91_DDRSDRC_MDR]
240
241	/* Active DDRC self-refresh mode */
242	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
243	str	r3, .saved_sam9_lpr
244	bic	r3, r3, #AT91_DDRSDRC_LPCB
245	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
246	str	r3, [r2, #AT91_DDRSDRC_LPR]
247
248	/* If using the 2nd ddr controller */
249	ldr	r2, .sramc1_base
250	cmp	r2, #0
251	beq	no_2nd_ddrc
252
253	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
254	str	r3, .saved_sam9_mdr1
255	bic	r3, r3, #~AT91_DDRSDRC_MD
256	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
257	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
258	biceq	r3, r3, #AT91_DDRSDRC_MD
259	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
260	streq	r3, [r2, #AT91_DDRSDRC_MDR]
261
262	/* Active DDRC self-refresh mode */
263	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
264	str	r3, .saved_sam9_lpr1
265	bic	r3, r3, #AT91_DDRSDRC_LPCB
266	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
267	str	r3, [r2, #AT91_DDRSDRC_LPR]
268
269no_2nd_ddrc:
270	b	exit_sramc_sf
271
272ddrc_exit_sf:
273	/* Restore MDR in case of LPDDR1 */
274	ldr	r3, .saved_sam9_mdr
275	str	r3, [r2, #AT91_DDRSDRC_MDR]
276	/* Restore LPR on AT91 with DDRAM */
277	ldr	r3, .saved_sam9_lpr
278	str	r3, [r2, #AT91_DDRSDRC_LPR]
279
280	/* If using the 2nd ddr controller */
281	ldr	r2, .sramc1_base
282	cmp	r2, #0
283	ldrne	r3, .saved_sam9_mdr1
284	strne	r3, [r2, #AT91_DDRSDRC_MDR]
285	ldrne	r3, .saved_sam9_lpr1
286	strne	r3, [r2, #AT91_DDRSDRC_LPR]
287
288	b	exit_sramc_sf
289
290	/*
291	 * SDRAMC Memory controller
292	 */
293sdramc_sf:
294	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
295	beq	sdramc_exit_sf
296
297	/* Active SDRAMC self-refresh mode */
298	ldr	r3, [r2, #AT91_SDRAMC_LPR]
299	str	r3, .saved_sam9_lpr
300	bic	r3, r3, #AT91_SDRAMC_LPCB
301	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
302	str	r3, [r2, #AT91_SDRAMC_LPR]
303
304sdramc_exit_sf:
305	ldr	r3, .saved_sam9_lpr
306	str	r3, [r2, #AT91_SDRAMC_LPR]
307
308exit_sramc_sf:
309	mov	pc, lr
310ENDPROC(at91_sramc_self_refresh)
311
312.pmc_base:
313	.word 0
314.sramc_base:
315	.word 0
316.sramc1_base:
317	.word 0
318.memtype:
319	.word 0
320.pm_mode:
321	.word 0
322.saved_mckr:
323	.word 0
324.saved_pllar:
325	.word 0
326.saved_sam9_lpr:
327	.word 0
328.saved_sam9_lpr1:
329	.word 0
330.saved_sam9_mdr:
331	.word 0
332.saved_sam9_mdr1:
333	.word 0
334
335ENTRY(at91_pm_suspend_in_sram_sz)
336	.word .-at91_pm_suspend_in_sram
337