aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorJoseph Lo <josephl@nvidia.com>2012-08-16 05:31:52 -0400
committerStephen Warren <swarren@nvidia.com>2012-09-13 13:41:06 -0400
commit453689e407f2b7c0a72a2e6fb2ef84c20475773b (patch)
tree83b532ff1b43e684ca3e92978c6d806bdc240f5c /arch/arm/mach-tegra
parent59b0f6825c15d24859e22b1024440ae2a094983e (diff)
ARM: tegra20: add CPU hotplug support
Hotplug function put CPU in offline or online mode at runtime. When the CPU been put into offline, it was been clock gated. The offline CPU can be power gated, when the remaining CPU goes into LP2. Based on the worked by: Colin Cross <ccross@android.com> Gary King <gking@nvidia.com> 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/common.c1
-rw-r--r--arch/arm/mach-tegra/hotplug.c8
-rw-r--r--arch/arm/mach-tegra/sleep-t20.S82
-rw-r--r--arch/arm/mach-tegra/sleep.h4
5 files changed, 96 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index efb2f90a8f77..84d21f514418 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_IDLE) += sleep.o
15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o
16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o 16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o
17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-t20.o
18obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o 19obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o
19obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o 20obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o
20obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-t30.o 21obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-t30.o
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 06520564d815..0560538bf598 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -136,6 +136,7 @@ void __init tegra20_init_early(void)
136 tegra_init_cache(0x331, 0x441); 136 tegra_init_cache(0x331, 0x441);
137 tegra_pmc_init(); 137 tegra_pmc_init();
138 tegra_powergate_init(); 138 tegra_powergate_init();
139 tegra20_hotplug_init();
139} 140}
140#endif 141#endif
141#ifdef CONFIG_ARCH_TEGRA_3x_SOC 142#ifdef CONFIG_ARCH_TEGRA_3x_SOC
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index be92d4c07606..d02a35476135 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -56,6 +56,14 @@ int platform_cpu_disable(unsigned int cpu)
56 return cpu == 0 ? -EPERM : 0; 56 return cpu == 0 ? -EPERM : 0;
57} 57}
58 58
59#ifdef CONFIG_ARCH_TEGRA_2x_SOC
60extern void tegra20_hotplug_shutdown(void);
61void __init tegra20_hotplug_init(void)
62{
63 tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
64}
65#endif
66
59#ifdef CONFIG_ARCH_TEGRA_3x_SOC 67#ifdef CONFIG_ARCH_TEGRA_3x_SOC
60extern void tegra30_hotplug_shutdown(void); 68extern void tegra30_hotplug_shutdown(void);
61void __init tegra30_hotplug_init(void) 69void __init tegra30_hotplug_init(void)
diff --git a/arch/arm/mach-tegra/sleep-t20.S b/arch/arm/mach-tegra/sleep-t20.S
new file mode 100644
index 000000000000..a36ae413e2b8
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep-t20.S
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
3 * Copyright (c) 2011, Google, Inc.
4 *
5 * Author: Colin Cross <ccross@android.com>
6 * Gary King <gking@nvidia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/linkage.h>
22
23#include <asm/assembler.h>
24
25#include <mach/iomap.h>
26
27#include "sleep.h"
28#include "flowctrl.h"
29
30#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
31/*
32 * tegra20_hotplug_shutdown(void)
33 *
34 * puts the current cpu in reset
35 * should never return
36 */
37ENTRY(tegra20_hotplug_shutdown)
38 /* Turn off SMP coherency */
39 exit_smp r4, r5
40
41 /* Put this CPU down */
42 cpu_id r0
43 bl tegra20_cpu_shutdown
44 mov pc, lr @ should never get here
45ENDPROC(tegra20_hotplug_shutdown)
46
47/*
48 * tegra20_cpu_shutdown(int cpu)
49 *
50 * r0 is cpu to reset
51 *
52 * puts the specified CPU in wait-for-event mode on the flow controller
53 * and puts the CPU in reset
54 * can be called on the current cpu or another cpu
55 * if called on the current cpu, does not return
56 * MUST NOT BE CALLED FOR CPU 0.
57 *
58 * corrupts r0-r3, r12
59 */
60ENTRY(tegra20_cpu_shutdown)
61 cmp r0, #0
62 moveq pc, lr @ must not be called for CPU 0
63
64 cpu_to_halt_reg r1, r0
65 ldr r3, =TEGRA_FLOW_CTRL_VIRT
66 mov r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
67 str r2, [r3, r1] @ put flow controller in wait event mode
68 ldr r2, [r3, r1]
69 isb
70 dsb
71 movw r1, 0x1011
72 mov r1, r1, lsl r0
73 ldr r3, =TEGRA_CLK_RESET_VIRT
74 str r1, [r3, #0x340] @ put slave CPU in reset
75 isb
76 dsb
77 cpu_id r3
78 cmp r3, r0
79 beq .
80 mov pc, lr
81ENDPROC(tegra20_cpu_shutdown)
82#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 0f047eb3ca2e..e25a7cd703d9 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -23,6 +23,8 @@
23 + IO_CPU_VIRT) 23 + IO_CPU_VIRT)
24#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \ 24#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
25 + IO_PPSB_VIRT) 25 + IO_PPSB_VIRT)
26#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
27 + IO_PPSB_VIRT)
26 28
27#ifdef __ASSEMBLY__ 29#ifdef __ASSEMBLY__
28/* returns the offset of the flow controller halt register for a cpu */ 30/* returns the offset of the flow controller halt register for a cpu */
@@ -72,8 +74,10 @@
72#else 74#else
73 75
74#ifdef CONFIG_HOTPLUG_CPU 76#ifdef CONFIG_HOTPLUG_CPU
77void tegra20_hotplug_init(void);
75void tegra30_hotplug_init(void); 78void tegra30_hotplug_init(void);
76#else 79#else
80static inline void tegra20_hotplug_init(void) {}
77static inline void tegra30_hotplug_init(void) {} 81static inline void tegra30_hotplug_init(void) {}
78#endif 82#endif
79 83