aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorJoseph Lo <josephl@nvidia.com>2013-05-20 06:39:29 -0400
committerStephen Warren <swarren@nvidia.com>2013-05-22 17:19:22 -0400
commit33d5c01915ccca298a5fda7e0cb33199d225e03a (patch)
tree2ea8efaabc2265ea6d03a902b2b6adfd8ec62ba7 /arch/arm/mach-tegra
parent31972fd95527a5942b777e89404501d5421a0df0 (diff)
ARM: tegra114: add CPU hotplug support
The Tegra114 is a quad cores SoC. Each core can be hotplugged including CPU0. The hotplug sequence can be controlled by setting event trigger in flow controller. Then the flow controller will take care all the power sequence that include CPU up and down. Signed-off-by: Joseph Lo <josephl@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/hotplug.c2
-rw-r--r--arch/arm/mach-tegra/reset-handler.S15
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S30
-rw-r--r--arch/arm/mach-tegra/sleep.h2
5 files changed, 42 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index d011f0ad49c4..98b184efc110 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
30obj-$(CONFIG_TEGRA_PCI) += pcie.o 30obj-$(CONFIG_TEGRA_PCI) += pcie.o
31 31
32obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o 32obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
33obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
33ifeq ($(CONFIG_CPU_IDLE),y) 34ifeq ($(CONFIG_CPU_IDLE),y)
34obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o 35obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
35endif 36endif
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 184914a68d73..d07f152b275f 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -55,4 +55,6 @@ void __init tegra_hotplug_init(void)
55 tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 55 tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
56 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 56 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
57 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 57 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
58 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
59 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
58} 60}
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 424e01f5bca7..d2042ac736eb 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -38,18 +38,24 @@
38 * CPU boot vector when restarting the a CPU following 38 * CPU boot vector when restarting the a CPU following
39 * an LP2 transition. Also branched to by LP0 and LP1 resume after 39 * an LP2 transition. Also branched to by LP0 and LP1 resume after
40 * re-enabling sdram. 40 * re-enabling sdram.
41 *
42 * r6: SoC ID
41 */ 43 */
42ENTRY(tegra_resume) 44ENTRY(tegra_resume)
43 bl v7_invalidate_l1 45 bl v7_invalidate_l1
44 46
45 cpu_id r0 47 cpu_id r0
48 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
49 cmp r6, #TEGRA114
50 beq no_cpu0_chk
51
46 cmp r0, #0 @ CPU0? 52 cmp r0, #0 @ CPU0?
47 THUMB( it ne ) 53 THUMB( it ne )
48 bne cpu_resume @ no 54 bne cpu_resume @ no
55no_cpu0_chk:
49 56
50#ifndef CONFIG_ARCH_TEGRA_2x_SOC 57#ifndef CONFIG_ARCH_TEGRA_2x_SOC
51 /* Are we on Tegra20? */ 58 /* Are we on Tegra20? */
52 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
53 cmp r6, #TEGRA20 59 cmp r6, #TEGRA20
54 beq 1f @ Yes 60 beq 1f @ Yes
55 /* Clear the flow controller flags for this CPU. */ 61 /* Clear the flow controller flags for this CPU. */
@@ -187,11 +193,14 @@ __is_not_lp2:
187 193
188#ifdef CONFIG_SMP 194#ifdef CONFIG_SMP
189 /* 195 /*
190 * Can only be secondary boot (initial or hotplug) but CPU 0 196 * Can only be secondary boot (initial or hotplug)
191 * cannot be here. 197 * CPU0 can't be here for Tegra20/30
192 */ 198 */
199 cmp r6, #TEGRA114
200 beq __no_cpu0_chk
193 cmp r10, #0 201 cmp r10, #0
194 bleq __die @ CPU0 cannot be here 202 bleq __die @ CPU0 cannot be here
203__no_cpu0_chk:
195 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] 204 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
196 cmp lr, #0 205 cmp lr, #0
197 bleq __die @ no secondary startup handler 206 bleq __die @ no secondary startup handler
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index d29dfcce948d..ada8821b48be 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -19,6 +19,7 @@
19#include <asm/assembler.h> 19#include <asm/assembler.h>
20#include <asm/asm-offsets.h> 20#include <asm/asm-offsets.h>
21 21
22#include "fuse.h"
22#include "sleep.h" 23#include "sleep.h"
23#include "flowctrl.h" 24#include "flowctrl.h"
24 25
@@ -43,14 +44,19 @@ ENDPROC(tegra30_hotplug_shutdown)
43 * 44 *
44 * Puts the current CPU in wait-for-event mode on the flow controller 45 * Puts the current CPU in wait-for-event mode on the flow controller
45 * and powergates it -- flags (in R0) indicate the request type. 46 * and powergates it -- flags (in R0) indicate the request type.
46 * Must never be called for CPU 0.
47 * 47 *
48 * corrupts r0-r4, r12 48 * r10 = SoC ID
49 * corrupts r0-r4, r10-r12
49 */ 50 */
50ENTRY(tegra30_cpu_shutdown) 51ENTRY(tegra30_cpu_shutdown)
51 cpu_id r3 52 cpu_id r3
53 tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
54 cmp r10, #TEGRA30
55 bne _no_cpu0_chk @ It's not Tegra30
56
52 cmp r3, #0 57 cmp r3, #0
53 moveq pc, lr @ Must never be called for CPU 0 58 moveq pc, lr @ Must never be called for CPU 0
59_no_cpu0_chk:
54 60
55 ldr r12, =TEGRA_FLOW_CTRL_VIRT 61 ldr r12, =TEGRA_FLOW_CTRL_VIRT
56 cpu_to_csr_reg r1, r3 62 cpu_to_csr_reg r1, r3
@@ -65,7 +71,9 @@ ENTRY(tegra30_cpu_shutdown)
65 movw r12, \ 71 movw r12, \
66 FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \ 72 FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
67 FLOW_CTRL_CSR_ENABLE 73 FLOW_CTRL_CSR_ENABLE
68 mov r4, #(1 << 4) 74 cmp r10, #TEGRA30
75 moveq r4, #(1 << 4) @ wfe bitmap
76 movne r4, #(1 << 8) @ wfi bitmap
69 ARM( orr r12, r12, r4, lsl r3 ) 77 ARM( orr r12, r12, r4, lsl r3 )
70 THUMB( lsl r4, r4, r3 ) 78 THUMB( lsl r4, r4, r3 )
71 THUMB( orr r12, r12, r4 ) 79 THUMB( orr r12, r12, r4 )
@@ -79,9 +87,20 @@ delay_1:
79 cpsid a @ disable imprecise aborts. 87 cpsid a @ disable imprecise aborts.
80 ldr r3, [r1] @ read CSR 88 ldr r3, [r1] @ read CSR
81 str r3, [r1] @ clear CSR 89 str r3, [r1] @ clear CSR
90
82 tst r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN 91 tst r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
92 beq flow_ctrl_setting_for_lp2
93
94 /* flow controller set up for hotplug */
95 mov r3, #FLOW_CTRL_WAITEVENT @ For hotplug
96 b flow_ctrl_done
97flow_ctrl_setting_for_lp2:
98 /* flow controller set up for LP2 */
99 cmp r10, #TEGRA30
83 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2 100 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2
84 movne r3, #FLOW_CTRL_WAITEVENT @ For hotplug 101 movne r3, #FLOW_CTRL_WAITEVENT
102flow_ctrl_done:
103 cmp r10, #TEGRA30
85 str r3, [r2] 104 str r3, [r2]
86 ldr r0, [r2] 105 ldr r0, [r2]
87 b wfe_war 106 b wfe_war
@@ -89,7 +108,8 @@ delay_1:
89__cpu_reset_again: 108__cpu_reset_again:
90 dsb 109 dsb
91 .align 5 110 .align 5
92 wfe @ CPU should be power gated here 111 wfeeq @ CPU should be power gated here
112 wfine
93wfe_war: 113wfe_war:
94 b __cpu_reset_again 114 b __cpu_reset_again
95 115
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 2269c0d6fa67..98b7da698f2b 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -25,6 +25,8 @@
25 + IO_PPSB_VIRT) 25 + IO_PPSB_VIRT)
26#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \ 26#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
27 + IO_PPSB_VIRT) 27 + IO_PPSB_VIRT)
28#define TEGRA_APB_MISC_VIRT (TEGRA_APB_MISC_BASE - IO_APB_PHYS \
29 + IO_APB_VIRT)
28#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT) 30#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
29 31
30/* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */ 32/* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */