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