diff options
Diffstat (limited to 'arch/arm/mach-tegra/sleep.h')
-rw-r--r-- | arch/arm/mach-tegra/sleep.h | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 59298f1efbe9..2557c3f687a8 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h @@ -25,6 +25,11 @@ #include <mach/iomap.h> +#ifdef CONFIG_CACHE_L2X0 +#define USE_TEGRA_CPU_SUSPEND 1 +#else +#define USE_TEGRA_CPU_SUSPEND 0 +#endif #ifndef CONFIG_TRUSTED_FOUNDATIONS /* FIXME: The code associated with this should be removed if our change to save the diagnostic regsiter in the CPU context is accepted. */ @@ -123,6 +128,61 @@ #endif .endm +.macro push_ctx_regs, tmp1 + push_stack_token \tmp1 @ debug check word + stmfd sp!, {r4 - r11, lr} + /* Save the current TTB0 and CONTEXTID registers. */ + mrc p15, 0, r5, c2, c0, 0 @ TTB 0 + mrc p15, 0, r6, c13, c0, 1 @ CONTEXTID +#if USE_TEGRA_DIAG_REG_SAVE + mrc p15, 0, r4, c15, c0, 1 @ read diagnostic register + stmfd sp!, {r4-r6} +#else + stmfd sp!, {r5-r6} +#endif + /* Switch to the tegra_pgd so that IRAM and the MMU shut-off code + will be flat mapped (VA==PA). We also do this because the common + ARM CPU state save/restore code doesn't support an external L2 + cache controller. If the current PGD is left active, the common + ARM MMU restore may (and eventually will) damage the currently + running page tables by adding a temporary flat section mapping + that could be picked up by other CPUs from the L2 cache + resulting in a kernel panic. */ + ldr r6, tegra_pgd_phys_address + ldr r6, [r6] + mov r7, #0 + dsb + mcr p15, 0, r7, c13, c0, 1 @ CONTEXTID = reserved context + isb + mcr p15, 0, r6, c2, c0, 0 @ TTB 0 + isb + mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB + mcr p15, 0, r7, c7, c5, 6 @ flush BTAC + mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache + dsb +.endm + +.macro pop_ctx_regs, tmp1, tmp2 +#if USE_TEGRA_DIAG_REG_SAVE + ldmfd sp!, {r4-r6} + mcr p15, 0, r4, c15, c0, 1 @ write diagnostic register +#else + ldmfd sp!, {r5-r6} +#endif + dsb + mcr p15, 0, r5, c2, c0, 0 @ TTB 0 + isb + mcr p15, 0, r6, c13, c0, 1 @ CONTEXTID = reserved context + isb + mov r7, #0 + mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB + mcr p15, 0, r7, c7, c5, 6 @ flush BTAC + mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache + dsb + ldmfd sp!, {r4 - r11, lr} + pop_stack_token \tmp1, \tmp2 @ debug stack debug token +.endm + #else /* !defined(__ASSEMBLY__) */ #define FLOW_CTRL_HALT_CPU(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \ @@ -145,9 +205,8 @@ static inline void flowctrl_writel(unsigned long val, void __iomem *addr) void tegra_pen_lock(void); void tegra_pen_unlock(void); void tegra_cpu_wfi(void); -int tegra_sleep_cpu_finish(unsigned long v2p); +void tegra_sleep_cpu_save(unsigned long v2p); void tegra_resume(void); -void tegra_cpu_resume(void); #ifdef CONFIG_ARCH_TEGRA_2x_SOC extern void tegra2_iram_start; @@ -156,14 +215,14 @@ int tegra2_cpu_is_resettable_soon(void); void tegra2_cpu_reset(int cpu); void tegra2_cpu_set_resettable_soon(void); void tegra2_cpu_clear_resettable(void); -int tegra2_sleep_core_finish(unsigned long int); +void tegra2_sleep_core(unsigned long v2p); void tegra2_hotplug_shutdown(void); void tegra2_sleep_wfi(unsigned long v2p); #else extern void tegra3_iram_start; extern void tegra3_iram_end; -int tegra3_sleep_core_finish(unsigned long int); -int tegra3_sleep_cpu_secondary_finish(unsigned long int); +void tegra3_sleep_core(unsigned long v2p); +void tegra3_sleep_cpu_secondary(unsigned long v2p); void tegra3_hotplug_shutdown(void); #endif |