aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/headsmp.S60
-rw-r--r--arch/arm/mach-tegra/reset.c6
-rw-r--r--arch/arm/mach-tegra/sleep.h1
3 files changed, 67 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 93f0370cc95b..82dc84b6b868 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -68,6 +68,55 @@ ENTRY(tegra_secondary_startup)
68 b secondary_startup 68 b secondary_startup
69ENDPROC(tegra_secondary_startup) 69ENDPROC(tegra_secondary_startup)
70 70
71#ifdef CONFIG_PM_SLEEP
72/*
73 * tegra_resume
74 *
75 * CPU boot vector when restarting the a CPU following
76 * an LP2 transition. Also branched to by LP0 and LP1 resume after
77 * re-enabling sdram.
78 */
79ENTRY(tegra_resume)
80 bl v7_invalidate_l1
81 /* Enable coresight */
82 mov32 r0, 0xC5ACCE55
83 mcr p14, 0, r0, c7, c12, 6
84
85 cpu_id r0
86 cmp r0, #0 @ CPU0?
87 bne cpu_resume @ no
88
89#ifdef CONFIG_ARCH_TEGRA_3x_SOC
90 /* Are we on Tegra20? */
91 mov32 r6, TEGRA_APB_MISC_BASE
92 ldr r0, [r6, #APB_MISC_GP_HIDREV]
93 and r0, r0, #0xff00
94 cmp r0, #(0x20 << 8)
95 beq 1f @ Yes
96 /* Clear the flow controller flags for this CPU. */
97 mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR
98 ldr r1, [r2]
99 /* Clear event & intr flag */
100 orr r1, r1, \
101 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
102 movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps
103 bic r1, r1, r0
104 str r1, [r2]
1051:
106#endif
107
108#ifdef CONFIG_HAVE_ARM_SCU
109 /* enable SCU */
110 mov32 r0, TEGRA_ARM_PERIF_BASE
111 ldr r1, [r0]
112 orr r1, r1, #1
113 str r1, [r0]
114#endif
115
116 b cpu_resume
117ENDPROC(tegra_resume)
118#endif
119
71 .align L1_CACHE_SHIFT 120 .align L1_CACHE_SHIFT
72ENTRY(__tegra_cpu_reset_handler_start) 121ENTRY(__tegra_cpu_reset_handler_start)
73 122
@@ -121,6 +170,17 @@ ENTRY(__tegra_cpu_reset_handler)
1211: 1701:
122#endif 171#endif
123 172
173 /* Waking up from LP2? */
174 ldr r9, [r12, #RESET_DATA(MASK_LP2)]
175 tst r9, r11 @ if in_lp2
176 beq __is_not_lp2
177 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)]
178 cmp lr, #0
179 bleq __die @ no LP2 startup handler
180 bx lr
181
182__is_not_lp2:
183
124#ifdef CONFIG_SMP 184#ifdef CONFIG_SMP
125 /* 185 /*
126 * Can only be secondary boot (initial or hotplug) but CPU 0 186 * Can only be secondary boot (initial or hotplug) but CPU 0
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index e05da7d10c3b..3fd89ecd158e 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -25,6 +25,7 @@
25#include "iomap.h" 25#include "iomap.h"
26#include "irammap.h" 26#include "irammap.h"
27#include "reset.h" 27#include "reset.h"
28#include "sleep.h"
28#include "fuse.h" 29#include "fuse.h"
29 30
30#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \ 31#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
@@ -79,5 +80,10 @@ void __init tegra_cpu_reset_handler_init(void)
79 virt_to_phys((void *)tegra_secondary_startup); 80 virt_to_phys((void *)tegra_secondary_startup);
80#endif 81#endif
81 82
83#ifdef CONFIG_PM_SLEEP
84 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
85 virt_to_phys((void *)tegra_resume);
86#endif
87
82 tegra_cpu_reset_handler_enable(); 88 tegra_cpu_reset_handler_enable();
83} 89}
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 4889b281c5f9..addb83f5bc73 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -72,6 +72,7 @@
72 dsb 72 dsb
73.endm 73.endm
74#else 74#else
75void tegra_resume(void);
75 76
76#ifdef CONFIG_HOTPLUG_CPU 77#ifdef CONFIG_HOTPLUG_CPU
77void tegra20_hotplug_init(void); 78void tegra20_hotplug_init(void);