18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * arch/arm/mach-at91/pm_slow_clock.S
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2006 Savin Zlobec
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * AT91SAM9 support:
88c2ecf20Sopenharmony_ci *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci#include <linux/linkage.h>
118c2ecf20Sopenharmony_ci#include <linux/clk/at91_pmc.h>
128c2ecf20Sopenharmony_ci#include "pm.h"
138c2ecf20Sopenharmony_ci#include "pm_data-offsets.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define	SRAMC_SELF_FRESH_ACTIVE		0x01
168c2ecf20Sopenharmony_ci#define	SRAMC_SELF_FRESH_EXIT		0x00
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cipmc	.req	r0
198c2ecf20Sopenharmony_citmp1	.req	r4
208c2ecf20Sopenharmony_citmp2	.req	r5
218c2ecf20Sopenharmony_citmp3	.req	r6
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * Wait until master clock is ready (after switching master clock source)
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci	.macro wait_mckrdy
278c2ecf20Sopenharmony_ci1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
288c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MCKRDY
298c2ecf20Sopenharmony_ci	beq	1b
308c2ecf20Sopenharmony_ci	.endm
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci * Wait until master oscillator has stabilized.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ci	.macro wait_moscrdy
368c2ecf20Sopenharmony_ci1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
378c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCS
388c2ecf20Sopenharmony_ci	beq	1b
398c2ecf20Sopenharmony_ci	.endm
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/*
428c2ecf20Sopenharmony_ci * Wait for main oscillator selection is done
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_ci	.macro wait_moscsels
458c2ecf20Sopenharmony_ci1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
468c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCSELS
478c2ecf20Sopenharmony_ci	beq	1b
488c2ecf20Sopenharmony_ci	.endm
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/*
518c2ecf20Sopenharmony_ci * Put the processor to enter the idle state
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_ci	.macro at91_cpu_idle
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_V7)
568c2ecf20Sopenharmony_ci	mov	tmp1, #AT91_PMC_PCK
578c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_SCDR]
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	dsb
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	wfi		@ Wait For Interrupt
628c2ecf20Sopenharmony_ci#else
638c2ecf20Sopenharmony_ci	mcr	p15, 0, tmp1, c7, c0, 4
648c2ecf20Sopenharmony_ci#endif
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	.endm
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	.text
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	.arm
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/*
738c2ecf20Sopenharmony_ci * void at91_suspend_sram_fn(struct at91_pm_data*)
748c2ecf20Sopenharmony_ci * @input param:
758c2ecf20Sopenharmony_ci * 	@r0: base address of struct at91_pm_data
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ci/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
788c2ecf20Sopenharmony_ci	.align 3
798c2ecf20Sopenharmony_ciENTRY(at91_pm_suspend_in_sram)
808c2ecf20Sopenharmony_ci	/* Save registers on stack */
818c2ecf20Sopenharmony_ci	stmfd	sp!, {r4 - r12, lr}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	/* Drain write buffer */
848c2ecf20Sopenharmony_ci	mov	tmp1, #0
858c2ecf20Sopenharmony_ci	mcr	p15, 0, tmp1, c7, c10, 4
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_PMC]
888c2ecf20Sopenharmony_ci	str	tmp1, .pmc_base
898c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_RAMC0]
908c2ecf20Sopenharmony_ci	str	tmp1, .sramc_base
918c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_RAMC1]
928c2ecf20Sopenharmony_ci	str	tmp1, .sramc1_base
938c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
948c2ecf20Sopenharmony_ci	str	tmp1, .memtype
958c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_MODE]
968c2ecf20Sopenharmony_ci	str	tmp1, .pm_mode
978c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
988c2ecf20Sopenharmony_ci	str	tmp1, .mckr_offset
998c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_PMC_VERSION]
1008c2ecf20Sopenharmony_ci	str	tmp1, .pmc_version
1018c2ecf20Sopenharmony_ci	/* Both ldrne below are here to preload their address in the TLB */
1028c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_SHDWC]
1038c2ecf20Sopenharmony_ci	str	tmp1, .shdwc
1048c2ecf20Sopenharmony_ci	cmp	tmp1, #0
1058c2ecf20Sopenharmony_ci	ldrne	tmp2, [tmp1, #0]
1068c2ecf20Sopenharmony_ci	ldr	tmp1, [r0, #PM_DATA_SFRBU]
1078c2ecf20Sopenharmony_ci	str	tmp1, .sfrbu
1088c2ecf20Sopenharmony_ci	cmp	tmp1, #0
1098c2ecf20Sopenharmony_ci	ldrne	tmp2, [tmp1, #0x10]
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	/* Active the self-refresh mode */
1128c2ecf20Sopenharmony_ci	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
1138c2ecf20Sopenharmony_ci	bl	at91_sramc_self_refresh
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	ldr	r0, .pm_mode
1168c2ecf20Sopenharmony_ci	cmp	r0, #AT91_PM_STANDBY
1178c2ecf20Sopenharmony_ci	beq	standby
1188c2ecf20Sopenharmony_ci	cmp	r0, #AT91_PM_BACKUP
1198c2ecf20Sopenharmony_ci	beq	backup_mode
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	bl	at91_ulp_mode
1228c2ecf20Sopenharmony_ci	b	exit_suspend
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistandby:
1258c2ecf20Sopenharmony_ci	/* Wait for interrupt */
1268c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
1278c2ecf20Sopenharmony_ci	at91_cpu_idle
1288c2ecf20Sopenharmony_ci	b	exit_suspend
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cibackup_mode:
1318c2ecf20Sopenharmony_ci	bl	at91_backup_mode
1328c2ecf20Sopenharmony_ci	b	exit_suspend
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciexit_suspend:
1358c2ecf20Sopenharmony_ci	/* Exit the self-refresh mode */
1368c2ecf20Sopenharmony_ci	mov	r0, #SRAMC_SELF_FRESH_EXIT
1378c2ecf20Sopenharmony_ci	bl	at91_sramc_self_refresh
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	/* Restore registers, and return */
1408c2ecf20Sopenharmony_ci	ldmfd	sp!, {r4 - r12, pc}
1418c2ecf20Sopenharmony_ciENDPROC(at91_pm_suspend_in_sram)
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ciENTRY(at91_backup_mode)
1448c2ecf20Sopenharmony_ci	/* Switch the master clock source to slow clock. */
1458c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
1468c2ecf20Sopenharmony_ci	ldr	tmp2, .mckr_offset
1478c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp2]
1488c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_CSS
1498c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp2]
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	wait_mckrdy
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	/*BUMEN*/
1548c2ecf20Sopenharmony_ci	ldr	r0, .sfrbu
1558c2ecf20Sopenharmony_ci	mov	tmp1, #0x1
1568c2ecf20Sopenharmony_ci	str	tmp1, [r0, #0x10]
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/* Shutdown */
1598c2ecf20Sopenharmony_ci	ldr	r0, .shdwc
1608c2ecf20Sopenharmony_ci	mov	tmp1, #0xA5000000
1618c2ecf20Sopenharmony_ci	add	tmp1, tmp1, #0x1
1628c2ecf20Sopenharmony_ci	str	tmp1, [r0, #0]
1638c2ecf20Sopenharmony_ciENDPROC(at91_backup_mode)
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci.macro at91_pm_ulp0_mode
1668c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
1678c2ecf20Sopenharmony_ci	ldr	tmp2, .pm_mode
1688c2ecf20Sopenharmony_ci	ldr	tmp3, .mckr_offset
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	/* Check if ULP0 fast variant has been requested. */
1718c2ecf20Sopenharmony_ci	cmp	tmp2, #AT91_PM_ULP0_FAST
1728c2ecf20Sopenharmony_ci	bne	0f
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	/* Set highest prescaler for power saving */
1758c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp3]
1768c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PRES
1778c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PRES_64
1788c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp3]
1798c2ecf20Sopenharmony_ci	wait_mckrdy
1808c2ecf20Sopenharmony_ci	b	1f
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci0:
1838c2ecf20Sopenharmony_ci	/* Turn off the crystal oscillator */
1848c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
1858c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
1868c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
1878c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	/* Save RC oscillator state */
1908c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_SR]
1918c2ecf20Sopenharmony_ci	str	tmp1, .saved_osc_status
1928c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
1938c2ecf20Sopenharmony_ci	bne	1f
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	/* Turn off RC oscillator */
1968c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
1978c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
1988c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
1998c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2008c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/* Wait main RC disabled done */
2038c2ecf20Sopenharmony_ci2:	ldr	tmp1, [pmc, #AT91_PMC_SR]
2048c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
2058c2ecf20Sopenharmony_ci	bne	2b
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	/* Wait for interrupt */
2088c2ecf20Sopenharmony_ci1:	at91_cpu_idle
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	/* Check if ULP0 fast variant has been requested. */
2118c2ecf20Sopenharmony_ci	cmp	tmp2, #AT91_PM_ULP0_FAST
2128c2ecf20Sopenharmony_ci	bne	5f
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/* Set lowest prescaler for fast resume. */
2158c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp3]
2168c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PRES
2178c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp3]
2188c2ecf20Sopenharmony_ci	wait_mckrdy
2198c2ecf20Sopenharmony_ci	b	6f
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci5:	/* Restore RC oscillator state */
2228c2ecf20Sopenharmony_ci	ldr	tmp1, .saved_osc_status
2238c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
2248c2ecf20Sopenharmony_ci	beq	4f
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	/* Turn on RC oscillator */
2278c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
2288c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
2298c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
2308c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2318c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	/* Wait main RC stabilization */
2348c2ecf20Sopenharmony_ci3:	ldr	tmp1, [pmc, #AT91_PMC_SR]
2358c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
2368c2ecf20Sopenharmony_ci	beq	3b
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	/* Turn on the crystal oscillator */
2398c2ecf20Sopenharmony_ci4:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
2408c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
2418c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2428c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	wait_moscrdy
2458c2ecf20Sopenharmony_ci6:
2468c2ecf20Sopenharmony_ci.endm
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci/**
2498c2ecf20Sopenharmony_ci * Note: This procedure only applies on the platform which uses
2508c2ecf20Sopenharmony_ci * the external crystal oscillator as a main clock source.
2518c2ecf20Sopenharmony_ci */
2528c2ecf20Sopenharmony_ci.macro at91_pm_ulp1_mode
2538c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
2548c2ecf20Sopenharmony_ci	ldr	tmp2, .mckr_offset
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	/* Save RC oscillator state and check if it is enabled. */
2578c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_SR]
2588c2ecf20Sopenharmony_ci	str	tmp1, .saved_osc_status
2598c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
2608c2ecf20Sopenharmony_ci	bne	2f
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	/* Enable RC oscillator */
2638c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
2648c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_MOSCRCEN
2658c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
2668c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2678c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	/* Wait main RC stabilization */
2708c2ecf20Sopenharmony_ci1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
2718c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
2728c2ecf20Sopenharmony_ci	beq	1b
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	/* Switch the main clock source to 12-MHz RC oscillator */
2758c2ecf20Sopenharmony_ci2:	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
2768c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_MOSCSEL
2778c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
2788c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2798c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	wait_moscsels
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	/* Disable the crystal oscillator */
2848c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
2858c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
2868c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
2878c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
2888c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	/* Switch the master clock source to main clock */
2918c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp2]
2928c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_CSS
2938c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
2948c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp2]
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	wait_mckrdy
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
2998c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
3008c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
3018c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
3028c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
3038c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	/* Quirk for SAM9X60's PMC */
3068c2ecf20Sopenharmony_ci	nop
3078c2ecf20Sopenharmony_ci	nop
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	wait_mckrdy
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	/* Enable the crystal oscillator */
3128c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
3138c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
3148c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
3158c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
3168c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	wait_moscrdy
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci	/* Switch the master clock source to slow clock */
3218c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp2]
3228c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_CSS
3238c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp2]
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	wait_mckrdy
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	/* Switch main clock source to crystal oscillator */
3288c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
3298c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
3308c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
3318c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
3328c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	wait_moscsels
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	/* Switch the master clock source to main clock */
3378c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp2]
3388c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_CSS
3398c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
3408c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp2]
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	wait_mckrdy
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	/* Restore RC oscillator state */
3458c2ecf20Sopenharmony_ci	ldr	tmp1, .saved_osc_status
3468c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
3478c2ecf20Sopenharmony_ci	bne	3f
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	/* Disable RC oscillator */
3508c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
3518c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_MOSCRCEN
3528c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
3538c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_KEY
3548c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_MOR]
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	/* Wait RC oscillator disable done */
3578c2ecf20Sopenharmony_ci4:	ldr	tmp1, [pmc, #AT91_PMC_SR]
3588c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_MOSCRCS
3598c2ecf20Sopenharmony_ci	bne	4b
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci3:
3628c2ecf20Sopenharmony_ci.endm
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci.macro at91_plla_disable
3658c2ecf20Sopenharmony_ci	/* Save PLLA setting and disable it */
3668c2ecf20Sopenharmony_ci	ldr	tmp1, .pmc_version
3678c2ecf20Sopenharmony_ci	cmp	tmp1, #AT91_PMC_V1
3688c2ecf20Sopenharmony_ci	beq	1f
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_SAM9X60
3718c2ecf20Sopenharmony_ci	/* Save PLLA settings. */
3728c2ecf20Sopenharmony_ci	ldr	tmp2, [pmc, #AT91_PMC_PLL_UPDT]
3738c2ecf20Sopenharmony_ci	bic	tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
3748c2ecf20Sopenharmony_ci	str	tmp2, [pmc, #AT91_PMC_PLL_UPDT]
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	/* save div. */
3778c2ecf20Sopenharmony_ci	mov	tmp1, #0
3788c2ecf20Sopenharmony_ci	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
3798c2ecf20Sopenharmony_ci	bic	tmp2, tmp2, #0xffffff00
3808c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, tmp2
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	/* save mul. */
3838c2ecf20Sopenharmony_ci	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
3848c2ecf20Sopenharmony_ci	bic	tmp2, tmp2, #0xffffff
3858c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, tmp2
3868c2ecf20Sopenharmony_ci	str	tmp1, .saved_pllar
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	/* step 2. */
3898c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
3908c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
3918c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
3928c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	/* step 3. */
3958c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
3968c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
3978c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
3988c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	/* step 4. */
4018c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4028c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
4038c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
4048c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	/* step 5. */
4078c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
4088c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
4098c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	/* step 7. */
4128c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4138c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
4148c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
4158c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci	b	2f
4188c2ecf20Sopenharmony_ci#endif
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci1:	/* Save PLLA setting and disable it */
4218c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
4228c2ecf20Sopenharmony_ci	str	tmp1, .saved_pllar
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	/* Disable PLLA. */
4258c2ecf20Sopenharmony_ci	mov	tmp1, #AT91_PMC_PLLCOUNT
4268c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
4278c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
4288c2ecf20Sopenharmony_ci2:
4298c2ecf20Sopenharmony_ci.endm
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci.macro at91_plla_enable
4328c2ecf20Sopenharmony_ci	ldr	tmp2, .saved_pllar
4338c2ecf20Sopenharmony_ci	ldr	tmp3, .pmc_version
4348c2ecf20Sopenharmony_ci	cmp	tmp3, #AT91_PMC_V1
4358c2ecf20Sopenharmony_ci	beq	4f
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_SAM9X60
4388c2ecf20Sopenharmony_ci	/* step 1. */
4398c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4408c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
4418c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
4428c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	/* step 2. */
4458c2ecf20Sopenharmony_ci	ldr	tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA
4468c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_ACR]
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	/* step 3. */
4498c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
4508c2ecf20Sopenharmony_ci	mov	tmp3, tmp2
4518c2ecf20Sopenharmony_ci	bic	tmp3, tmp3, #0xffffff
4528c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, tmp3
4538c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	/* step 8. */
4568c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4578c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
4588c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
4598c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	/* step 9. */
4628c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
4638c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
4648c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
4658c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
4668c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #0xff
4678c2ecf20Sopenharmony_ci	mov	tmp3, tmp2
4688c2ecf20Sopenharmony_ci	bic	tmp3, tmp3, #0xffffff00
4698c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, tmp3
4708c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	/* step 10. */
4738c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4748c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
4758c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
4768c2ecf20Sopenharmony_ci	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	/* step 11. */
4798c2ecf20Sopenharmony_ci3:	ldr	tmp1, [pmc, #AT91_PMC_PLL_ISR0]
4808c2ecf20Sopenharmony_ci	tst	tmp1, #0x1
4818c2ecf20Sopenharmony_ci	beq	3b
4828c2ecf20Sopenharmony_ci	b	2f
4838c2ecf20Sopenharmony_ci#endif
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	/* Restore PLLA setting */
4868c2ecf20Sopenharmony_ci4:	str	tmp2, [pmc, #AT91_CKGR_PLLAR]
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	/* Enable PLLA. */
4898c2ecf20Sopenharmony_ci	tst	tmp2, #(AT91_PMC_MUL &  0xff0000)
4908c2ecf20Sopenharmony_ci	bne	1f
4918c2ecf20Sopenharmony_ci	tst	tmp2, #(AT91_PMC_MUL & ~0xff0000)
4928c2ecf20Sopenharmony_ci	beq	2f
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
4958c2ecf20Sopenharmony_ci	tst	tmp1, #AT91_PMC_LOCKA
4968c2ecf20Sopenharmony_ci	beq	1b
4978c2ecf20Sopenharmony_ci2:
4988c2ecf20Sopenharmony_ci.endm
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ciENTRY(at91_ulp_mode)
5018c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
5028c2ecf20Sopenharmony_ci	ldr	tmp2, .mckr_offset
5038c2ecf20Sopenharmony_ci	ldr	tmp3, .pm_mode
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	/* Save Master clock setting */
5068c2ecf20Sopenharmony_ci	ldr	tmp1, [pmc, tmp2]
5078c2ecf20Sopenharmony_ci	str	tmp1, .saved_mckr
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	/*
5108c2ecf20Sopenharmony_ci	 * Set master clock source to:
5118c2ecf20Sopenharmony_ci	 * - MAINCK if using ULP0 fast variant
5128c2ecf20Sopenharmony_ci	 * - slow clock, otherwise
5138c2ecf20Sopenharmony_ci	 */
5148c2ecf20Sopenharmony_ci	bic	tmp1, tmp1, #AT91_PMC_CSS
5158c2ecf20Sopenharmony_ci	cmp	tmp3, #AT91_PM_ULP0_FAST
5168c2ecf20Sopenharmony_ci	bne	save_mck
5178c2ecf20Sopenharmony_ci	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
5188c2ecf20Sopenharmony_cisave_mck:
5198c2ecf20Sopenharmony_ci	str	tmp1, [pmc, tmp2]
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci	wait_mckrdy
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	at91_plla_disable
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci	cmp	tmp3, #AT91_PM_ULP1
5268c2ecf20Sopenharmony_ci	beq	ulp1_mode
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	at91_pm_ulp0_mode
5298c2ecf20Sopenharmony_ci	b	ulp_exit
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ciulp1_mode:
5328c2ecf20Sopenharmony_ci	at91_pm_ulp1_mode
5338c2ecf20Sopenharmony_ci	b	ulp_exit
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ciulp_exit:
5368c2ecf20Sopenharmony_ci	ldr	pmc, .pmc_base
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	at91_plla_enable
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_ci	/*
5418c2ecf20Sopenharmony_ci	 * Restore master clock setting
5428c2ecf20Sopenharmony_ci	 */
5438c2ecf20Sopenharmony_ci	ldr	tmp1, .mckr_offset
5448c2ecf20Sopenharmony_ci	ldr	tmp2, .saved_mckr
5458c2ecf20Sopenharmony_ci	str	tmp2, [pmc, tmp1]
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	wait_mckrdy
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci	mov	pc, lr
5508c2ecf20Sopenharmony_ciENDPROC(at91_ulp_mode)
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci/*
5538c2ecf20Sopenharmony_ci * void at91_sramc_self_refresh(unsigned int is_active)
5548c2ecf20Sopenharmony_ci *
5558c2ecf20Sopenharmony_ci * @input param:
5568c2ecf20Sopenharmony_ci *	@r0: 1 - active self-refresh mode
5578c2ecf20Sopenharmony_ci *	     0 - exit self-refresh mode
5588c2ecf20Sopenharmony_ci * register usage:
5598c2ecf20Sopenharmony_ci * 	@r1: memory type
5608c2ecf20Sopenharmony_ci *	@r2: base address of the sram controller
5618c2ecf20Sopenharmony_ci */
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ciENTRY(at91_sramc_self_refresh)
5648c2ecf20Sopenharmony_ci	ldr	r1, .memtype
5658c2ecf20Sopenharmony_ci	ldr	r2, .sramc_base
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	cmp	r1, #AT91_MEMCTRL_MC
5688c2ecf20Sopenharmony_ci	bne	ddrc_sf
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_ci	/*
5718c2ecf20Sopenharmony_ci	 * at91rm9200 Memory controller
5728c2ecf20Sopenharmony_ci	 */
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	 /*
5758c2ecf20Sopenharmony_ci	  * For exiting the self-refresh mode, do nothing,
5768c2ecf20Sopenharmony_ci	  * automatically exit the self-refresh mode.
5778c2ecf20Sopenharmony_ci	  */
5788c2ecf20Sopenharmony_ci	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
5798c2ecf20Sopenharmony_ci	beq	exit_sramc_sf
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	/* Active SDRAM self-refresh mode */
5828c2ecf20Sopenharmony_ci	mov	r3, #1
5838c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_MC_SDRAMC_SRR]
5848c2ecf20Sopenharmony_ci	b	exit_sramc_sf
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ciddrc_sf:
5878c2ecf20Sopenharmony_ci	cmp	r1, #AT91_MEMCTRL_DDRSDR
5888c2ecf20Sopenharmony_ci	bne	sdramc_sf
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	/*
5918c2ecf20Sopenharmony_ci	 * DDR Memory controller
5928c2ecf20Sopenharmony_ci	 */
5938c2ecf20Sopenharmony_ci	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
5948c2ecf20Sopenharmony_ci	beq	ddrc_exit_sf
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci	/* LPDDR1 --> force DDR2 mode during self-refresh */
5978c2ecf20Sopenharmony_ci	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
5988c2ecf20Sopenharmony_ci	str	r3, .saved_sam9_mdr
5998c2ecf20Sopenharmony_ci	bic	r3, r3, #~AT91_DDRSDRC_MD
6008c2ecf20Sopenharmony_ci	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
6018c2ecf20Sopenharmony_ci	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
6028c2ecf20Sopenharmony_ci	biceq	r3, r3, #AT91_DDRSDRC_MD
6038c2ecf20Sopenharmony_ci	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
6048c2ecf20Sopenharmony_ci	streq	r3, [r2, #AT91_DDRSDRC_MDR]
6058c2ecf20Sopenharmony_ci
6068c2ecf20Sopenharmony_ci	/* Active DDRC self-refresh mode */
6078c2ecf20Sopenharmony_ci	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
6088c2ecf20Sopenharmony_ci	str	r3, .saved_sam9_lpr
6098c2ecf20Sopenharmony_ci	bic	r3, r3, #AT91_DDRSDRC_LPCB
6108c2ecf20Sopenharmony_ci	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
6118c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_DDRSDRC_LPR]
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci	/* If using the 2nd ddr controller */
6148c2ecf20Sopenharmony_ci	ldr	r2, .sramc1_base
6158c2ecf20Sopenharmony_ci	cmp	r2, #0
6168c2ecf20Sopenharmony_ci	beq	no_2nd_ddrc
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_ci	ldr	r3, [r2, #AT91_DDRSDRC_MDR]
6198c2ecf20Sopenharmony_ci	str	r3, .saved_sam9_mdr1
6208c2ecf20Sopenharmony_ci	bic	r3, r3, #~AT91_DDRSDRC_MD
6218c2ecf20Sopenharmony_ci	cmp	r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
6228c2ecf20Sopenharmony_ci	ldreq	r3, [r2, #AT91_DDRSDRC_MDR]
6238c2ecf20Sopenharmony_ci	biceq	r3, r3, #AT91_DDRSDRC_MD
6248c2ecf20Sopenharmony_ci	orreq	r3, r3, #AT91_DDRSDRC_MD_DDR2
6258c2ecf20Sopenharmony_ci	streq	r3, [r2, #AT91_DDRSDRC_MDR]
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci	/* Active DDRC self-refresh mode */
6288c2ecf20Sopenharmony_ci	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
6298c2ecf20Sopenharmony_ci	str	r3, .saved_sam9_lpr1
6308c2ecf20Sopenharmony_ci	bic	r3, r3, #AT91_DDRSDRC_LPCB
6318c2ecf20Sopenharmony_ci	orr	r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
6328c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_DDRSDRC_LPR]
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_cino_2nd_ddrc:
6358c2ecf20Sopenharmony_ci	b	exit_sramc_sf
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ciddrc_exit_sf:
6388c2ecf20Sopenharmony_ci	/* Restore MDR in case of LPDDR1 */
6398c2ecf20Sopenharmony_ci	ldr	r3, .saved_sam9_mdr
6408c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_DDRSDRC_MDR]
6418c2ecf20Sopenharmony_ci	/* Restore LPR on AT91 with DDRAM */
6428c2ecf20Sopenharmony_ci	ldr	r3, .saved_sam9_lpr
6438c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_DDRSDRC_LPR]
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci	/* If using the 2nd ddr controller */
6468c2ecf20Sopenharmony_ci	ldr	r2, .sramc1_base
6478c2ecf20Sopenharmony_ci	cmp	r2, #0
6488c2ecf20Sopenharmony_ci	ldrne	r3, .saved_sam9_mdr1
6498c2ecf20Sopenharmony_ci	strne	r3, [r2, #AT91_DDRSDRC_MDR]
6508c2ecf20Sopenharmony_ci	ldrne	r3, .saved_sam9_lpr1
6518c2ecf20Sopenharmony_ci	strne	r3, [r2, #AT91_DDRSDRC_LPR]
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	b	exit_sramc_sf
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ci	/*
6568c2ecf20Sopenharmony_ci	 * SDRAMC Memory controller
6578c2ecf20Sopenharmony_ci	 */
6588c2ecf20Sopenharmony_cisdramc_sf:
6598c2ecf20Sopenharmony_ci	tst	r0, #SRAMC_SELF_FRESH_ACTIVE
6608c2ecf20Sopenharmony_ci	beq	sdramc_exit_sf
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	/* Active SDRAMC self-refresh mode */
6638c2ecf20Sopenharmony_ci	ldr	r3, [r2, #AT91_SDRAMC_LPR]
6648c2ecf20Sopenharmony_ci	str	r3, .saved_sam9_lpr
6658c2ecf20Sopenharmony_ci	bic	r3, r3, #AT91_SDRAMC_LPCB
6668c2ecf20Sopenharmony_ci	orr	r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
6678c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_SDRAMC_LPR]
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_cisdramc_exit_sf:
6708c2ecf20Sopenharmony_ci	ldr	r3, .saved_sam9_lpr
6718c2ecf20Sopenharmony_ci	str	r3, [r2, #AT91_SDRAMC_LPR]
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ciexit_sramc_sf:
6748c2ecf20Sopenharmony_ci	mov	pc, lr
6758c2ecf20Sopenharmony_ciENDPROC(at91_sramc_self_refresh)
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci.pmc_base:
6788c2ecf20Sopenharmony_ci	.word 0
6798c2ecf20Sopenharmony_ci.sramc_base:
6808c2ecf20Sopenharmony_ci	.word 0
6818c2ecf20Sopenharmony_ci.sramc1_base:
6828c2ecf20Sopenharmony_ci	.word 0
6838c2ecf20Sopenharmony_ci.shdwc:
6848c2ecf20Sopenharmony_ci	.word 0
6858c2ecf20Sopenharmony_ci.sfrbu:
6868c2ecf20Sopenharmony_ci	.word 0
6878c2ecf20Sopenharmony_ci.memtype:
6888c2ecf20Sopenharmony_ci	.word 0
6898c2ecf20Sopenharmony_ci.pm_mode:
6908c2ecf20Sopenharmony_ci	.word 0
6918c2ecf20Sopenharmony_ci.mckr_offset:
6928c2ecf20Sopenharmony_ci	.word 0
6938c2ecf20Sopenharmony_ci.pmc_version:
6948c2ecf20Sopenharmony_ci	.word 0
6958c2ecf20Sopenharmony_ci.saved_mckr:
6968c2ecf20Sopenharmony_ci	.word 0
6978c2ecf20Sopenharmony_ci.saved_pllar:
6988c2ecf20Sopenharmony_ci	.word 0
6998c2ecf20Sopenharmony_ci.saved_sam9_lpr:
7008c2ecf20Sopenharmony_ci	.word 0
7018c2ecf20Sopenharmony_ci.saved_sam9_lpr1:
7028c2ecf20Sopenharmony_ci	.word 0
7038c2ecf20Sopenharmony_ci.saved_sam9_mdr:
7048c2ecf20Sopenharmony_ci	.word 0
7058c2ecf20Sopenharmony_ci.saved_sam9_mdr1:
7068c2ecf20Sopenharmony_ci	.word 0
7078c2ecf20Sopenharmony_ci.saved_osc_status:
7088c2ecf20Sopenharmony_ci	.word 0
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_ciENTRY(at91_pm_suspend_in_sram_sz)
7118c2ecf20Sopenharmony_ci	.word .-at91_pm_suspend_in_sram
712