xref: /linux/arch/arm/mach-omap2/sleep43xx.S (revision 11140cc40ddc3e7a2f2e3352e8a0587a93ba75df)
141d37e61SDave Gerlach/* SPDX-License-Identifier: GPL-2.0 */
241d37e61SDave Gerlach/*
341d37e61SDave Gerlach * Low level suspend code for AM43XX SoCs
441d37e61SDave Gerlach *
541d37e61SDave Gerlach * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
641d37e61SDave Gerlach *	Dave Gerlach, Vaibhav Bedia
741d37e61SDave Gerlach */
841d37e61SDave Gerlach
941d9d44dSDave Gerlach#include <generated/ti-pm-asm-offsets.h>
1041d37e61SDave Gerlach#include <linux/linkage.h>
1141d37e61SDave Gerlach#include <linux/ti-emif-sram.h>
1274655749SDave Gerlach#include <linux/platform_data/pm33xx.h>
1341d37e61SDave Gerlach#include <asm/assembler.h>
1441d37e61SDave Gerlach#include <asm/hardware/cache-l2x0.h>
1541d37e61SDave Gerlach#include <asm/memory.h>
1641d37e61SDave Gerlach
1741d37e61SDave Gerlach#include "cm33xx.h"
1841d37e61SDave Gerlach#include "common.h"
1941d37e61SDave Gerlach#include "iomap.h"
2041d37e61SDave Gerlach#include "omap-secure.h"
2141d37e61SDave Gerlach#include "omap44xx.h"
2241d37e61SDave Gerlach#include "prm33xx.h"
2341d37e61SDave Gerlach#include "prcm43xx.h"
2441d37e61SDave Gerlach
2574655749SDave Gerlach/* replicated define because linux/bitops.h cannot be included in assembly */
2674655749SDave Gerlach#define BIT(nr)			(1 << (nr))
2774655749SDave Gerlach
2841d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED		0x00030000
2941d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE		0x0003
3041d37e61SDave Gerlach#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE		0x0002
3141d37e61SDave Gerlach
3241d37e61SDave Gerlach#define AM43XX_EMIF_POWEROFF_ENABLE			0x1
3341d37e61SDave Gerlach#define AM43XX_EMIF_POWEROFF_DISABLE			0x0
3441d37e61SDave Gerlach
3541d37e61SDave Gerlach#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP		0x1
3641d37e61SDave Gerlach#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO		0x3
3741d37e61SDave Gerlach
3841d37e61SDave Gerlach#define AM43XX_CM_BASE					0x44DF0000
3941d37e61SDave Gerlach
4041d37e61SDave Gerlach#define AM43XX_CM_REGADDR(inst, reg)                           \
4141d37e61SDave Gerlach       AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg))
4241d37e61SDave Gerlach
4341d37e61SDave Gerlach#define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
4441d37e61SDave Gerlach					AM43XX_CM_MPU_MPU_CDOFFS)
4541d37e61SDave Gerlach#define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
4641d37e61SDave Gerlach					AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET)
4741d37e61SDave Gerlach#define AM43XX_CM_PER_EMIF_CLKCTRL  AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \
4841d37e61SDave Gerlach					AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
4941d37e61SDave Gerlach#define AM43XX_PRM_EMIF_CTRL_OFFSET			0x0030
5041d37e61SDave Gerlach
518c5a916fSKeerthy#define RTC_SECONDS_REG					0x0
528c5a916fSKeerthy#define RTC_PMIC_REG					0x98
538c5a916fSKeerthy#define RTC_PMIC_POWER_EN				BIT(16)
548c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_STS				BIT(12)
558c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_POL				BIT(4)
568c5a916fSKeerthy#define RTC_PMIC_EXT_WAKEUP_EN				BIT(0)
578c5a916fSKeerthy
5841d37e61SDave Gerlach	.arm
5941d37e61SDave Gerlach	.align 3
6041d37e61SDave Gerlach
6141d37e61SDave GerlachENTRY(am43xx_do_wfi)
6241d37e61SDave Gerlach	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
6341d37e61SDave Gerlach
6474655749SDave Gerlach	/* Save wfi_flags arg to data space */
6574655749SDave Gerlach	mov	r4, r0
6674655749SDave Gerlach	adr	r3, am43xx_pm_ro_sram_data
6774655749SDave Gerlach	ldr	r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
6874655749SDave Gerlach	str	r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
6974655749SDave Gerlach
7003de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0
7141d37e61SDave Gerlach	/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
7241d37e61SDave Gerlach	ldr	r1, get_l2cache_base
7341d37e61SDave Gerlach	blx	r1
7441d37e61SDave Gerlach	mov	r8, r0
7503de3727SArnd Bergmann#endif
7641d37e61SDave Gerlach
7774655749SDave Gerlach	/* Only flush cache is we know we are losing MPU context */
7874655749SDave Gerlach	tst	r4, #WFI_FLAG_FLUSH_CACHE
7974655749SDave Gerlach	beq	cache_skip_flush
8074655749SDave Gerlach
8141d37e61SDave Gerlach	/*
8241d37e61SDave Gerlach	 * Flush all data from the L1 and L2 data cache before disabling
8341d37e61SDave Gerlach	 * SCTLR.C bit.
8441d37e61SDave Gerlach	 */
8541d37e61SDave Gerlach	ldr	r1, kernel_flush
8641d37e61SDave Gerlach	blx	r1
8741d37e61SDave Gerlach
8841d37e61SDave Gerlach	/*
8941d37e61SDave Gerlach	 * Clear the SCTLR.C bit to prevent further data cache
9041d37e61SDave Gerlach	 * allocation. Clearing SCTLR.C would make all the data accesses
9141d37e61SDave Gerlach	 * strongly ordered and would not hit the cache.
9241d37e61SDave Gerlach	 */
9341d37e61SDave Gerlach	mrc	p15, 0, r0, c1, c0, 0
9441d37e61SDave Gerlach	bic	r0, r0, #(1 << 2)	@ Disable the C bit
9541d37e61SDave Gerlach	mcr	p15, 0, r0, c1, c0, 0
9641d37e61SDave Gerlach	isb
9741d37e61SDave Gerlach	dsb
9841d37e61SDave Gerlach
9941d37e61SDave Gerlach	/*
10041d37e61SDave Gerlach	 * Invalidate L1 and L2 data cache.
10141d37e61SDave Gerlach	 */
10241d37e61SDave Gerlach	ldr	r1, kernel_flush
10341d37e61SDave Gerlach	blx	r1
10441d37e61SDave Gerlach
10541d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0
10641d37e61SDave Gerlach	/*
10741d37e61SDave Gerlach	 * Clean and invalidate the L2 cache.
10841d37e61SDave Gerlach	 */
10941d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
11041d37e61SDave Gerlach	mov	r0, #0x03
11141d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
11241d37e61SDave Gerlach	dsb
11341d37e61SDave Gerlach	smc	#0
11441d37e61SDave Gerlach	dsb
11541d37e61SDave Gerlach#endif
11641d37e61SDave Gerlach	mov	r0, r8
11741d37e61SDave Gerlach	adr	r4, am43xx_pm_ro_sram_data
11841d37e61SDave Gerlach	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
11941d37e61SDave Gerlach
12041d37e61SDave Gerlach	mov	r2, r0
12141d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_AUX_CTRL]
12241d37e61SDave Gerlach	str	r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
12341d37e61SDave Gerlach	ldr	r0, [r2, #L310_PREFETCH_CTRL]
12441d37e61SDave Gerlach	str	r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
12541d37e61SDave Gerlach
12641d37e61SDave Gerlach	ldr	r0, l2_val
12741d37e61SDave Gerlach	str	r0, [r2, #L2X0_CLEAN_INV_WAY]
12841d37e61SDave Gerlachwait:
12941d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CLEAN_INV_WAY]
13041d37e61SDave Gerlach	ldr	r1, l2_val
13141d37e61SDave Gerlach	ands	r0, r0, r1
13241d37e61SDave Gerlach	bne	wait
13341d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
13441d37e61SDave Gerlach	mov	r0, #0x00
13541d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
13641d37e61SDave Gerlach	dsb
13741d37e61SDave Gerlach	smc	#0
13841d37e61SDave Gerlach	dsb
13941d37e61SDave Gerlach#endif
14041d37e61SDave Gerlachl2x_sync:
14141d37e61SDave Gerlach	mov	r0, r8
14241d37e61SDave Gerlach	mov	r2, r0
14341d37e61SDave Gerlach	mov	r0, #0x0
14441d37e61SDave Gerlach	str	r0, [r2, #L2X0_CACHE_SYNC]
14541d37e61SDave Gerlachsync:
14641d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CACHE_SYNC]
14741d37e61SDave Gerlach	ands	r0, r0, #0x1
14841d37e61SDave Gerlach	bne	sync
14941d37e61SDave Gerlach#endif
15041d37e61SDave Gerlach
15174655749SDave Gerlach	/* Restore wfi_flags */
15274655749SDave Gerlach	adr	r3, am43xx_pm_ro_sram_data
15374655749SDave Gerlach	ldr	r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
15474655749SDave Gerlach	ldr	r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
15574655749SDave Gerlach
15674655749SDave Gerlachcache_skip_flush:
1578c5a916fSKeerthy	/*
1588c5a916fSKeerthy	 * If we are trying to enter RTC+DDR mode we must perform
1598c5a916fSKeerthy	 * a read from the rtc address space to ensure translation
1608c5a916fSKeerthy	 * presence in the TLB to avoid page table walk after DDR
1618c5a916fSKeerthy	 * is unavailable.
1628c5a916fSKeerthy	 */
1638c5a916fSKeerthy	tst	r4, #WFI_FLAG_RTC_ONLY
1648c5a916fSKeerthy	beq	skip_rtc_va_refresh
1658c5a916fSKeerthy
1668c5a916fSKeerthy	adr	r3, am43xx_pm_ro_sram_data
1678c5a916fSKeerthy	ldr	r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
1688c5a916fSKeerthy	ldr	r0, [r1]
1698c5a916fSKeerthy
1708c5a916fSKeerthyskip_rtc_va_refresh:
17174655749SDave Gerlach	/* Check if we want self refresh */
17274655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
17374655749SDave Gerlach	beq	emif_skip_enter_sr
17474655749SDave Gerlach
17541d37e61SDave Gerlach	adr     r9, am43xx_emif_sram_table
17641d37e61SDave Gerlach
17741d37e61SDave Gerlach	ldr     r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
17841d37e61SDave Gerlach	blx     r3
17941d37e61SDave Gerlach
18074655749SDave Gerlachemif_skip_enter_sr:
18174655749SDave Gerlach	/* Only necessary if PER is losing context */
18274655749SDave Gerlach	tst	r4, #WFI_FLAG_SAVE_EMIF
18374655749SDave Gerlach	beq	emif_skip_save
18474655749SDave Gerlach
18541d37e61SDave Gerlach	ldr     r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
18641d37e61SDave Gerlach	blx	r3
18741d37e61SDave Gerlach
18874655749SDave Gerlachemif_skip_save:
18974655749SDave Gerlach	/* Only can disable EMIF if we have entered self refresh */
19074655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
19174655749SDave Gerlach	beq	emif_skip_disable
19274655749SDave Gerlach
19341d37e61SDave Gerlach	/* Disable EMIF */
19441d37e61SDave Gerlach	ldr	r1, am43xx_virt_emif_clkctrl
19541d37e61SDave Gerlach	ldr	r2, [r1]
19641d37e61SDave Gerlach	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
19741d37e61SDave Gerlach	str	r2, [r1]
19841d37e61SDave Gerlach
19941d37e61SDave Gerlachwait_emif_disable:
20041d37e61SDave Gerlach	ldr	r2, [r1]
20141d37e61SDave Gerlach	mov	r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
20241d37e61SDave Gerlach	cmp	r2, r3
20341d37e61SDave Gerlach	bne	wait_emif_disable
20441d37e61SDave Gerlach
20574655749SDave Gerlachemif_skip_disable:
2068c5a916fSKeerthy	tst	r4, #WFI_FLAG_RTC_ONLY
2078c5a916fSKeerthy	beq	skip_rtc_only
2088c5a916fSKeerthy
2098c5a916fSKeerthy	adr	r3, am43xx_pm_ro_sram_data
2108c5a916fSKeerthy	ldr	r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
2118c5a916fSKeerthy
2128c5a916fSKeerthy	ldr	r0, [r1, #RTC_PMIC_REG]
2138c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_POWER_EN
2148c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_STS
2158c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_EN
2168c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_POL
2178c5a916fSKeerthy	str	r0, [r1, #RTC_PMIC_REG]
2188c5a916fSKeerthy	ldr	r0, [r1, #RTC_PMIC_REG]
2198c5a916fSKeerthy	/* Wait for 2 seconds to lose power */
2208c5a916fSKeerthy	mov	r3, #2
2218c5a916fSKeerthy	ldr	r2, [r1, #RTC_SECONDS_REG]
2228c5a916fSKeerthyrtc_loop:
2238c5a916fSKeerthy	ldr	r0, [r1, #RTC_SECONDS_REG]
2248c5a916fSKeerthy	cmp	r0, r2
2258c5a916fSKeerthy	beq	rtc_loop
2268c5a916fSKeerthy	mov	r2, r0
2278c5a916fSKeerthy	subs	r3, r3, #1
2288c5a916fSKeerthy	bne	rtc_loop
2298c5a916fSKeerthy
2308c5a916fSKeerthy	b	re_enable_emif
2318c5a916fSKeerthy
2328c5a916fSKeerthyskip_rtc_only:
2338c5a916fSKeerthy
23474655749SDave Gerlach	tst	r4, #WFI_FLAG_WAKE_M3
23574655749SDave Gerlach	beq	wkup_m3_skip
23674655749SDave Gerlach
23741d37e61SDave Gerlach	/*
23841d37e61SDave Gerlach	 * For the MPU WFI to be registered as an interrupt
23941d37e61SDave Gerlach	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
24041d37e61SDave Gerlach	 * to DISABLED
24141d37e61SDave Gerlach	 */
24241d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkctrl
24341d37e61SDave Gerlach	ldr	r2, [r1]
24441d37e61SDave Gerlach	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
24541d37e61SDave Gerlach	str	r2, [r1]
24641d37e61SDave Gerlach
24741d37e61SDave Gerlach	/*
24841d37e61SDave Gerlach	 * Put MPU CLKDM to SW_SLEEP
24941d37e61SDave Gerlach	 */
25041d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
25141d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
25241d37e61SDave Gerlach	str	r2, [r1]
25341d37e61SDave Gerlach
25474655749SDave Gerlachwkup_m3_skip:
25541d37e61SDave Gerlach	/*
25641d37e61SDave Gerlach	 * Execute a barrier instruction to ensure that all cache,
25741d37e61SDave Gerlach	 * TLB and branch predictor maintenance operations issued
25841d37e61SDave Gerlach	 * have completed.
25941d37e61SDave Gerlach	 */
26041d37e61SDave Gerlach	dsb
26141d37e61SDave Gerlach	dmb
26241d37e61SDave Gerlach
26341d37e61SDave Gerlach	/*
26441d37e61SDave Gerlach	 * Execute a WFI instruction and wait until the
26541d37e61SDave Gerlach	 * STANDBYWFI output is asserted to indicate that the
26641d37e61SDave Gerlach	 * CPU is in idle and low power state. CPU can specualatively
26741d37e61SDave Gerlach	 * prefetch the instructions so add NOPs after WFI. Sixteen
26841d37e61SDave Gerlach	 * NOPs as per Cortex-A9 pipeline.
26941d37e61SDave Gerlach	 */
27041d37e61SDave Gerlach	wfi
27141d37e61SDave Gerlach
27241d37e61SDave Gerlach	nop
27341d37e61SDave Gerlach	nop
27441d37e61SDave Gerlach	nop
27541d37e61SDave Gerlach	nop
27641d37e61SDave Gerlach	nop
27741d37e61SDave Gerlach	nop
27841d37e61SDave Gerlach	nop
27941d37e61SDave Gerlach	nop
28041d37e61SDave Gerlach	nop
28141d37e61SDave Gerlach	nop
28241d37e61SDave Gerlach	nop
28341d37e61SDave Gerlach	nop
28441d37e61SDave Gerlach	nop
28541d37e61SDave Gerlach	nop
28641d37e61SDave Gerlach	nop
28741d37e61SDave Gerlach	nop
28841d37e61SDave Gerlach
28941d37e61SDave Gerlach	/* We come here in case of an abort due to a late interrupt */
29041d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
29141d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
29241d37e61SDave Gerlach	str	r2, [r1]
29341d37e61SDave Gerlach
29441d37e61SDave Gerlach	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
29541d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkctrl
29641d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
29741d37e61SDave Gerlach	str	r2, [r1]
29841d37e61SDave Gerlach
2998c5a916fSKeerthyre_enable_emif:
30041d37e61SDave Gerlach	/* Re-enable EMIF */
30141d37e61SDave Gerlach	ldr	r1, am43xx_virt_emif_clkctrl
30241d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
30341d37e61SDave Gerlach	str	r2, [r1]
30441d37e61SDave Gerlachwait_emif_enable:
30541d37e61SDave Gerlach	ldr	r3, [r1]
30641d37e61SDave Gerlach	cmp	r2, r3
30741d37e61SDave Gerlach	bne	wait_emif_enable
30841d37e61SDave Gerlach
30974655749SDave Gerlach	tst	r4, #WFI_FLAG_FLUSH_CACHE
31074655749SDave Gerlach	beq	cache_skip_restore
31174655749SDave Gerlach
31241d37e61SDave Gerlach	/*
31341d37e61SDave Gerlach	 * Set SCTLR.C bit to allow data cache allocation
31441d37e61SDave Gerlach	 */
31541d37e61SDave Gerlach	mrc	p15, 0, r0, c1, c0, 0
31641d37e61SDave Gerlach	orr	r0, r0, #(1 << 2)	@ Enable the C bit
31741d37e61SDave Gerlach	mcr	p15, 0, r0, c1, c0, 0
31841d37e61SDave Gerlach	isb
31941d37e61SDave Gerlach
32074655749SDave Gerlachcache_skip_restore:
32174655749SDave Gerlach	/* Only necessary if PER is losing context */
32274655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
32374655749SDave Gerlach	beq	emif_skip_exit_sr_abt
32474655749SDave Gerlach
32574655749SDave Gerlach	adr	r9, am43xx_emif_sram_table
32641d37e61SDave Gerlach	ldr	r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
32741d37e61SDave Gerlach	blx	r1
32841d37e61SDave Gerlach
32974655749SDave Gerlachemif_skip_exit_sr_abt:
33041d37e61SDave Gerlach	/* Let the suspend code know about the abort */
33141d37e61SDave Gerlach	mov	r0, #1
33241d37e61SDave Gerlach	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
33341d37e61SDave GerlachENDPROC(am43xx_do_wfi)
33441d37e61SDave Gerlach
33541d37e61SDave Gerlach	.align
33641d37e61SDave GerlachENTRY(am43xx_resume_offset)
33741d37e61SDave Gerlach	.word . - am43xx_do_wfi
33841d37e61SDave Gerlach
33941d37e61SDave GerlachENTRY(am43xx_resume_from_deep_sleep)
34041d37e61SDave Gerlach	/* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */
34141d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
34241d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
34341d37e61SDave Gerlach	str	r2, [r1]
34441d37e61SDave Gerlach
34541d37e61SDave Gerlach	/* For AM43xx, use EMIF power down until context is restored */
34641d37e61SDave Gerlach	ldr	r2, am43xx_phys_emif_poweroff
34741d37e61SDave Gerlach	mov	r1, #AM43XX_EMIF_POWEROFF_ENABLE
34841d37e61SDave Gerlach	str	r1, [r2, #0x0]
34941d37e61SDave Gerlach
35041d37e61SDave Gerlach	/* Re-enable EMIF */
35141d37e61SDave Gerlach	ldr	r1, am43xx_phys_emif_clkctrl
35241d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
35341d37e61SDave Gerlach	str	r2, [r1]
35441d37e61SDave Gerlachwait_emif_enable1:
35541d37e61SDave Gerlach	ldr	r3, [r1]
35641d37e61SDave Gerlach	cmp	r2, r3
35741d37e61SDave Gerlach	bne	wait_emif_enable1
35841d37e61SDave Gerlach
35941d37e61SDave Gerlach	adr     r9, am43xx_emif_sram_table
36041d37e61SDave Gerlach
36141d37e61SDave Gerlach	ldr     r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
36241d37e61SDave Gerlach	blx     r1
36341d37e61SDave Gerlach
36441d37e61SDave Gerlach	ldr     r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
36541d37e61SDave Gerlach	blx     r1
36641d37e61SDave Gerlach
36741d37e61SDave Gerlach	ldr     r2, am43xx_phys_emif_poweroff
36841d37e61SDave Gerlach	mov     r1, #AM43XX_EMIF_POWEROFF_DISABLE
36941d37e61SDave Gerlach	str     r1, [r2, #0x0]
37041d37e61SDave Gerlach
371*11140cc4SDave Gerlach	ldr     r1, [r9, #EMIF_PM_RUN_HW_LEVELING]
372*11140cc4SDave Gerlach	blx     r1
373*11140cc4SDave Gerlach
37441d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0
37541d37e61SDave Gerlach	ldr	r2, l2_cache_base
37641d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CTRL]
37741d37e61SDave Gerlach	and	r0, #0x0f
37841d37e61SDave Gerlach	cmp	r0, #1
37941d37e61SDave Gerlach	beq	skip_l2en			@ Skip if already enabled
38041d37e61SDave Gerlach
38141d37e61SDave Gerlach	adr	r4, am43xx_pm_ro_sram_data
38241d37e61SDave Gerlach	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET]
38341d37e61SDave Gerlach	ldr     r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
38441d37e61SDave Gerlach
38541d37e61SDave Gerlach	ldr	r12, l2_smc1
38641d37e61SDave Gerlach	dsb
38741d37e61SDave Gerlach	smc	#0
38841d37e61SDave Gerlach	dsb
38941d37e61SDave Gerlachset_aux_ctrl:
39041d37e61SDave Gerlach	ldr     r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
39141d37e61SDave Gerlach	ldr	r12, l2_smc2
39241d37e61SDave Gerlach	dsb
39341d37e61SDave Gerlach	smc	#0
39441d37e61SDave Gerlach	dsb
39541d37e61SDave Gerlach
39641d37e61SDave Gerlach	/* L2 invalidate on resume */
39741d37e61SDave Gerlach	ldr	r0, l2_val
39841d37e61SDave Gerlach	ldr	r2, l2_cache_base
39941d37e61SDave Gerlach	str	r0, [r2, #L2X0_INV_WAY]
40041d37e61SDave Gerlachwait2:
40141d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_INV_WAY]
40241d37e61SDave Gerlach	ldr	r1, l2_val
40341d37e61SDave Gerlach	ands	r0, r0, r1
40441d37e61SDave Gerlach	bne	wait2
40541d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
40641d37e61SDave Gerlach	mov	r0, #0x00
40741d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
40841d37e61SDave Gerlach	dsb
40941d37e61SDave Gerlach	smc	#0
41041d37e61SDave Gerlach	dsb
41141d37e61SDave Gerlach#endif
41241d37e61SDave Gerlachl2x_sync2:
41341d37e61SDave Gerlach	ldr	r2, l2_cache_base
41441d37e61SDave Gerlach	mov	r0, #0x0
41541d37e61SDave Gerlach	str	r0, [r2, #L2X0_CACHE_SYNC]
41641d37e61SDave Gerlachsync2:
41741d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CACHE_SYNC]
41841d37e61SDave Gerlach	ands	r0, r0, #0x1
41941d37e61SDave Gerlach	bne	sync2
42041d37e61SDave Gerlach
42141d37e61SDave Gerlach	mov	r0, #0x1
42241d37e61SDave Gerlach	ldr	r12, l2_smc3
42341d37e61SDave Gerlach	dsb
42441d37e61SDave Gerlach	smc	#0
42541d37e61SDave Gerlach	dsb
42641d37e61SDave Gerlach#endif
42741d37e61SDave Gerlachskip_l2en:
42841d37e61SDave Gerlach	/* We are back. Branch to the common CPU resume routine */
42941d37e61SDave Gerlach	mov	r0, #0
43041d37e61SDave Gerlach	ldr	pc, resume_addr
43141d37e61SDave GerlachENDPROC(am43xx_resume_from_deep_sleep)
43241d37e61SDave Gerlach
43341d37e61SDave Gerlach/*
43441d37e61SDave Gerlach * Local variables
43541d37e61SDave Gerlach */
43641d37e61SDave Gerlach	.align
43741d37e61SDave Gerlachkernel_flush:
43841d37e61SDave Gerlach	.word   v7_flush_dcache_all
43941d37e61SDave Gerlachddr_start:
44041d37e61SDave Gerlach	.word	PAGE_OFFSET
44141d37e61SDave Gerlach
44241d37e61SDave Gerlacham43xx_phys_emif_poweroff:
44341d37e61SDave Gerlach	.word   (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \
44441d37e61SDave Gerlach		 AM43XX_PRM_EMIF_CTRL_OFFSET)
44541d37e61SDave Gerlacham43xx_virt_mpu_clkstctrl:
44641d37e61SDave Gerlach	.word	(AM43XX_CM_MPU_CLKSTCTRL)
44741d37e61SDave Gerlacham43xx_virt_mpu_clkctrl:
44841d37e61SDave Gerlach	.word	(AM43XX_CM_MPU_MPU_CLKCTRL)
44941d37e61SDave Gerlacham43xx_virt_emif_clkctrl:
45041d37e61SDave Gerlach	.word	(AM43XX_CM_PER_EMIF_CLKCTRL)
45141d37e61SDave Gerlacham43xx_phys_emif_clkctrl:
45241d37e61SDave Gerlach	.word	(AM43XX_CM_BASE + AM43XX_CM_PER_INST + \
45341d37e61SDave Gerlach		 AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
45441d37e61SDave Gerlach
45503de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0
45641d37e61SDave Gerlach/* L2 cache related defines for AM437x */
45703de3727SArnd Bergmannget_l2cache_base:
45803de3727SArnd Bergmann	.word	omap4_get_l2cache_base
45941d37e61SDave Gerlachl2_cache_base:
46041d37e61SDave Gerlach	.word	OMAP44XX_L2CACHE_BASE
46141d37e61SDave Gerlachl2_smc1:
46241d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_PREFETCH_INDEX
46341d37e61SDave Gerlachl2_smc2:
46441d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_AUXCTRL_INDEX
46541d37e61SDave Gerlachl2_smc3:
46641d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_CTRL_INDEX
46741d37e61SDave Gerlachl2_val:
46841d37e61SDave Gerlach	.word	0xffff
46903de3727SArnd Bergmann#endif
47041d37e61SDave Gerlach
47141d37e61SDave Gerlach.align 3
47241d37e61SDave Gerlach/* DDR related defines */
47341d37e61SDave GerlachENTRY(am43xx_emif_sram_table)
47441d37e61SDave Gerlach	.space EMIF_PM_FUNCTIONS_SIZE
47541d37e61SDave Gerlach
47641d37e61SDave GerlachENTRY(am43xx_pm_sram)
47741d37e61SDave Gerlach	.word am43xx_do_wfi
47841d37e61SDave Gerlach	.word am43xx_do_wfi_sz
47941d37e61SDave Gerlach	.word am43xx_resume_offset
48041d37e61SDave Gerlach	.word am43xx_emif_sram_table
48141d37e61SDave Gerlach	.word am43xx_pm_ro_sram_data
48241d37e61SDave Gerlach
4838c5a916fSKeerthyresume_addr:
4848c5a916fSKeerthy	.word   cpu_resume - PAGE_OFFSET + 0x80000000
48541d37e61SDave Gerlach.align 3
48641d37e61SDave Gerlach
48741d37e61SDave GerlachENTRY(am43xx_pm_ro_sram_data)
48841d37e61SDave Gerlach	.space AMX3_PM_RO_SRAM_DATA_SIZE
48941d37e61SDave Gerlach
49041d37e61SDave GerlachENTRY(am43xx_do_wfi_sz)
49141d37e61SDave Gerlach	.word	. - am43xx_do_wfi
492