xref: /linux/arch/arm/mach-omap2/sleep43xx.S (revision 3fe1ee40b2a2db271513a498c475c13572dcb4c6)
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
59*3fe1ee40SStefan Agner	.arch armv7-a
60*3fe1ee40SStefan Agner	.arch_extension sec
6141d37e61SDave Gerlach	.align 3
6241d37e61SDave Gerlach
6341d37e61SDave GerlachENTRY(am43xx_do_wfi)
6441d37e61SDave Gerlach	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
6541d37e61SDave Gerlach
6674655749SDave Gerlach	/* Save wfi_flags arg to data space */
6774655749SDave Gerlach	mov	r4, r0
6874655749SDave Gerlach	adr	r3, am43xx_pm_ro_sram_data
6974655749SDave Gerlach	ldr	r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
7074655749SDave Gerlach	str	r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
7174655749SDave Gerlach
7203de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0
7341d37e61SDave Gerlach	/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
7441d37e61SDave Gerlach	ldr	r1, get_l2cache_base
7541d37e61SDave Gerlach	blx	r1
7641d37e61SDave Gerlach	mov	r8, r0
7703de3727SArnd Bergmann#endif
7841d37e61SDave Gerlach
7974655749SDave Gerlach	/* Only flush cache is we know we are losing MPU context */
8074655749SDave Gerlach	tst	r4, #WFI_FLAG_FLUSH_CACHE
8174655749SDave Gerlach	beq	cache_skip_flush
8274655749SDave Gerlach
8341d37e61SDave Gerlach	/*
8441d37e61SDave Gerlach	 * Flush all data from the L1 and L2 data cache before disabling
8541d37e61SDave Gerlach	 * SCTLR.C bit.
8641d37e61SDave Gerlach	 */
8741d37e61SDave Gerlach	ldr	r1, kernel_flush
8841d37e61SDave Gerlach	blx	r1
8941d37e61SDave Gerlach
9041d37e61SDave Gerlach	/*
9141d37e61SDave Gerlach	 * Clear the SCTLR.C bit to prevent further data cache
9241d37e61SDave Gerlach	 * allocation. Clearing SCTLR.C would make all the data accesses
9341d37e61SDave Gerlach	 * strongly ordered and would not hit the cache.
9441d37e61SDave Gerlach	 */
9541d37e61SDave Gerlach	mrc	p15, 0, r0, c1, c0, 0
9641d37e61SDave Gerlach	bic	r0, r0, #(1 << 2)	@ Disable the C bit
9741d37e61SDave Gerlach	mcr	p15, 0, r0, c1, c0, 0
9841d37e61SDave Gerlach	isb
9941d37e61SDave Gerlach	dsb
10041d37e61SDave Gerlach
10141d37e61SDave Gerlach	/*
10241d37e61SDave Gerlach	 * Invalidate L1 and L2 data cache.
10341d37e61SDave Gerlach	 */
10441d37e61SDave Gerlach	ldr	r1, kernel_flush
10541d37e61SDave Gerlach	blx	r1
10641d37e61SDave Gerlach
10741d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0
10841d37e61SDave Gerlach	/*
10941d37e61SDave Gerlach	 * Clean and invalidate the L2 cache.
11041d37e61SDave Gerlach	 */
11141d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
11241d37e61SDave Gerlach	mov	r0, #0x03
11341d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
11441d37e61SDave Gerlach	dsb
11541d37e61SDave Gerlach	smc	#0
11641d37e61SDave Gerlach	dsb
11741d37e61SDave Gerlach#endif
11841d37e61SDave Gerlach	mov	r0, r8
11941d37e61SDave Gerlach	adr	r4, am43xx_pm_ro_sram_data
12041d37e61SDave Gerlach	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
12141d37e61SDave Gerlach
12241d37e61SDave Gerlach	mov	r2, r0
12341d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_AUX_CTRL]
12441d37e61SDave Gerlach	str	r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
12541d37e61SDave Gerlach	ldr	r0, [r2, #L310_PREFETCH_CTRL]
12641d37e61SDave Gerlach	str	r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
12741d37e61SDave Gerlach
12841d37e61SDave Gerlach	ldr	r0, l2_val
12941d37e61SDave Gerlach	str	r0, [r2, #L2X0_CLEAN_INV_WAY]
13041d37e61SDave Gerlachwait:
13141d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CLEAN_INV_WAY]
13241d37e61SDave Gerlach	ldr	r1, l2_val
13341d37e61SDave Gerlach	ands	r0, r0, r1
13441d37e61SDave Gerlach	bne	wait
13541d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
13641d37e61SDave Gerlach	mov	r0, #0x00
13741d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
13841d37e61SDave Gerlach	dsb
13941d37e61SDave Gerlach	smc	#0
14041d37e61SDave Gerlach	dsb
14141d37e61SDave Gerlach#endif
14241d37e61SDave Gerlachl2x_sync:
14341d37e61SDave Gerlach	mov	r0, r8
14441d37e61SDave Gerlach	mov	r2, r0
14541d37e61SDave Gerlach	mov	r0, #0x0
14641d37e61SDave Gerlach	str	r0, [r2, #L2X0_CACHE_SYNC]
14741d37e61SDave Gerlachsync:
14841d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CACHE_SYNC]
14941d37e61SDave Gerlach	ands	r0, r0, #0x1
15041d37e61SDave Gerlach	bne	sync
15141d37e61SDave Gerlach#endif
15241d37e61SDave Gerlach
15374655749SDave Gerlach	/* Restore wfi_flags */
15474655749SDave Gerlach	adr	r3, am43xx_pm_ro_sram_data
15574655749SDave Gerlach	ldr	r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
15674655749SDave Gerlach	ldr	r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
15774655749SDave Gerlach
15874655749SDave Gerlachcache_skip_flush:
1598c5a916fSKeerthy	/*
1608c5a916fSKeerthy	 * If we are trying to enter RTC+DDR mode we must perform
1618c5a916fSKeerthy	 * a read from the rtc address space to ensure translation
1628c5a916fSKeerthy	 * presence in the TLB to avoid page table walk after DDR
1638c5a916fSKeerthy	 * is unavailable.
1648c5a916fSKeerthy	 */
1658c5a916fSKeerthy	tst	r4, #WFI_FLAG_RTC_ONLY
1668c5a916fSKeerthy	beq	skip_rtc_va_refresh
1678c5a916fSKeerthy
1688c5a916fSKeerthy	adr	r3, am43xx_pm_ro_sram_data
1698c5a916fSKeerthy	ldr	r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
1708c5a916fSKeerthy	ldr	r0, [r1]
1718c5a916fSKeerthy
1728c5a916fSKeerthyskip_rtc_va_refresh:
17374655749SDave Gerlach	/* Check if we want self refresh */
17474655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
17574655749SDave Gerlach	beq	emif_skip_enter_sr
17674655749SDave Gerlach
17741d37e61SDave Gerlach	adr     r9, am43xx_emif_sram_table
17841d37e61SDave Gerlach
17941d37e61SDave Gerlach	ldr     r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
18041d37e61SDave Gerlach	blx     r3
18141d37e61SDave Gerlach
18274655749SDave Gerlachemif_skip_enter_sr:
18374655749SDave Gerlach	/* Only necessary if PER is losing context */
18474655749SDave Gerlach	tst	r4, #WFI_FLAG_SAVE_EMIF
18574655749SDave Gerlach	beq	emif_skip_save
18674655749SDave Gerlach
18741d37e61SDave Gerlach	ldr     r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
18841d37e61SDave Gerlach	blx	r3
18941d37e61SDave Gerlach
19074655749SDave Gerlachemif_skip_save:
19174655749SDave Gerlach	/* Only can disable EMIF if we have entered self refresh */
19274655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
19374655749SDave Gerlach	beq	emif_skip_disable
19474655749SDave Gerlach
19541d37e61SDave Gerlach	/* Disable EMIF */
19641d37e61SDave Gerlach	ldr	r1, am43xx_virt_emif_clkctrl
19741d37e61SDave Gerlach	ldr	r2, [r1]
19841d37e61SDave Gerlach	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
19941d37e61SDave Gerlach	str	r2, [r1]
20041d37e61SDave Gerlach
20141d37e61SDave Gerlachwait_emif_disable:
20241d37e61SDave Gerlach	ldr	r2, [r1]
20341d37e61SDave Gerlach	mov	r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
20441d37e61SDave Gerlach	cmp	r2, r3
20541d37e61SDave Gerlach	bne	wait_emif_disable
20641d37e61SDave Gerlach
20774655749SDave Gerlachemif_skip_disable:
2088c5a916fSKeerthy	tst	r4, #WFI_FLAG_RTC_ONLY
2098c5a916fSKeerthy	beq	skip_rtc_only
2108c5a916fSKeerthy
2118c5a916fSKeerthy	adr	r3, am43xx_pm_ro_sram_data
2128c5a916fSKeerthy	ldr	r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
2138c5a916fSKeerthy
2148c5a916fSKeerthy	ldr	r0, [r1, #RTC_PMIC_REG]
2158c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_POWER_EN
2168c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_STS
2178c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_EN
2188c5a916fSKeerthy	orr	r0, r0, #RTC_PMIC_EXT_WAKEUP_POL
2198c5a916fSKeerthy	str	r0, [r1, #RTC_PMIC_REG]
2208c5a916fSKeerthy	ldr	r0, [r1, #RTC_PMIC_REG]
2218c5a916fSKeerthy	/* Wait for 2 seconds to lose power */
2228c5a916fSKeerthy	mov	r3, #2
2238c5a916fSKeerthy	ldr	r2, [r1, #RTC_SECONDS_REG]
2248c5a916fSKeerthyrtc_loop:
2258c5a916fSKeerthy	ldr	r0, [r1, #RTC_SECONDS_REG]
2268c5a916fSKeerthy	cmp	r0, r2
2278c5a916fSKeerthy	beq	rtc_loop
2288c5a916fSKeerthy	mov	r2, r0
2298c5a916fSKeerthy	subs	r3, r3, #1
2308c5a916fSKeerthy	bne	rtc_loop
2318c5a916fSKeerthy
2328c5a916fSKeerthy	b	re_enable_emif
2338c5a916fSKeerthy
2348c5a916fSKeerthyskip_rtc_only:
2358c5a916fSKeerthy
23674655749SDave Gerlach	tst	r4, #WFI_FLAG_WAKE_M3
23774655749SDave Gerlach	beq	wkup_m3_skip
23874655749SDave Gerlach
23941d37e61SDave Gerlach	/*
24041d37e61SDave Gerlach	 * For the MPU WFI to be registered as an interrupt
24141d37e61SDave Gerlach	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
24241d37e61SDave Gerlach	 * to DISABLED
24341d37e61SDave Gerlach	 */
24441d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkctrl
24541d37e61SDave Gerlach	ldr	r2, [r1]
24641d37e61SDave Gerlach	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
24741d37e61SDave Gerlach	str	r2, [r1]
24841d37e61SDave Gerlach
24941d37e61SDave Gerlach	/*
25041d37e61SDave Gerlach	 * Put MPU CLKDM to SW_SLEEP
25141d37e61SDave Gerlach	 */
25241d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
25341d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
25441d37e61SDave Gerlach	str	r2, [r1]
25541d37e61SDave Gerlach
25674655749SDave Gerlachwkup_m3_skip:
25741d37e61SDave Gerlach	/*
25841d37e61SDave Gerlach	 * Execute a barrier instruction to ensure that all cache,
25941d37e61SDave Gerlach	 * TLB and branch predictor maintenance operations issued
26041d37e61SDave Gerlach	 * have completed.
26141d37e61SDave Gerlach	 */
26241d37e61SDave Gerlach	dsb
26341d37e61SDave Gerlach	dmb
26441d37e61SDave Gerlach
26541d37e61SDave Gerlach	/*
26641d37e61SDave Gerlach	 * Execute a WFI instruction and wait until the
26741d37e61SDave Gerlach	 * STANDBYWFI output is asserted to indicate that the
26841d37e61SDave Gerlach	 * CPU is in idle and low power state. CPU can specualatively
26941d37e61SDave Gerlach	 * prefetch the instructions so add NOPs after WFI. Sixteen
27041d37e61SDave Gerlach	 * NOPs as per Cortex-A9 pipeline.
27141d37e61SDave Gerlach	 */
27241d37e61SDave Gerlach	wfi
27341d37e61SDave Gerlach
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	nop
28941d37e61SDave Gerlach	nop
29041d37e61SDave Gerlach
29141d37e61SDave Gerlach	/* We come here in case of an abort due to a late interrupt */
29241d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
29341d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
29441d37e61SDave Gerlach	str	r2, [r1]
29541d37e61SDave Gerlach
29641d37e61SDave Gerlach	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
29741d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkctrl
29841d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
29941d37e61SDave Gerlach	str	r2, [r1]
30041d37e61SDave Gerlach
3018c5a916fSKeerthyre_enable_emif:
30241d37e61SDave Gerlach	/* Re-enable EMIF */
30341d37e61SDave Gerlach	ldr	r1, am43xx_virt_emif_clkctrl
30441d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
30541d37e61SDave Gerlach	str	r2, [r1]
30641d37e61SDave Gerlachwait_emif_enable:
30741d37e61SDave Gerlach	ldr	r3, [r1]
30841d37e61SDave Gerlach	cmp	r2, r3
30941d37e61SDave Gerlach	bne	wait_emif_enable
31041d37e61SDave Gerlach
31174655749SDave Gerlach	tst	r4, #WFI_FLAG_FLUSH_CACHE
31274655749SDave Gerlach	beq	cache_skip_restore
31374655749SDave Gerlach
31441d37e61SDave Gerlach	/*
31541d37e61SDave Gerlach	 * Set SCTLR.C bit to allow data cache allocation
31641d37e61SDave Gerlach	 */
31741d37e61SDave Gerlach	mrc	p15, 0, r0, c1, c0, 0
31841d37e61SDave Gerlach	orr	r0, r0, #(1 << 2)	@ Enable the C bit
31941d37e61SDave Gerlach	mcr	p15, 0, r0, c1, c0, 0
32041d37e61SDave Gerlach	isb
32141d37e61SDave Gerlach
32274655749SDave Gerlachcache_skip_restore:
32374655749SDave Gerlach	/* Only necessary if PER is losing context */
32474655749SDave Gerlach	tst	r4, #WFI_FLAG_SELF_REFRESH
32574655749SDave Gerlach	beq	emif_skip_exit_sr_abt
32674655749SDave Gerlach
32774655749SDave Gerlach	adr	r9, am43xx_emif_sram_table
32841d37e61SDave Gerlach	ldr	r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
32941d37e61SDave Gerlach	blx	r1
33041d37e61SDave Gerlach
33174655749SDave Gerlachemif_skip_exit_sr_abt:
33241d37e61SDave Gerlach	/* Let the suspend code know about the abort */
33341d37e61SDave Gerlach	mov	r0, #1
33441d37e61SDave Gerlach	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
33541d37e61SDave GerlachENDPROC(am43xx_do_wfi)
33641d37e61SDave Gerlach
33741d37e61SDave Gerlach	.align
33841d37e61SDave GerlachENTRY(am43xx_resume_offset)
33941d37e61SDave Gerlach	.word . - am43xx_do_wfi
34041d37e61SDave Gerlach
34141d37e61SDave GerlachENTRY(am43xx_resume_from_deep_sleep)
34241d37e61SDave Gerlach	/* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */
34341d37e61SDave Gerlach	ldr	r1, am43xx_virt_mpu_clkstctrl
34441d37e61SDave Gerlach	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
34541d37e61SDave Gerlach	str	r2, [r1]
34641d37e61SDave Gerlach
34741d37e61SDave Gerlach	/* For AM43xx, use EMIF power down until context is restored */
34841d37e61SDave Gerlach	ldr	r2, am43xx_phys_emif_poweroff
34941d37e61SDave Gerlach	mov	r1, #AM43XX_EMIF_POWEROFF_ENABLE
35041d37e61SDave Gerlach	str	r1, [r2, #0x0]
35141d37e61SDave Gerlach
35241d37e61SDave Gerlach	/* Re-enable EMIF */
35341d37e61SDave Gerlach	ldr	r1, am43xx_phys_emif_clkctrl
35441d37e61SDave Gerlach	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
35541d37e61SDave Gerlach	str	r2, [r1]
35641d37e61SDave Gerlachwait_emif_enable1:
35741d37e61SDave Gerlach	ldr	r3, [r1]
35841d37e61SDave Gerlach	cmp	r2, r3
35941d37e61SDave Gerlach	bne	wait_emif_enable1
36041d37e61SDave Gerlach
36141d37e61SDave Gerlach	adr     r9, am43xx_emif_sram_table
36241d37e61SDave Gerlach
36341d37e61SDave Gerlach	ldr     r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
36441d37e61SDave Gerlach	blx     r1
36541d37e61SDave Gerlach
36641d37e61SDave Gerlach	ldr     r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
36741d37e61SDave Gerlach	blx     r1
36841d37e61SDave Gerlach
36941d37e61SDave Gerlach	ldr     r2, am43xx_phys_emif_poweroff
37041d37e61SDave Gerlach	mov     r1, #AM43XX_EMIF_POWEROFF_DISABLE
37141d37e61SDave Gerlach	str     r1, [r2, #0x0]
37241d37e61SDave Gerlach
37311140cc4SDave Gerlach	ldr     r1, [r9, #EMIF_PM_RUN_HW_LEVELING]
37411140cc4SDave Gerlach	blx     r1
37511140cc4SDave Gerlach
37641d37e61SDave Gerlach#ifdef CONFIG_CACHE_L2X0
37741d37e61SDave Gerlach	ldr	r2, l2_cache_base
37841d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CTRL]
37941d37e61SDave Gerlach	and	r0, #0x0f
38041d37e61SDave Gerlach	cmp	r0, #1
38141d37e61SDave Gerlach	beq	skip_l2en			@ Skip if already enabled
38241d37e61SDave Gerlach
38341d37e61SDave Gerlach	adr	r4, am43xx_pm_ro_sram_data
38441d37e61SDave Gerlach	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET]
38541d37e61SDave Gerlach	ldr     r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
38641d37e61SDave Gerlach
38741d37e61SDave Gerlach	ldr	r12, l2_smc1
38841d37e61SDave Gerlach	dsb
38941d37e61SDave Gerlach	smc	#0
39041d37e61SDave Gerlach	dsb
39141d37e61SDave Gerlachset_aux_ctrl:
39241d37e61SDave Gerlach	ldr     r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
39341d37e61SDave Gerlach	ldr	r12, l2_smc2
39441d37e61SDave Gerlach	dsb
39541d37e61SDave Gerlach	smc	#0
39641d37e61SDave Gerlach	dsb
39741d37e61SDave Gerlach
39841d37e61SDave Gerlach	/* L2 invalidate on resume */
39941d37e61SDave Gerlach	ldr	r0, l2_val
40041d37e61SDave Gerlach	ldr	r2, l2_cache_base
40141d37e61SDave Gerlach	str	r0, [r2, #L2X0_INV_WAY]
40241d37e61SDave Gerlachwait2:
40341d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_INV_WAY]
40441d37e61SDave Gerlach	ldr	r1, l2_val
40541d37e61SDave Gerlach	ands	r0, r0, r1
40641d37e61SDave Gerlach	bne	wait2
40741d37e61SDave Gerlach#ifdef CONFIG_PL310_ERRATA_727915
40841d37e61SDave Gerlach	mov	r0, #0x00
40941d37e61SDave Gerlach	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
41041d37e61SDave Gerlach	dsb
41141d37e61SDave Gerlach	smc	#0
41241d37e61SDave Gerlach	dsb
41341d37e61SDave Gerlach#endif
41441d37e61SDave Gerlachl2x_sync2:
41541d37e61SDave Gerlach	ldr	r2, l2_cache_base
41641d37e61SDave Gerlach	mov	r0, #0x0
41741d37e61SDave Gerlach	str	r0, [r2, #L2X0_CACHE_SYNC]
41841d37e61SDave Gerlachsync2:
41941d37e61SDave Gerlach	ldr	r0, [r2, #L2X0_CACHE_SYNC]
42041d37e61SDave Gerlach	ands	r0, r0, #0x1
42141d37e61SDave Gerlach	bne	sync2
42241d37e61SDave Gerlach
42341d37e61SDave Gerlach	mov	r0, #0x1
42441d37e61SDave Gerlach	ldr	r12, l2_smc3
42541d37e61SDave Gerlach	dsb
42641d37e61SDave Gerlach	smc	#0
42741d37e61SDave Gerlach	dsb
42841d37e61SDave Gerlach#endif
42941d37e61SDave Gerlachskip_l2en:
43041d37e61SDave Gerlach	/* We are back. Branch to the common CPU resume routine */
43141d37e61SDave Gerlach	mov	r0, #0
43241d37e61SDave Gerlach	ldr	pc, resume_addr
43341d37e61SDave GerlachENDPROC(am43xx_resume_from_deep_sleep)
43441d37e61SDave Gerlach
43541d37e61SDave Gerlach/*
43641d37e61SDave Gerlach * Local variables
43741d37e61SDave Gerlach */
43841d37e61SDave Gerlach	.align
43941d37e61SDave Gerlachkernel_flush:
44041d37e61SDave Gerlach	.word   v7_flush_dcache_all
44141d37e61SDave Gerlachddr_start:
44241d37e61SDave Gerlach	.word	PAGE_OFFSET
44341d37e61SDave Gerlach
44441d37e61SDave Gerlacham43xx_phys_emif_poweroff:
44541d37e61SDave Gerlach	.word   (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \
44641d37e61SDave Gerlach		 AM43XX_PRM_EMIF_CTRL_OFFSET)
44741d37e61SDave Gerlacham43xx_virt_mpu_clkstctrl:
44841d37e61SDave Gerlach	.word	(AM43XX_CM_MPU_CLKSTCTRL)
44941d37e61SDave Gerlacham43xx_virt_mpu_clkctrl:
45041d37e61SDave Gerlach	.word	(AM43XX_CM_MPU_MPU_CLKCTRL)
45141d37e61SDave Gerlacham43xx_virt_emif_clkctrl:
45241d37e61SDave Gerlach	.word	(AM43XX_CM_PER_EMIF_CLKCTRL)
45341d37e61SDave Gerlacham43xx_phys_emif_clkctrl:
45441d37e61SDave Gerlach	.word	(AM43XX_CM_BASE + AM43XX_CM_PER_INST + \
45541d37e61SDave Gerlach		 AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
45641d37e61SDave Gerlach
45703de3727SArnd Bergmann#ifdef CONFIG_CACHE_L2X0
45841d37e61SDave Gerlach/* L2 cache related defines for AM437x */
45903de3727SArnd Bergmannget_l2cache_base:
46003de3727SArnd Bergmann	.word	omap4_get_l2cache_base
46141d37e61SDave Gerlachl2_cache_base:
46241d37e61SDave Gerlach	.word	OMAP44XX_L2CACHE_BASE
46341d37e61SDave Gerlachl2_smc1:
46441d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_PREFETCH_INDEX
46541d37e61SDave Gerlachl2_smc2:
46641d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_AUXCTRL_INDEX
46741d37e61SDave Gerlachl2_smc3:
46841d37e61SDave Gerlach	.word	OMAP4_MON_L2X0_CTRL_INDEX
46941d37e61SDave Gerlachl2_val:
47041d37e61SDave Gerlach	.word	0xffff
47103de3727SArnd Bergmann#endif
47241d37e61SDave Gerlach
47341d37e61SDave Gerlach.align 3
47441d37e61SDave Gerlach/* DDR related defines */
47541d37e61SDave GerlachENTRY(am43xx_emif_sram_table)
47641d37e61SDave Gerlach	.space EMIF_PM_FUNCTIONS_SIZE
47741d37e61SDave Gerlach
47841d37e61SDave GerlachENTRY(am43xx_pm_sram)
47941d37e61SDave Gerlach	.word am43xx_do_wfi
48041d37e61SDave Gerlach	.word am43xx_do_wfi_sz
48141d37e61SDave Gerlach	.word am43xx_resume_offset
48241d37e61SDave Gerlach	.word am43xx_emif_sram_table
48341d37e61SDave Gerlach	.word am43xx_pm_ro_sram_data
48441d37e61SDave Gerlach
4858c5a916fSKeerthyresume_addr:
4868c5a916fSKeerthy	.word   cpu_resume - PAGE_OFFSET + 0x80000000
48741d37e61SDave Gerlach.align 3
48841d37e61SDave Gerlach
48941d37e61SDave GerlachENTRY(am43xx_pm_ro_sram_data)
49041d37e61SDave Gerlach	.space AMX3_PM_RO_SRAM_DATA_SIZE
49141d37e61SDave Gerlach
49241d37e61SDave GerlachENTRY(am43xx_do_wfi_sz)
49341d37e61SDave Gerlach	.word	. - am43xx_do_wfi
494