xref: /openbmc/linux/arch/arm/mach-at91/pm_suspend.S (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
2828b98faSWenyou Yang/*
3828b98faSWenyou Yang * arch/arm/mach-at91/pm_slow_clock.S
4828b98faSWenyou Yang *
5828b98faSWenyou Yang *  Copyright (C) 2006 Savin Zlobec
6828b98faSWenyou Yang *
7828b98faSWenyou Yang * AT91SAM9 support:
88c9290aeSAlexandre Belloni *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
9828b98faSWenyou Yang */
10828b98faSWenyou Yang#include <linux/linkage.h>
11828b98faSWenyou Yang#include <linux/clk/at91_pmc.h>
12828b98faSWenyou Yang#include "pm.h"
139fac85a6SMasahiro Yamada#include "pm_data-offsets.h"
14828b98faSWenyou Yang
15*a2faac39SNick Desaulniers#ifdef CONFIG_CPU_V7
16*a2faac39SNick Desaulniers.arch armv7-a
17*a2faac39SNick Desaulniers#endif
18*a2faac39SNick Desaulniers
19828b98faSWenyou Yang#define	SRAMC_SELF_FRESH_ACTIVE		0x01
20828b98faSWenyou Yang#define	SRAMC_SELF_FRESH_EXIT		0x00
21828b98faSWenyou Yang
22828b98faSWenyou Yangpmc	.req	r0
23828b98faSWenyou Yangtmp1	.req	r4
24828b98faSWenyou Yangtmp2	.req	r5
254fd36e45SClaudiu Bezneatmp3	.req	r6
26828b98faSWenyou Yang
27828b98faSWenyou Yang/*
28828b98faSWenyou Yang * Wait until master clock is ready (after switching master clock source)
2915126bb6SClaudiu Beznea *
3015126bb6SClaudiu Beznea * @r_mckid:	register holding master clock identifier
3115126bb6SClaudiu Beznea *
3215126bb6SClaudiu Beznea * Side effects: overwrites r7, r8
33828b98faSWenyou Yang */
3415126bb6SClaudiu Beznea	.macro wait_mckrdy r_mckid
3515126bb6SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
3615126bb6SClaudiu Beznea	cmp	\r_mckid, #0
3715126bb6SClaudiu Beznea	beq	1f
3815126bb6SClaudiu Beznea	mov	r7, #AT91_PMC_MCKXRDY
3915126bb6SClaudiu Beznea	b	2f
4015126bb6SClaudiu Beznea#endif
4115126bb6SClaudiu Beznea1:	mov	r7, #AT91_PMC_MCKRDY
4215126bb6SClaudiu Beznea2:	ldr	r8, [pmc, #AT91_PMC_SR]
4315126bb6SClaudiu Beznea	and	r8, r7
4415126bb6SClaudiu Beznea	cmp	r8, r7
4515126bb6SClaudiu Beznea	bne	2b
46828b98faSWenyou Yang	.endm
47828b98faSWenyou Yang
48828b98faSWenyou Yang/*
49828b98faSWenyou Yang * Wait until master oscillator has stabilized.
5029cdf077SClaudiu Beznea *
5129cdf077SClaudiu Beznea * Side effects: overwrites r7
52828b98faSWenyou Yang */
53828b98faSWenyou Yang	.macro wait_moscrdy
5429cdf077SClaudiu Beznea1:	ldr	r7, [pmc, #AT91_PMC_SR]
5529cdf077SClaudiu Beznea	tst	r7, #AT91_PMC_MOSCS
56828b98faSWenyou Yang	beq	1b
57828b98faSWenyou Yang	.endm
58828b98faSWenyou Yang
59828b98faSWenyou Yang/*
605b56c182SWenyou Yang * Wait for main oscillator selection is done
6129cdf077SClaudiu Beznea *
6229cdf077SClaudiu Beznea * Side effects: overwrites r7
635b56c182SWenyou Yang */
645b56c182SWenyou Yang	.macro wait_moscsels
6529cdf077SClaudiu Beznea1:	ldr	r7, [pmc, #AT91_PMC_SR]
6629cdf077SClaudiu Beznea	tst	r7, #AT91_PMC_MOSCSELS
675b56c182SWenyou Yang	beq	1b
685b56c182SWenyou Yang	.endm
695b56c182SWenyou Yang
705b56c182SWenyou Yang/*
7120567658SWenyou Yang * Put the processor to enter the idle state
7229cdf077SClaudiu Beznea *
7329cdf077SClaudiu Beznea * Side effects: overwrites r7
7420567658SWenyou Yang */
7520567658SWenyou Yang	.macro at91_cpu_idle
7620567658SWenyou Yang
7720567658SWenyou Yang#if defined(CONFIG_CPU_V7)
7829cdf077SClaudiu Beznea	mov	r7, #AT91_PMC_PCK
7929cdf077SClaudiu Beznea	str	r7, [pmc, #AT91_PMC_SCDR]
8020567658SWenyou Yang
8120567658SWenyou Yang	dsb
8220567658SWenyou Yang
8320567658SWenyou Yang	wfi		@ Wait For Interrupt
8420567658SWenyou Yang#else
8520567658SWenyou Yang	mcr	p15, 0, tmp1, c7, c0, 4
8620567658SWenyou Yang#endif
8720567658SWenyou Yang
8820567658SWenyou Yang	.endm
8920567658SWenyou Yang
90475be50fSClaudiu Beznea/**
91475be50fSClaudiu Beznea * Set state for 2.5V low power regulator
92475be50fSClaudiu Beznea * @ena: 0 - disable regulator
93475be50fSClaudiu Beznea *	 1 - enable regulator
94475be50fSClaudiu Beznea *
95475be50fSClaudiu Beznea * Side effects: overwrites r7, r8, r9, r10
96475be50fSClaudiu Beznea */
97475be50fSClaudiu Beznea	.macro at91_2_5V_reg_set_low_power ena
98475be50fSClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
99475be50fSClaudiu Beznea	ldr	r7, .sfrbu
100475be50fSClaudiu Beznea	mov	r8, #\ena
101475be50fSClaudiu Beznea	ldr	r9, [r7, #AT91_SFRBU_25LDOCR]
102475be50fSClaudiu Beznea	orr	r9, r9, #AT91_SFRBU_25LDOCR_LP
103475be50fSClaudiu Beznea	cmp	r8, #1
104475be50fSClaudiu Beznea	beq	lp_done_\ena
105475be50fSClaudiu Beznea	bic	r9, r9, #AT91_SFRBU_25LDOCR_LP
106475be50fSClaudiu Beznealp_done_\ena:
107475be50fSClaudiu Beznea	ldr	r10, =AT91_SFRBU_25LDOCR_LDOANAKEY
108475be50fSClaudiu Beznea	orr	r9, r9, r10
109475be50fSClaudiu Beznea	str	r9, [r7, #AT91_SFRBU_25LDOCR]
110475be50fSClaudiu Beznea#endif
111475be50fSClaudiu Beznea	.endm
112475be50fSClaudiu Beznea
113f205adb6SClaudiu Beznea	.macro at91_backup_set_lpm reg
114f205adb6SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
115f205adb6SClaudiu Beznea	orr	\reg, \reg, #0x200000
116f205adb6SClaudiu Beznea#endif
117f205adb6SClaudiu Beznea	.endm
118f205adb6SClaudiu Beznea
119828b98faSWenyou Yang	.text
120828b98faSWenyou Yang
121828b98faSWenyou Yang	.arm
122828b98faSWenyou Yang
123f0bbf179SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
124f0bbf179SClaudiu Beznea/**
125f0bbf179SClaudiu Beznea * Enable self-refresh
126f0bbf179SClaudiu Beznea *
127f0bbf179SClaudiu Beznea * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7
128f0bbf179SClaudiu Beznea */
129f0bbf179SClaudiu Beznea.macro at91_sramc_self_refresh_ena
130f0bbf179SClaudiu Beznea	ldr	r2, .sramc_base
131f0bbf179SClaudiu Beznea	ldr	r3, .sramc_phy_base
132f0bbf179SClaudiu Beznea	ldr	r7, .pm_mode
133f0bbf179SClaudiu Beznea
134f0bbf179SClaudiu Beznea	dsb
135f0bbf179SClaudiu Beznea
136f0bbf179SClaudiu Beznea	/* Disable all AXI ports. */
137f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_0]
138f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #0x1
139f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_0]
140f0bbf179SClaudiu Beznea
141f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_1]
142f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #0x1
143f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_1]
144f0bbf179SClaudiu Beznea
145f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_2]
146f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #0x1
147f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_2]
148f0bbf179SClaudiu Beznea
149f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_3]
150f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #0x1
151f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_3]
152f0bbf179SClaudiu Beznea
153f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_4]
154f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #0x1
155f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_4]
156f0bbf179SClaudiu Beznea
157f0bbf179SClaudiu Bezneasr_ena_1:
158f0bbf179SClaudiu Beznea	/* Wait for all ports to disable. */
159f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PSTAT]
160f0bbf179SClaudiu Beznea	ldr	tmp2, =UDDRC_PSTAT_ALL_PORTS
161f0bbf179SClaudiu Beznea	tst	tmp1, tmp2
162f0bbf179SClaudiu Beznea	bne	sr_ena_1
163f0bbf179SClaudiu Beznea
164f0bbf179SClaudiu Beznea	/* Switch to self-refresh. */
165f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PWRCTL]
1669a0775c9SClaudiu Beznea	orr	tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
167f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PWRCTL]
168f0bbf179SClaudiu Beznea
169f0bbf179SClaudiu Bezneasr_ena_2:
170f0bbf179SClaudiu Beznea	/* Wait for self-refresh enter. */
171f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_STAT]
172f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK
173f0bbf179SClaudiu Beznea	cmp	tmp1, #UDDRC_STAT_SELFREF_TYPE_SW
174f0bbf179SClaudiu Beznea	bne	sr_ena_2
175f0bbf179SClaudiu Beznea
176cef8cdc0SClaudiu Beznea	/* Disable DX DLLs for non-backup modes. */
177f0bbf179SClaudiu Beznea	cmp	r7, #AT91_PM_BACKUP
178f0bbf179SClaudiu Beznea	beq	sr_ena_3
179a02875c4SClaudiu Beznea
180cef8cdc0SClaudiu Beznea	/* Do not soft reset the AC DLL. */
181cef8cdc0SClaudiu Beznea	ldr	tmp1, [r3, DDR3PHY_ACDLLCR]
182cef8cdc0SClaudiu Beznea	bic	tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST
183cef8cdc0SClaudiu Beznea	str	tmp1, [r3, DDR3PHY_ACDLLCR]
184cef8cdc0SClaudiu Beznea
185a02875c4SClaudiu Beznea	/* Disable DX DLLs. */
186a02875c4SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
187a02875c4SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
188a02875c4SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]
189a02875c4SClaudiu Beznea
190a02875c4SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
191a02875c4SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
192a02875c4SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]
193f0bbf179SClaudiu Beznea
194f0bbf179SClaudiu Bezneasr_ena_3:
195f0bbf179SClaudiu Beznea	/* Power down DDR PHY data receivers. */
196f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DXCCR]
197f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
198f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DXCCR]
199f0bbf179SClaudiu Beznea
200f0bbf179SClaudiu Beznea	/* Power down ADDR/CMD IO. */
201f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_ACIOCR]
202f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
203f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
204f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
205f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_ACIOCR]
206f0bbf179SClaudiu Beznea
207f0bbf179SClaudiu Beznea	/* Power down ODT. */
208f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DSGCR]
209f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
210f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DSGCR]
211f0bbf179SClaudiu Beznea.endm
212f0bbf179SClaudiu Beznea
213f0bbf179SClaudiu Beznea/**
214f0bbf179SClaudiu Beznea * Disable self-refresh
215f0bbf179SClaudiu Beznea *
216f0bbf179SClaudiu Beznea * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3
217f0bbf179SClaudiu Beznea */
218f0bbf179SClaudiu Beznea.macro at91_sramc_self_refresh_dis
219f0bbf179SClaudiu Beznea	ldr	r2, .sramc_base
220f0bbf179SClaudiu Beznea	ldr	r3, .sramc_phy_base
221f0bbf179SClaudiu Beznea
222f0bbf179SClaudiu Beznea	/* Power up DDR PHY data receivers. */
223f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DXCCR]
224f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
225f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DXCCR]
226f0bbf179SClaudiu Beznea
227f0bbf179SClaudiu Beznea	/* Power up the output of CK and CS pins. */
228f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_ACIOCR]
229f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
230f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
231f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
232f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_ACIOCR]
233f0bbf179SClaudiu Beznea
234f0bbf179SClaudiu Beznea	/* Power up ODT. */
235f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DSGCR]
236f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
237f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DSGCR]
238f0bbf179SClaudiu Beznea
239a02875c4SClaudiu Beznea	/* Enable DX DLLs. */
240a02875c4SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
241a02875c4SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
242a02875c4SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]
243a02875c4SClaudiu Beznea
244a02875c4SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
245a02875c4SClaudiu Beznea	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
246a02875c4SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]
247f0bbf179SClaudiu Beznea
248f0bbf179SClaudiu Beznea	/* Enable quasi-dynamic programming. */
249f0bbf179SClaudiu Beznea	mov	tmp1, #0
250f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_SWCTRL]
251f0bbf179SClaudiu Beznea
252f0bbf179SClaudiu Beznea	/* De-assert SDRAM initialization. */
253f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_DFIMISC]
254f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
255f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_DFIMISC]
256f0bbf179SClaudiu Beznea
257f0bbf179SClaudiu Beznea	/* Quasi-dynamic programming done. */
258f0bbf179SClaudiu Beznea	mov	tmp1, #UDDRC_SWCTRL_SW_DONE
259f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_SWCTRL]
260f0bbf179SClaudiu Beznea
261f0bbf179SClaudiu Bezneasr_dis_1:
262f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_SWSTAT]
263f0bbf179SClaudiu Beznea	tst	tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
264f0bbf179SClaudiu Beznea	beq	sr_dis_1
265f0bbf179SClaudiu Beznea
266f0bbf179SClaudiu Beznea	/* DLL soft-reset + DLL lock wait + ITM reset */
267f0bbf179SClaudiu Beznea	mov	tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \
268f0bbf179SClaudiu Beznea			DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST)
269f0bbf179SClaudiu Beznea	str	tmp1, [r3, #DDR3PHY_PIR]
270f0bbf179SClaudiu Beznea
271f0bbf179SClaudiu Bezneasr_dis_4:
272f0bbf179SClaudiu Beznea	/* Wait for it. */
273f0bbf179SClaudiu Beznea	ldr	tmp1, [r3, #DDR3PHY_PGSR]
274f0bbf179SClaudiu Beznea	tst	tmp1, #DDR3PHY_PGSR_IDONE
275f0bbf179SClaudiu Beznea	beq	sr_dis_4
276f0bbf179SClaudiu Beznea
277f0bbf179SClaudiu Beznea	/* Enable quasi-dynamic programming. */
278f0bbf179SClaudiu Beznea	mov	tmp1, #0
279f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_SWCTRL]
280f0bbf179SClaudiu Beznea
281f0bbf179SClaudiu Beznea	/* Assert PHY init complete enable signal. */
282f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_DFIMISC]
283f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
284f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_DFIMISC]
285f0bbf179SClaudiu Beznea
286f0bbf179SClaudiu Beznea	/* Programming is done. Set sw_done. */
287f0bbf179SClaudiu Beznea	mov	tmp1, #UDDRC_SWCTRL_SW_DONE
288f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_SWCTRL]
289f0bbf179SClaudiu Beznea
290f0bbf179SClaudiu Bezneasr_dis_5:
291f0bbf179SClaudiu Beznea	/* Wait for it. */
292f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_SWSTAT]
293f0bbf179SClaudiu Beznea	tst	tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
294f0bbf179SClaudiu Beznea	beq	sr_dis_5
295f0bbf179SClaudiu Beznea
296f0bbf179SClaudiu Beznea	/* Trigger self-refresh exit. */
297f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PWRCTL]
2989a0775c9SClaudiu Beznea	bic	tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
299f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PWRCTL]
300f0bbf179SClaudiu Beznea
301f0bbf179SClaudiu Bezneasr_dis_6:
302f0bbf179SClaudiu Beznea	/* Wait for self-refresh exit done. */
303f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_STAT]
304f0bbf179SClaudiu Beznea	bic	tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK
305f0bbf179SClaudiu Beznea	cmp	tmp1, #UDDRC_STAT_OPMODE_NORMAL
306f0bbf179SClaudiu Beznea	bne	sr_dis_6
307f0bbf179SClaudiu Beznea
308f0bbf179SClaudiu Beznea	/* Enable all AXI ports. */
309f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_0]
310f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #0x1
311f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_0]
312f0bbf179SClaudiu Beznea
313f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_1]
314f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #0x1
315f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_1]
316f0bbf179SClaudiu Beznea
317f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_2]
318f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #0x1
319f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_2]
320f0bbf179SClaudiu Beznea
321f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_3]
322f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #0x1
323f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_3]
324f0bbf179SClaudiu Beznea
325f0bbf179SClaudiu Beznea	ldr	tmp1, [r2, #UDDRC_PCTRL_4]
326f0bbf179SClaudiu Beznea	orr	tmp1, tmp1, #0x1
327f0bbf179SClaudiu Beznea	str	tmp1, [r2, #UDDRC_PCTRL_4]
328f0bbf179SClaudiu Beznea
329f0bbf179SClaudiu Beznea	dsb
330f0bbf179SClaudiu Beznea.endm
331f0bbf179SClaudiu Beznea#else
33287e1b30cSClaudiu Beznea/**
33387e1b30cSClaudiu Beznea * Enable self-refresh
33487e1b30cSClaudiu Beznea *
33587e1b30cSClaudiu Beznea * register usage:
33687e1b30cSClaudiu Beznea * 	@r1: memory type
33787e1b30cSClaudiu Beznea *	@r2: base address of the sram controller
33887e1b30cSClaudiu Beznea *	@r3: temporary
339828b98faSWenyou Yang */
34087e1b30cSClaudiu Beznea.macro at91_sramc_self_refresh_ena
34187e1b30cSClaudiu Beznea	ldr	r1, .memtype
34287e1b30cSClaudiu Beznea	ldr	r2, .sramc_base
343828b98faSWenyou Yang
34487e1b30cSClaudiu Beznea	cmp	r1, #AT91_MEMCTRL_MC
34587e1b30cSClaudiu Beznea	bne	sr_ena_ddrc_sf
346828b98faSWenyou Yang
34787e1b30cSClaudiu Beznea	/* Active SDRAM self-refresh mode */
34887e1b30cSClaudiu Beznea	mov	r3, #1
34987e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
35087e1b30cSClaudiu Beznea	b	sr_ena_exit
351828b98faSWenyou Yang
35287e1b30cSClaudiu Bezneasr_ena_ddrc_sf:
35387e1b30cSClaudiu Beznea	cmp	r1, #AT91_MEMCTRL_DDRSDR
35487e1b30cSClaudiu Beznea	bne	sr_ena_sdramc_sf
355828b98faSWenyou Yang
35687e1b30cSClaudiu Beznea	/*
35787e1b30cSClaudiu Beznea	 * DDR Memory controller
35887e1b30cSClaudiu Beznea	 */
359828b98faSWenyou Yang
36087e1b30cSClaudiu Beznea	/* LPDDR1 --> force DDR2 mode during self-refresh */
36187e1b30cSClaudiu Beznea	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
36287e1b30cSClaudiu Beznea	str	r3, .saved_sam9_mdr
36387e1b30cSClaudiu Beznea	bic	r3, r3, #~AT91_DDRSDRC_MD
36487e1b30cSClaudiu Beznea	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
36587e1b30cSClaudiu Beznea	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
36687e1b30cSClaudiu Beznea	biceq	r3, r3, #AT91_DDRSDRC_MD
36787e1b30cSClaudiu Beznea	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
36887e1b30cSClaudiu Beznea	streq	r3, [r2, #AT91_DDRSDRC_MDR]
3695b56c182SWenyou Yang
37087e1b30cSClaudiu Beznea	/* Active DDRC self-refresh mode */
37187e1b30cSClaudiu Beznea	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
37287e1b30cSClaudiu Beznea	str	r3, .saved_sam9_lpr
37387e1b30cSClaudiu Beznea	bic	r3, r3, #AT91_DDRSDRC_LPCB
37487e1b30cSClaudiu Beznea	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
37587e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_DDRSDRC_LPR]
37624a0f5c5SAlexandre Belloni
37787e1b30cSClaudiu Beznea	/* If using the 2nd ddr controller */
37887e1b30cSClaudiu Beznea	ldr	r2, .sramc1_base
37987e1b30cSClaudiu Beznea	cmp	r2, #0
38087e1b30cSClaudiu Beznea	beq	sr_ena_no_2nd_ddrc
38124a0f5c5SAlexandre Belloni
38287e1b30cSClaudiu Beznea	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
38387e1b30cSClaudiu Beznea	str	r3, .saved_sam9_mdr1
38487e1b30cSClaudiu Beznea	bic	r3, r3, #~AT91_DDRSDRC_MD
38587e1b30cSClaudiu Beznea	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
38687e1b30cSClaudiu Beznea	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
38787e1b30cSClaudiu Beznea	biceq	r3, r3, #AT91_DDRSDRC_MD
38887e1b30cSClaudiu Beznea	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
38987e1b30cSClaudiu Beznea	streq	r3, [r2, #AT91_DDRSDRC_MDR]
39024a0f5c5SAlexandre Belloni
39187e1b30cSClaudiu Beznea	/* Active DDRC self-refresh mode */
39287e1b30cSClaudiu Beznea	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
39387e1b30cSClaudiu Beznea	str	r3, .saved_sam9_lpr1
39487e1b30cSClaudiu Beznea	bic	r3, r3, #AT91_DDRSDRC_LPCB
39587e1b30cSClaudiu Beznea	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
39687e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_DDRSDRC_LPR]
39724a0f5c5SAlexandre Belloni
39887e1b30cSClaudiu Bezneasr_ena_no_2nd_ddrc:
39987e1b30cSClaudiu Beznea	b	sr_ena_exit
4009f7195daSClaudiu Beznea
40187e1b30cSClaudiu Beznea	/*
40287e1b30cSClaudiu Beznea	 * SDRAMC Memory controller
40387e1b30cSClaudiu Beznea	 */
40487e1b30cSClaudiu Bezneasr_ena_sdramc_sf:
40587e1b30cSClaudiu Beznea	/* Active SDRAMC self-refresh mode */
40687e1b30cSClaudiu Beznea	ldr	r3, [r2, #AT91_SDRAMC_LPR]
40787e1b30cSClaudiu Beznea	str	r3, .saved_sam9_lpr
40887e1b30cSClaudiu Beznea	bic	r3, r3, #AT91_SDRAMC_LPCB
40987e1b30cSClaudiu Beznea	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
41087e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_SDRAMC_LPR]
4119f7195daSClaudiu Beznea
41287e1b30cSClaudiu Beznea	ldr	r3, .saved_sam9_lpr
41387e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_SDRAMC_LPR]
41424a0f5c5SAlexandre Belloni
41587e1b30cSClaudiu Bezneasr_ena_exit:
41687e1b30cSClaudiu Beznea.endm
41787e1b30cSClaudiu Beznea
41887e1b30cSClaudiu Beznea/**
41987e1b30cSClaudiu Beznea * Disable self-refresh
42087e1b30cSClaudiu Beznea *
42187e1b30cSClaudiu Beznea * register usage:
42287e1b30cSClaudiu Beznea * 	@r1: memory type
42387e1b30cSClaudiu Beznea *	@r2: base address of the sram controller
42487e1b30cSClaudiu Beznea *	@r3: temporary
42587e1b30cSClaudiu Beznea */
42687e1b30cSClaudiu Beznea.macro at91_sramc_self_refresh_dis
42787e1b30cSClaudiu Beznea	ldr	r1, .memtype
42887e1b30cSClaudiu Beznea	ldr	r2, .sramc_base
42987e1b30cSClaudiu Beznea
43087e1b30cSClaudiu Beznea	cmp	r1, #AT91_MEMCTRL_MC
43187e1b30cSClaudiu Beznea	bne	sr_dis_ddrc_exit_sf
43287e1b30cSClaudiu Beznea
43387e1b30cSClaudiu Beznea	/*
43487e1b30cSClaudiu Beznea	 * at91rm9200 Memory controller
43587e1b30cSClaudiu Beznea	 */
43687e1b30cSClaudiu Beznea
43787e1b30cSClaudiu Beznea	 /*
43887e1b30cSClaudiu Beznea	  * For exiting the self-refresh mode, do nothing,
43987e1b30cSClaudiu Beznea	  * automatically exit the self-refresh mode.
44087e1b30cSClaudiu Beznea	  */
44187e1b30cSClaudiu Beznea	b	sr_dis_exit
44287e1b30cSClaudiu Beznea
44387e1b30cSClaudiu Bezneasr_dis_ddrc_exit_sf:
44487e1b30cSClaudiu Beznea	cmp	r1, #AT91_MEMCTRL_DDRSDR
44587e1b30cSClaudiu Beznea	bne	sdramc_exit_sf
44687e1b30cSClaudiu Beznea
44787e1b30cSClaudiu Beznea	/* DDR Memory controller */
44887e1b30cSClaudiu Beznea
44987e1b30cSClaudiu Beznea	/* Restore MDR in case of LPDDR1 */
45087e1b30cSClaudiu Beznea	ldr	r3, .saved_sam9_mdr
45187e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_DDRSDRC_MDR]
45287e1b30cSClaudiu Beznea	/* Restore LPR on AT91 with DDRAM */
45387e1b30cSClaudiu Beznea	ldr	r3, .saved_sam9_lpr
45487e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_DDRSDRC_LPR]
45587e1b30cSClaudiu Beznea
45687e1b30cSClaudiu Beznea	/* If using the 2nd ddr controller */
45787e1b30cSClaudiu Beznea	ldr	r2, .sramc1_base
45887e1b30cSClaudiu Beznea	cmp	r2, #0
45987e1b30cSClaudiu Beznea	ldrne	r3, .saved_sam9_mdr1
46087e1b30cSClaudiu Beznea	strne	r3, [r2, #AT91_DDRSDRC_MDR]
46187e1b30cSClaudiu Beznea	ldrne	r3, .saved_sam9_lpr1
46287e1b30cSClaudiu Beznea	strne	r3, [r2, #AT91_DDRSDRC_LPR]
46387e1b30cSClaudiu Beznea
46487e1b30cSClaudiu Beznea	b	sr_dis_exit
46587e1b30cSClaudiu Beznea
46687e1b30cSClaudiu Bezneasdramc_exit_sf:
46787e1b30cSClaudiu Beznea	/* SDRAMC Memory controller */
46887e1b30cSClaudiu Beznea	ldr	r3, .saved_sam9_lpr
46987e1b30cSClaudiu Beznea	str	r3, [r2, #AT91_SDRAMC_LPR]
47087e1b30cSClaudiu Beznea
47187e1b30cSClaudiu Bezneasr_dis_exit:
47287e1b30cSClaudiu Beznea.endm
473f0bbf179SClaudiu Beznea#endif
47424a0f5c5SAlexandre Belloni
4755b56c182SWenyou Yang.macro at91_pm_ulp0_mode
4765b56c182SWenyou Yang	ldr	pmc, .pmc_base
477e70bfc2fSClaudiu Beznea	ldr	tmp2, .pm_mode
478e70bfc2fSClaudiu Beznea	ldr	tmp3, .mckr_offset
4795b56c182SWenyou Yang
480e70bfc2fSClaudiu Beznea	/* Check if ULP0 fast variant has been requested. */
481e70bfc2fSClaudiu Beznea	cmp	tmp2, #AT91_PM_ULP0_FAST
482e70bfc2fSClaudiu Beznea	bne	0f
483e70bfc2fSClaudiu Beznea
484e70bfc2fSClaudiu Beznea	/* Set highest prescaler for power saving */
485e70bfc2fSClaudiu Beznea	ldr	tmp1, [pmc, tmp3]
486e70bfc2fSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PRES
487e70bfc2fSClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PRES_64
488e70bfc2fSClaudiu Beznea	str	tmp1, [pmc, tmp3]
48915126bb6SClaudiu Beznea
49015126bb6SClaudiu Beznea	mov	tmp3, #0
49115126bb6SClaudiu Beznea	wait_mckrdy tmp3
492e70bfc2fSClaudiu Beznea	b	1f
493e70bfc2fSClaudiu Beznea
494e70bfc2fSClaudiu Beznea0:
4955b56c182SWenyou Yang	/* Turn off the crystal oscillator */
4965b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
4975b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
4985b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
4995b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
5005b56c182SWenyou Yang
501bc0779bdSClaudiu Beznea	/* Save RC oscillator state */
502bc0779bdSClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_SR]
503bc0779bdSClaudiu Beznea	str	tmp1, .saved_osc_status
504bc0779bdSClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
505bc0779bdSClaudiu Beznea	bne	1f
506bc0779bdSClaudiu Beznea
507bc0779bdSClaudiu Beznea	/* Turn off RC oscillator */
508bc0779bdSClaudiu Beznea	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
509bc0779bdSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
510bc0779bdSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
511bc0779bdSClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_KEY
512bc0779bdSClaudiu Beznea	str	tmp1, [pmc, #AT91_CKGR_MOR]
513bc0779bdSClaudiu Beznea
514bc0779bdSClaudiu Beznea	/* Wait main RC disabled done */
515bc0779bdSClaudiu Beznea2:	ldr	tmp1, [pmc, #AT91_PMC_SR]
516bc0779bdSClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
517bc0779bdSClaudiu Beznea	bne	2b
518bc0779bdSClaudiu Beznea
5195b56c182SWenyou Yang	/* Wait for interrupt */
520bc0779bdSClaudiu Beznea1:	at91_cpu_idle
521bc0779bdSClaudiu Beznea
522e70bfc2fSClaudiu Beznea	/* Check if ULP0 fast variant has been requested. */
523e70bfc2fSClaudiu Beznea	cmp	tmp2, #AT91_PM_ULP0_FAST
524e70bfc2fSClaudiu Beznea	bne	5f
525e70bfc2fSClaudiu Beznea
526e70bfc2fSClaudiu Beznea	/* Set lowest prescaler for fast resume. */
52715126bb6SClaudiu Beznea	ldr	tmp3, .mckr_offset
528e70bfc2fSClaudiu Beznea	ldr	tmp1, [pmc, tmp3]
529e70bfc2fSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PRES
530e70bfc2fSClaudiu Beznea	str	tmp1, [pmc, tmp3]
53115126bb6SClaudiu Beznea
53215126bb6SClaudiu Beznea	mov	tmp3, #0
53315126bb6SClaudiu Beznea	wait_mckrdy tmp3
534e70bfc2fSClaudiu Beznea	b	6f
535e70bfc2fSClaudiu Beznea
536e70bfc2fSClaudiu Beznea5:	/* Restore RC oscillator state */
537bc0779bdSClaudiu Beznea	ldr	tmp1, .saved_osc_status
538bc0779bdSClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
539bc0779bdSClaudiu Beznea	beq	4f
540bc0779bdSClaudiu Beznea
541bc0779bdSClaudiu Beznea	/* Turn on RC oscillator */
542bc0779bdSClaudiu Beznea	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
543bc0779bdSClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
544bc0779bdSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
545bc0779bdSClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_KEY
546bc0779bdSClaudiu Beznea	str	tmp1, [pmc, #AT91_CKGR_MOR]
547bc0779bdSClaudiu Beznea
548bc0779bdSClaudiu Beznea	/* Wait main RC stabilization */
549bc0779bdSClaudiu Beznea3:	ldr	tmp1, [pmc, #AT91_PMC_SR]
550bc0779bdSClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
551bc0779bdSClaudiu Beznea	beq	3b
5525b56c182SWenyou Yang
5535b56c182SWenyou Yang	/* Turn on the crystal oscillator */
554bc0779bdSClaudiu Beznea4:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
5555b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
5565b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
5575b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
5585b56c182SWenyou Yang
5595b56c182SWenyou Yang	wait_moscrdy
560e70bfc2fSClaudiu Beznea6:
5615b56c182SWenyou Yang.endm
5625b56c182SWenyou Yang
5635b56c182SWenyou Yang/**
5645b56c182SWenyou Yang * Note: This procedure only applies on the platform which uses
5655b56c182SWenyou Yang * the external crystal oscillator as a main clock source.
5665b56c182SWenyou Yang */
5675b56c182SWenyou Yang.macro at91_pm_ulp1_mode
5685b56c182SWenyou Yang	ldr	pmc, .pmc_base
5696ec1587bSClaudiu Beznea	ldr	tmp2, .mckr_offset
57015126bb6SClaudiu Beznea	mov	tmp3, #0
5715b56c182SWenyou Yang
572eaedc0d3SClaudiu Beznea	/* Save RC oscillator state and check if it is enabled. */
573eaedc0d3SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_SR]
574eaedc0d3SClaudiu Beznea	str	tmp1, .saved_osc_status
575eaedc0d3SClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
576eaedc0d3SClaudiu Beznea	bne	2f
577eaedc0d3SClaudiu Beznea
578eaedc0d3SClaudiu Beznea	/* Enable RC oscillator */
5795b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
580eaedc0d3SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
581eaedc0d3SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
582eaedc0d3SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_KEY
583eaedc0d3SClaudiu Beznea	str	tmp1, [pmc, #AT91_CKGR_MOR]
584eaedc0d3SClaudiu Beznea
585eaedc0d3SClaudiu Beznea	/* Wait main RC stabilization */
586eaedc0d3SClaudiu Beznea1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
587eaedc0d3SClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
588eaedc0d3SClaudiu Beznea	beq	1b
589eaedc0d3SClaudiu Beznea
590eaedc0d3SClaudiu Beznea	/* Switch the main clock source to 12-MHz RC oscillator */
591eaedc0d3SClaudiu Beznea2:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
5925b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_MOSCSEL
5935b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
5945b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
5955b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
5965b56c182SWenyou Yang
5975b56c182SWenyou Yang	wait_moscsels
5985b56c182SWenyou Yang
5995b56c182SWenyou Yang	/* Disable the crystal oscillator */
6005b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
6015b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
6025b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
6035b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
6045b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
6055b56c182SWenyou Yang
6065b56c182SWenyou Yang	/* Switch the master clock source to main clock */
6076ec1587bSClaudiu Beznea	ldr	tmp1, [pmc, tmp2]
6085b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_CSS
6095b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
6106ec1587bSClaudiu Beznea	str	tmp1, [pmc, tmp2]
6115b56c182SWenyou Yang
61215126bb6SClaudiu Beznea	wait_mckrdy tmp3
6135b56c182SWenyou Yang
6145b56c182SWenyou Yang	/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
6155b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
6165b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
6175b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
6185b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
6195b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
6205b56c182SWenyou Yang
621bb1a0e87SClaudiu Beznea	/* Quirk for SAM9X60's PMC */
622bb1a0e87SClaudiu Beznea	nop
623bb1a0e87SClaudiu Beznea	nop
624bb1a0e87SClaudiu Beznea
62515126bb6SClaudiu Beznea	wait_mckrdy tmp3
6265b56c182SWenyou Yang
6275b56c182SWenyou Yang	/* Enable the crystal oscillator */
6285b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
6295b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
6305b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
6315b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
6325b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
6335b56c182SWenyou Yang
6345b56c182SWenyou Yang	wait_moscrdy
6355b56c182SWenyou Yang
6365b56c182SWenyou Yang	/* Switch the master clock source to slow clock */
6376ec1587bSClaudiu Beznea	ldr	tmp1, [pmc, tmp2]
6385b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_CSS
6396ec1587bSClaudiu Beznea	str	tmp1, [pmc, tmp2]
6405b56c182SWenyou Yang
64115126bb6SClaudiu Beznea	wait_mckrdy tmp3
6425b56c182SWenyou Yang
6435b56c182SWenyou Yang	/* Switch main clock source to crystal oscillator */
6445b56c182SWenyou Yang	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
6455b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
6465b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
6475b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_KEY
6485b56c182SWenyou Yang	str	tmp1, [pmc, #AT91_CKGR_MOR]
6495b56c182SWenyou Yang
6505b56c182SWenyou Yang	wait_moscsels
6515b56c182SWenyou Yang
6525b56c182SWenyou Yang	/* Switch the master clock source to main clock */
6536ec1587bSClaudiu Beznea	ldr	tmp1, [pmc, tmp2]
6545b56c182SWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_CSS
6555b56c182SWenyou Yang	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
6566ec1587bSClaudiu Beznea	str	tmp1, [pmc, tmp2]
6575b56c182SWenyou Yang
65815126bb6SClaudiu Beznea	wait_mckrdy tmp3
659eaedc0d3SClaudiu Beznea
660eaedc0d3SClaudiu Beznea	/* Restore RC oscillator state */
661eaedc0d3SClaudiu Beznea	ldr	tmp1, .saved_osc_status
662eaedc0d3SClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
663eaedc0d3SClaudiu Beznea	bne	3f
664eaedc0d3SClaudiu Beznea
665eaedc0d3SClaudiu Beznea	/* Disable RC oscillator */
666eaedc0d3SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
667eaedc0d3SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
668eaedc0d3SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
669eaedc0d3SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_KEY
670eaedc0d3SClaudiu Beznea	str	tmp1, [pmc, #AT91_CKGR_MOR]
671eaedc0d3SClaudiu Beznea
672eaedc0d3SClaudiu Beznea	/* Wait RC oscillator disable done */
673eaedc0d3SClaudiu Beznea4:	ldr	tmp1, [pmc, #AT91_PMC_SR]
674eaedc0d3SClaudiu Beznea	tst	tmp1, #AT91_PMC_MOSCRCS
675eaedc0d3SClaudiu Beznea	bne	4b
676eaedc0d3SClaudiu Beznea
677eaedc0d3SClaudiu Beznea3:
6785b56c182SWenyou Yang.endm
6795b56c182SWenyou Yang
68063d1a6b1SClaudiu Beznea.macro at91_plla_disable
68163d1a6b1SClaudiu Beznea	/* Save PLLA setting and disable it */
6824fd36e45SClaudiu Beznea	ldr	tmp1, .pmc_version
6834fd36e45SClaudiu Beznea	cmp	tmp1, #AT91_PMC_V1
6844fd36e45SClaudiu Beznea	beq	1f
6854fd36e45SClaudiu Beznea
686e3821ed4SClaudiu Beznea#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL
6874fd36e45SClaudiu Beznea	/* Save PLLA settings. */
6884fd36e45SClaudiu Beznea	ldr	tmp2, [pmc, #AT91_PMC_PLL_UPDT]
6894fd36e45SClaudiu Beznea	bic	tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
6904fd36e45SClaudiu Beznea	str	tmp2, [pmc, #AT91_PMC_PLL_UPDT]
6914fd36e45SClaudiu Beznea
6924fd36e45SClaudiu Beznea	/* save div. */
6934fd36e45SClaudiu Beznea	mov	tmp1, #0
6944fd36e45SClaudiu Beznea	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
6954fd36e45SClaudiu Beznea	bic	tmp2, tmp2, #0xffffff00
6964fd36e45SClaudiu Beznea	orr	tmp1, tmp1, tmp2
6974fd36e45SClaudiu Beznea
6984fd36e45SClaudiu Beznea	/* save mul. */
6994fd36e45SClaudiu Beznea	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
7004fd36e45SClaudiu Beznea	bic	tmp2, tmp2, #0xffffff
7014fd36e45SClaudiu Beznea	orr	tmp1, tmp1, tmp2
7024fd36e45SClaudiu Beznea	str	tmp1, .saved_pllar
7034fd36e45SClaudiu Beznea
7044fd36e45SClaudiu Beznea	/* step 2. */
7054fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7064fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7074fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7084fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7094fd36e45SClaudiu Beznea
7104fd36e45SClaudiu Beznea	/* step 3. */
7114fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7124fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
7134fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
7144fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7154fd36e45SClaudiu Beznea
7164fd36e45SClaudiu Beznea	/* step 4. */
7174fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7184fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7194fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7204fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7214fd36e45SClaudiu Beznea
7224fd36e45SClaudiu Beznea	/* step 5. */
7234fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7244fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
7254fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7264fd36e45SClaudiu Beznea
7274fd36e45SClaudiu Beznea	/* step 7. */
7284fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7294fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7304fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7314fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7324fd36e45SClaudiu Beznea
7334fd36e45SClaudiu Beznea	b	2f
7344fd36e45SClaudiu Beznea#endif
7354fd36e45SClaudiu Beznea
7364fd36e45SClaudiu Beznea1:	/* Save PLLA setting and disable it */
73763d1a6b1SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
73863d1a6b1SClaudiu Beznea	str	tmp1, .saved_pllar
73963d1a6b1SClaudiu Beznea
74063d1a6b1SClaudiu Beznea	/* Disable PLLA. */
74163d1a6b1SClaudiu Beznea	mov	tmp1, #AT91_PMC_PLLCOUNT
74263d1a6b1SClaudiu Beznea	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
74363d1a6b1SClaudiu Beznea	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
7444fd36e45SClaudiu Beznea2:
74563d1a6b1SClaudiu Beznea.endm
74663d1a6b1SClaudiu Beznea
74763d1a6b1SClaudiu Beznea.macro at91_plla_enable
7484fd36e45SClaudiu Beznea	ldr	tmp2, .saved_pllar
7494fd36e45SClaudiu Beznea	ldr	tmp3, .pmc_version
7504fd36e45SClaudiu Beznea	cmp	tmp3, #AT91_PMC_V1
7514fd36e45SClaudiu Beznea	beq	4f
7524fd36e45SClaudiu Beznea
753e3821ed4SClaudiu Beznea#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL
7544fd36e45SClaudiu Beznea	/* step 1. */
7554fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7564fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7574fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7584fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7594fd36e45SClaudiu Beznea
7604fd36e45SClaudiu Beznea	/* step 2. */
761d30337daSArnd Bergmann	ldr	tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA
7624fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_ACR]
7634fd36e45SClaudiu Beznea
7644fd36e45SClaudiu Beznea	/* step 3. */
7654fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
7664fd36e45SClaudiu Beznea	mov	tmp3, tmp2
7674fd36e45SClaudiu Beznea	bic	tmp3, tmp3, #0xffffff
7684fd36e45SClaudiu Beznea	orr	tmp1, tmp1, tmp3
7694fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
7704fd36e45SClaudiu Beznea
7714fd36e45SClaudiu Beznea	/* step 8. */
7724fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7734fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7744fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7754fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7764fd36e45SClaudiu Beznea
7774fd36e45SClaudiu Beznea	/* step 9. */
7784fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7794fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
7804fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
7814fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
7824fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #0xff
7834fd36e45SClaudiu Beznea	mov	tmp3, tmp2
7844fd36e45SClaudiu Beznea	bic	tmp3, tmp3, #0xffffff00
7854fd36e45SClaudiu Beznea	orr	tmp1, tmp1, tmp3
7864fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
7874fd36e45SClaudiu Beznea
7884fd36e45SClaudiu Beznea	/* step 10. */
7894fd36e45SClaudiu Beznea	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7904fd36e45SClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
7914fd36e45SClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
7924fd36e45SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
7934fd36e45SClaudiu Beznea
7944fd36e45SClaudiu Beznea	/* step 11. */
7954fd36e45SClaudiu Beznea3:	ldr	tmp1, [pmc, #AT91_PMC_PLL_ISR0]
7964fd36e45SClaudiu Beznea	tst	tmp1, #0x1
7974fd36e45SClaudiu Beznea	beq	3b
7984fd36e45SClaudiu Beznea	b	2f
7994fd36e45SClaudiu Beznea#endif
8004fd36e45SClaudiu Beznea
80163d1a6b1SClaudiu Beznea	/* Restore PLLA setting */
8024fd36e45SClaudiu Beznea4:	str	tmp2, [pmc, #AT91_CKGR_PLLAR]
80363d1a6b1SClaudiu Beznea
80463d1a6b1SClaudiu Beznea	/* Enable PLLA. */
8054fd36e45SClaudiu Beznea	tst	tmp2, #(AT91_PMC_MUL &  0xff0000)
80663d1a6b1SClaudiu Beznea	bne	1f
8074fd36e45SClaudiu Beznea	tst	tmp2, #(AT91_PMC_MUL & ~0xff0000)
80863d1a6b1SClaudiu Beznea	beq	2f
80963d1a6b1SClaudiu Beznea
81063d1a6b1SClaudiu Beznea1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
81163d1a6b1SClaudiu Beznea	tst	tmp1, #AT91_PMC_LOCKA
81263d1a6b1SClaudiu Beznea	beq	1b
81363d1a6b1SClaudiu Beznea2:
81463d1a6b1SClaudiu Beznea.endm
81563d1a6b1SClaudiu Beznea
81628eb1d40SClaudiu Beznea/**
81728eb1d40SClaudiu Beznea * at91_mckx_ps_enable:	save MCK1..4 settings and switch it to main clock
81828eb1d40SClaudiu Beznea *
81928eb1d40SClaudiu Beznea * Side effects: overwrites tmp1, tmp2
82028eb1d40SClaudiu Beznea */
82128eb1d40SClaudiu Beznea.macro at91_mckx_ps_enable
82228eb1d40SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
82328eb1d40SClaudiu Beznea	ldr	pmc, .pmc_base
82428eb1d40SClaudiu Beznea
82528eb1d40SClaudiu Beznea	/* There are 4 MCKs we need to handle: MCK1..4 */
82628eb1d40SClaudiu Beznea	mov	tmp1, #1
82728eb1d40SClaudiu Bezneae_loop:	cmp	tmp1, #5
82828eb1d40SClaudiu Beznea	beq	e_done
82928eb1d40SClaudiu Beznea
83028eb1d40SClaudiu Beznea	/* Write MCK ID to retrieve the settings. */
83128eb1d40SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_MCR_V2]
83228eb1d40SClaudiu Beznea	ldr	tmp2, [pmc, #AT91_PMC_MCR_V2]
83328eb1d40SClaudiu Beznea
83428eb1d40SClaudiu Bezneae_save_mck1:
83528eb1d40SClaudiu Beznea	cmp	tmp1, #1
83628eb1d40SClaudiu Beznea	bne	e_save_mck2
83728eb1d40SClaudiu Beznea	str	tmp2, .saved_mck1
83828eb1d40SClaudiu Beznea	b	e_ps
83928eb1d40SClaudiu Beznea
84028eb1d40SClaudiu Bezneae_save_mck2:
84128eb1d40SClaudiu Beznea	cmp	tmp1, #2
84228eb1d40SClaudiu Beznea	bne	e_save_mck3
84328eb1d40SClaudiu Beznea	str	tmp2, .saved_mck2
84428eb1d40SClaudiu Beznea	b	e_ps
84528eb1d40SClaudiu Beznea
84628eb1d40SClaudiu Bezneae_save_mck3:
84728eb1d40SClaudiu Beznea	cmp	tmp1, #3
84828eb1d40SClaudiu Beznea	bne	e_save_mck4
84928eb1d40SClaudiu Beznea	str	tmp2, .saved_mck3
85028eb1d40SClaudiu Beznea	b	e_ps
85128eb1d40SClaudiu Beznea
85228eb1d40SClaudiu Bezneae_save_mck4:
85328eb1d40SClaudiu Beznea	str	tmp2, .saved_mck4
85428eb1d40SClaudiu Beznea
85528eb1d40SClaudiu Bezneae_ps:
85628eb1d40SClaudiu Beznea	/* Use CSS=MAINCK and DIV=1. */
85728eb1d40SClaudiu Beznea	bic	tmp2, tmp2, #AT91_PMC_MCR_V2_CSS
85828eb1d40SClaudiu Beznea	bic	tmp2, tmp2, #AT91_PMC_MCR_V2_DIV
85928eb1d40SClaudiu Beznea	orr	tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MAINCK
86028eb1d40SClaudiu Beznea	orr	tmp2, tmp2, #AT91_PMC_MCR_V2_DIV1
86128eb1d40SClaudiu Beznea	str	tmp2, [pmc, #AT91_PMC_MCR_V2]
86228eb1d40SClaudiu Beznea
86328eb1d40SClaudiu Beznea	wait_mckrdy tmp1
86428eb1d40SClaudiu Beznea
86528eb1d40SClaudiu Beznea	add	tmp1, tmp1, #1
86628eb1d40SClaudiu Beznea	b	e_loop
86728eb1d40SClaudiu Beznea
86828eb1d40SClaudiu Bezneae_done:
86928eb1d40SClaudiu Beznea#endif
87028eb1d40SClaudiu Beznea.endm
87128eb1d40SClaudiu Beznea
87228eb1d40SClaudiu Beznea/**
87328eb1d40SClaudiu Beznea * at91_mckx_ps_restore: restore MCK1..4 settings
87428eb1d40SClaudiu Beznea *
87528eb1d40SClaudiu Beznea * Side effects: overwrites tmp1, tmp2
87628eb1d40SClaudiu Beznea */
87728eb1d40SClaudiu Beznea.macro at91_mckx_ps_restore
87828eb1d40SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
87928eb1d40SClaudiu Beznea	ldr	pmc, .pmc_base
88028eb1d40SClaudiu Beznea
88128eb1d40SClaudiu Beznea	/* There are 4 MCKs we need to handle: MCK1..4 */
88228eb1d40SClaudiu Beznea	mov	tmp1, #1
88328eb1d40SClaudiu Beznear_loop:	cmp	tmp1, #5
88428eb1d40SClaudiu Beznea	beq	r_done
88528eb1d40SClaudiu Beznea
88628eb1d40SClaudiu Beznear_save_mck1:
88728eb1d40SClaudiu Beznea	cmp	tmp1, #1
88828eb1d40SClaudiu Beznea	bne	r_save_mck2
88928eb1d40SClaudiu Beznea	ldr	tmp2, .saved_mck1
89028eb1d40SClaudiu Beznea	b	r_ps
89128eb1d40SClaudiu Beznea
89228eb1d40SClaudiu Beznear_save_mck2:
89328eb1d40SClaudiu Beznea	cmp	tmp1, #2
89428eb1d40SClaudiu Beznea	bne	r_save_mck3
89528eb1d40SClaudiu Beznea	ldr	tmp2, .saved_mck2
89628eb1d40SClaudiu Beznea	b	r_ps
89728eb1d40SClaudiu Beznea
89828eb1d40SClaudiu Beznear_save_mck3:
89928eb1d40SClaudiu Beznea	cmp	tmp1, #3
90028eb1d40SClaudiu Beznea	bne	r_save_mck4
90128eb1d40SClaudiu Beznea	ldr	tmp2, .saved_mck3
90228eb1d40SClaudiu Beznea	b	r_ps
90328eb1d40SClaudiu Beznea
90428eb1d40SClaudiu Beznear_save_mck4:
90528eb1d40SClaudiu Beznea	ldr	tmp2, .saved_mck4
90628eb1d40SClaudiu Beznea
90728eb1d40SClaudiu Beznear_ps:
90828eb1d40SClaudiu Beznea	/* Write MCK ID to retrieve the settings. */
90928eb1d40SClaudiu Beznea	str	tmp1, [pmc, #AT91_PMC_MCR_V2]
91028eb1d40SClaudiu Beznea	ldr	tmp3, [pmc, #AT91_PMC_MCR_V2]
91128eb1d40SClaudiu Beznea
91228eb1d40SClaudiu Beznea	/* We need to restore CSS and DIV. */
91328eb1d40SClaudiu Beznea	bic	tmp3, tmp3, #AT91_PMC_MCR_V2_CSS
91428eb1d40SClaudiu Beznea	bic	tmp3, tmp3, #AT91_PMC_MCR_V2_DIV
91528eb1d40SClaudiu Beznea	orr	tmp3, tmp3, tmp2
91628eb1d40SClaudiu Beznea	bic	tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK
91728eb1d40SClaudiu Beznea	orr	tmp3, tmp3, tmp1
91828eb1d40SClaudiu Beznea	orr	tmp3, tmp3, #AT91_PMC_MCR_V2_CMD
91928eb1d40SClaudiu Beznea	str	tmp2, [pmc, #AT91_PMC_MCR_V2]
92028eb1d40SClaudiu Beznea
92128eb1d40SClaudiu Beznea	wait_mckrdy tmp1
92228eb1d40SClaudiu Beznea
92328eb1d40SClaudiu Beznea	add	tmp1, tmp1, #1
92428eb1d40SClaudiu Beznea	b	r_loop
92528eb1d40SClaudiu Beznear_done:
92628eb1d40SClaudiu Beznea#endif
92728eb1d40SClaudiu Beznea.endm
92828eb1d40SClaudiu Beznea
92987e1b30cSClaudiu Beznea.macro at91_ulp_mode
93028eb1d40SClaudiu Beznea	at91_mckx_ps_enable
93128eb1d40SClaudiu Beznea
932828b98faSWenyou Yang	ldr	pmc, .pmc_base
9336ec1587bSClaudiu Beznea	ldr	tmp2, .mckr_offset
934e70bfc2fSClaudiu Beznea	ldr	tmp3, .pm_mode
935828b98faSWenyou Yang
936828b98faSWenyou Yang	/* Save Master clock setting */
9376ec1587bSClaudiu Beznea	ldr	tmp1, [pmc, tmp2]
938828b98faSWenyou Yang	str	tmp1, .saved_mckr
939828b98faSWenyou Yang
940828b98faSWenyou Yang	/*
941e70bfc2fSClaudiu Beznea	 * Set master clock source to:
942e70bfc2fSClaudiu Beznea	 * - MAINCK if using ULP0 fast variant
943e70bfc2fSClaudiu Beznea	 * - slow clock, otherwise
944828b98faSWenyou Yang	 */
945828b98faSWenyou Yang	bic	tmp1, tmp1, #AT91_PMC_CSS
946e70bfc2fSClaudiu Beznea	cmp	tmp3, #AT91_PM_ULP0_FAST
947e70bfc2fSClaudiu Beznea	bne	save_mck
948e70bfc2fSClaudiu Beznea	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
949e70bfc2fSClaudiu Bezneasave_mck:
9506ec1587bSClaudiu Beznea	str	tmp1, [pmc, tmp2]
951828b98faSWenyou Yang
95215126bb6SClaudiu Beznea	mov	tmp3, #0
95315126bb6SClaudiu Beznea	wait_mckrdy tmp3
954828b98faSWenyou Yang
95563d1a6b1SClaudiu Beznea	at91_plla_disable
956c4cae59dSClaudiu Beznea
957475be50fSClaudiu Beznea	/* Enable low power mode for 2.5V regulator. */
958475be50fSClaudiu Beznea	at91_2_5V_reg_set_low_power 1
959475be50fSClaudiu Beznea
96015126bb6SClaudiu Beznea	ldr	tmp3, .pm_mode
961e70bfc2fSClaudiu Beznea	cmp	tmp3, #AT91_PM_ULP1
9625b56c182SWenyou Yang	beq	ulp1_mode
963828b98faSWenyou Yang
9645b56c182SWenyou Yang	at91_pm_ulp0_mode
9655b56c182SWenyou Yang	b	ulp_exit
966828b98faSWenyou Yang
9675b56c182SWenyou Yangulp1_mode:
9685b56c182SWenyou Yang	at91_pm_ulp1_mode
9695b56c182SWenyou Yang	b	ulp_exit
970828b98faSWenyou Yang
9715b56c182SWenyou Yangulp_exit:
972475be50fSClaudiu Beznea	/* Disable low power mode for 2.5V regulator. */
973475be50fSClaudiu Beznea	at91_2_5V_reg_set_low_power 0
974475be50fSClaudiu Beznea
9755b56c182SWenyou Yang	ldr	pmc, .pmc_base
976828b98faSWenyou Yang
97763d1a6b1SClaudiu Beznea	at91_plla_enable
978c4cae59dSClaudiu Beznea
979828b98faSWenyou Yang	/*
980828b98faSWenyou Yang	 * Restore master clock setting
981828b98faSWenyou Yang	 */
9826ec1587bSClaudiu Beznea	ldr	tmp1, .mckr_offset
9836ec1587bSClaudiu Beznea	ldr	tmp2, .saved_mckr
9846ec1587bSClaudiu Beznea	str	tmp2, [pmc, tmp1]
985828b98faSWenyou Yang
98615126bb6SClaudiu Beznea	mov	tmp3, #0
98715126bb6SClaudiu Beznea	wait_mckrdy tmp3
988828b98faSWenyou Yang
98928eb1d40SClaudiu Beznea	at91_mckx_ps_restore
99087e1b30cSClaudiu Beznea.endm
99187e1b30cSClaudiu Beznea
99287e1b30cSClaudiu Beznea.macro at91_backup_mode
99387e1b30cSClaudiu Beznea	/* Switch the master clock source to slow clock. */
99487e1b30cSClaudiu Beznea	ldr	pmc, .pmc_base
99587e1b30cSClaudiu Beznea	ldr	tmp2, .mckr_offset
99687e1b30cSClaudiu Beznea	ldr	tmp1, [pmc, tmp2]
99787e1b30cSClaudiu Beznea	bic	tmp1, tmp1, #AT91_PMC_CSS
99887e1b30cSClaudiu Beznea	str	tmp1, [pmc, tmp2]
99987e1b30cSClaudiu Beznea
100015126bb6SClaudiu Beznea	mov	tmp3, #0
100115126bb6SClaudiu Beznea	wait_mckrdy tmp3
100287e1b30cSClaudiu Beznea
100387e1b30cSClaudiu Beznea	/*BUMEN*/
100487e1b30cSClaudiu Beznea	ldr	r0, .sfrbu
100587e1b30cSClaudiu Beznea	mov	tmp1, #0x1
100687e1b30cSClaudiu Beznea	str	tmp1, [r0, #0x10]
100787e1b30cSClaudiu Beznea
10085b0bef87SClaudiu Beznea	/* Wait for it. */
10095b0bef87SClaudiu Beznea1:	ldr	tmp1, [r0, #0x10]
10105b0bef87SClaudiu Beznea	tst	tmp1, #0x1
10115b0bef87SClaudiu Beznea	beq	1b
10125b0bef87SClaudiu Beznea
101387e1b30cSClaudiu Beznea	/* Shutdown */
101487e1b30cSClaudiu Beznea	ldr	r0, .shdwc
101587e1b30cSClaudiu Beznea	mov	tmp1, #0xA5000000
101687e1b30cSClaudiu Beznea	add	tmp1, tmp1, #0x1
1017f205adb6SClaudiu Beznea	at91_backup_set_lpm tmp1
101887e1b30cSClaudiu Beznea	str	tmp1, [r0, #0]
101987e1b30cSClaudiu Beznea.endm
1020828b98faSWenyou Yang
1021828b98faSWenyou Yang/*
102287e1b30cSClaudiu Beznea * void at91_suspend_sram_fn(struct at91_pm_data*)
1023828b98faSWenyou Yang * @input param:
102487e1b30cSClaudiu Beznea * 	@r0: base address of struct at91_pm_data
1025828b98faSWenyou Yang */
102687e1b30cSClaudiu Beznea/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
102787e1b30cSClaudiu Beznea	.align 3
102887e1b30cSClaudiu BezneaENTRY(at91_pm_suspend_in_sram)
102987e1b30cSClaudiu Beznea	/* Save registers on stack */
103087e1b30cSClaudiu Beznea	stmfd	sp!, {r4 - r12, lr}
1031828b98faSWenyou Yang
103287e1b30cSClaudiu Beznea	/* Drain write buffer */
103387e1b30cSClaudiu Beznea	mov	tmp1, #0
103487e1b30cSClaudiu Beznea	mcr	p15, 0, tmp1, c7, c10, 4
1035828b98faSWenyou Yang
1036d8d667eeSClaudiu Beznea	/* Flush tlb. */
1037d8d667eeSClaudiu Beznea	mov	r4, #0
1038d8d667eeSClaudiu Beznea	mcr	p15, 0, r4, c8, c7, 0
1039d8d667eeSClaudiu Beznea
1040e42cbbe5SClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
1041e42cbbe5SClaudiu Beznea	str	tmp1, .mckr_offset
1042e42cbbe5SClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_PMC_VERSION]
1043e42cbbe5SClaudiu Beznea	str	tmp1, .pmc_version
1044e42cbbe5SClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
1045e42cbbe5SClaudiu Beznea	str	tmp1, .memtype
1046e42cbbe5SClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_MODE]
1047e42cbbe5SClaudiu Beznea	str	tmp1, .pm_mode
1048e42cbbe5SClaudiu Beznea
1049d8d667eeSClaudiu Beznea	/*
1050d8d667eeSClaudiu Beznea	 * ldrne below are here to preload their address in the TLB as access
1051d8d667eeSClaudiu Beznea	 * to RAM may be limited while in self-refresh.
1052d8d667eeSClaudiu Beznea	 */
105387e1b30cSClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_PMC]
105487e1b30cSClaudiu Beznea	str	tmp1, .pmc_base
1055d8d667eeSClaudiu Beznea	cmp	tmp1, #0
1056d8d667eeSClaudiu Beznea	ldrne	tmp2, [tmp1, #0]
1057d8d667eeSClaudiu Beznea
105887e1b30cSClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_RAMC0]
105987e1b30cSClaudiu Beznea	str	tmp1, .sramc_base
1060d8d667eeSClaudiu Beznea	cmp	tmp1, #0
1061d8d667eeSClaudiu Beznea	ldrne	tmp2, [tmp1, #0]
1062d8d667eeSClaudiu Beznea
106387e1b30cSClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_RAMC1]
106487e1b30cSClaudiu Beznea	str	tmp1, .sramc1_base
1065d8d667eeSClaudiu Beznea	cmp	tmp1, #0
1066d8d667eeSClaudiu Beznea	ldrne	tmp2, [tmp1, #0]
1067d8d667eeSClaudiu Beznea
1068d8d667eeSClaudiu Beznea#ifndef CONFIG_SOC_SAM_V4_V5
1069d8d667eeSClaudiu Beznea	/* ldrne below are here to preload their address in the TLB */
1070f0bbf179SClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_RAMC_PHY]
1071f0bbf179SClaudiu Beznea	str	tmp1, .sramc_phy_base
1072d8d667eeSClaudiu Beznea	cmp	tmp1, #0
1073d8d667eeSClaudiu Beznea	ldrne	tmp2, [tmp1, #0]
1074d8d667eeSClaudiu Beznea
107587e1b30cSClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_SHDWC]
107687e1b30cSClaudiu Beznea	str	tmp1, .shdwc
107787e1b30cSClaudiu Beznea	cmp	tmp1, #0
107887e1b30cSClaudiu Beznea	ldrne	tmp2, [tmp1, #0]
1079d8d667eeSClaudiu Beznea
108087e1b30cSClaudiu Beznea	ldr	tmp1, [r0, #PM_DATA_SFRBU]
108187e1b30cSClaudiu Beznea	str	tmp1, .sfrbu
108287e1b30cSClaudiu Beznea	cmp	tmp1, #0
108387e1b30cSClaudiu Beznea	ldrne	tmp2, [tmp1, #0x10]
1084d8d667eeSClaudiu Beznea#endif
1085828b98faSWenyou Yang
108687e1b30cSClaudiu Beznea	/* Active the self-refresh mode */
108787e1b30cSClaudiu Beznea	at91_sramc_self_refresh_ena
1088828b98faSWenyou Yang
108987e1b30cSClaudiu Beznea	ldr	r0, .pm_mode
109087e1b30cSClaudiu Beznea	cmp	r0, #AT91_PM_STANDBY
109187e1b30cSClaudiu Beznea	beq	standby
109287e1b30cSClaudiu Beznea	cmp	r0, #AT91_PM_BACKUP
109387e1b30cSClaudiu Beznea	beq	backup_mode
1094828b98faSWenyou Yang
109587e1b30cSClaudiu Beznea	at91_ulp_mode
109687e1b30cSClaudiu Beznea	b	exit_suspend
1097828b98faSWenyou Yang
109887e1b30cSClaudiu Bezneastandby:
109987e1b30cSClaudiu Beznea	/* Wait for interrupt */
110087e1b30cSClaudiu Beznea	ldr	pmc, .pmc_base
110187e1b30cSClaudiu Beznea	at91_cpu_idle
110287e1b30cSClaudiu Beznea	b	exit_suspend
1103828b98faSWenyou Yang
110487e1b30cSClaudiu Bezneabackup_mode:
110587e1b30cSClaudiu Beznea	at91_backup_mode
1106828b98faSWenyou Yang
110787e1b30cSClaudiu Bezneaexit_suspend:
110887e1b30cSClaudiu Beznea	/* Exit the self-refresh mode */
110987e1b30cSClaudiu Beznea	at91_sramc_self_refresh_dis
1110828b98faSWenyou Yang
111187e1b30cSClaudiu Beznea	/* Restore registers, and return */
111287e1b30cSClaudiu Beznea	ldmfd	sp!, {r4 - r12, pc}
111387e1b30cSClaudiu BezneaENDPROC(at91_pm_suspend_in_sram)
1114828b98faSWenyou Yang
1115828b98faSWenyou Yang.pmc_base:
1116828b98faSWenyou Yang	.word 0
1117828b98faSWenyou Yang.sramc_base:
1118828b98faSWenyou Yang	.word 0
1119828b98faSWenyou Yang.sramc1_base:
1120828b98faSWenyou Yang	.word 0
1121f0bbf179SClaudiu Beznea.sramc_phy_base:
1122f0bbf179SClaudiu Beznea	.word 0
112324a0f5c5SAlexandre Belloni.shdwc:
112424a0f5c5SAlexandre Belloni	.word 0
11254a877560SClaudiu Beznea.sfrbu:
112624a0f5c5SAlexandre Belloni	.word 0
1127828b98faSWenyou Yang.memtype:
1128828b98faSWenyou Yang	.word 0
1129828b98faSWenyou Yang.pm_mode:
1130828b98faSWenyou Yang	.word 0
11316ec1587bSClaudiu Beznea.mckr_offset:
11326ec1587bSClaudiu Beznea	.word 0
11330be298a9SClaudiu Beznea.pmc_version:
11340be298a9SClaudiu Beznea	.word 0
1135828b98faSWenyou Yang.saved_mckr:
1136828b98faSWenyou Yang	.word 0
1137c4cae59dSClaudiu Beznea.saved_pllar:
1138c4cae59dSClaudiu Beznea	.word 0
1139828b98faSWenyou Yang.saved_sam9_lpr:
1140828b98faSWenyou Yang	.word 0
1141828b98faSWenyou Yang.saved_sam9_lpr1:
1142828b98faSWenyou Yang	.word 0
1143828b98faSWenyou Yang.saved_sam9_mdr:
1144828b98faSWenyou Yang	.word 0
1145828b98faSWenyou Yang.saved_sam9_mdr1:
1146828b98faSWenyou Yang	.word 0
1147eaedc0d3SClaudiu Beznea.saved_osc_status:
1148eaedc0d3SClaudiu Beznea	.word 0
114928eb1d40SClaudiu Beznea#ifdef CONFIG_SOC_SAMA7
115028eb1d40SClaudiu Beznea.saved_mck1:
115128eb1d40SClaudiu Beznea	.word 0
115228eb1d40SClaudiu Beznea.saved_mck2:
115328eb1d40SClaudiu Beznea	.word 0
115428eb1d40SClaudiu Beznea.saved_mck3:
115528eb1d40SClaudiu Beznea	.word 0
115628eb1d40SClaudiu Beznea.saved_mck4:
115728eb1d40SClaudiu Beznea	.word 0
115828eb1d40SClaudiu Beznea#endif
1159828b98faSWenyou Yang
11605726a8b9SWenyou YangENTRY(at91_pm_suspend_in_sram_sz)
11615726a8b9SWenyou Yang	.word .-at91_pm_suspend_in_sram
1162