aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-02-05 15:10:18 -0500
committerOlof Johansson <olof@lixom.net>2013-02-05 15:10:18 -0500
commitf0390669d13b0a1592fc7906445b4f6c8ec5af23 (patch)
tree4a27ffbd016d24f54ba1e3a38d46a386ab924bc6
parentb60decad7791694a36ad218cede77a407c1475ce (diff)
parent24e30c9417230b359bf6dfeb923e90138df7c112 (diff)
Merge tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/cleanup
From Stephen Warren: ARM: tegra: cleanup This pull request contains various cleanup and minor changes to core Tegra code: * Tegra clocksource driver is moved to drivers/clocksource. * Various typos, warning cleanup, statics cleanup, section mismatch fixes, etc. * Various small fixes/cleanups for CPU/hotplug/SMP code. This pull request is based on a merge of v3.8-rc3 and at least part of arm-soc's timer/cleanup branch. * tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra: ARM: tegra: fix compile error when disable CPU_IDLE ARM: tegra30: make the wait time of CPU power up to proportional to HZ ARM: tegra: make device can run on UP ARM: tegra: clean up the CPUINIT section ARM: tegra: moving the clock gating procedure to tegra_cpu_kill ARM: tegra: update the cache maintenance order for CPU shutdown ARM: tegra30: fix power up sequence for boot_secondary ARM: tegra: cpufreq: move clk_get/put out of function tegra_cpu_init/exit ARM: tegra: fix Kconfig warnings when !SMP ARM: tegra: Make variables static clocksource: tegra: cosmetic: Fix error message ARM: tegra: move timer.c to drivers/clocksource/ Signed-off-by: Olof Johansson <olof@lixom.net> Trivial conflicts: arch/arm/mach-tegra/board-dt-tegra20.c arch/arm/mach-tegra/board-dt-tegra30.c drivers/clocksource/Makefile
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-tegra/Kconfig4
-rw-r--r--arch/arm/mach-tegra/Makefile6
-rw-r--r--arch/arm/mach-tegra/apbio.c2
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c13
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c5
-rw-r--r--arch/arm/mach-tegra/board.h1
-rw-r--r--arch/arm/mach-tegra/common.c3
-rw-r--r--arch/arm/mach-tegra/common.h1
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c40
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c6
-rw-r--r--arch/arm/mach-tegra/flowctrl.c4
-rw-r--r--arch/arm/mach-tegra/headsmp.S221
-rw-r--r--arch/arm/mach-tegra/hotplug.c21
-rw-r--r--arch/arm/mach-tegra/platsmp.c43
-rw-r--r--arch/arm/mach-tegra/pm.c4
-rw-r--r--arch/arm/mach-tegra/reset-handler.S239
-rw-r--r--arch/arm/mach-tegra/reset.c2
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S3
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S3
-rw-r--r--arch/arm/mach-tegra/sleep.S4
-rw-r--r--arch/arm/mach-tegra/sleep.h1
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks_data.c6
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/tegra20_timer.c (renamed from arch/arm/mach-tegra/timer.c)9
25 files changed, 352 insertions, 291 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index af74b0fc4faa..c2950f3e678e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -642,6 +642,7 @@ config ARCH_TEGRA
642 select ARCH_HAS_CPUFREQ 642 select ARCH_HAS_CPUFREQ
643 select CLKDEV_LOOKUP 643 select CLKDEV_LOOKUP
644 select CLKSRC_MMIO 644 select CLKSRC_MMIO
645 select CLKSRC_OF
645 select COMMON_CLK 646 select COMMON_CLK
646 select GENERIC_CLOCKEVENTS 647 select GENERIC_CLOCKEVENTS
647 select HAVE_CLK 648 select HAVE_CLK
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index b442f15fd01a..1ec7f80e2af5 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -6,9 +6,9 @@ config ARCH_TEGRA_2x_SOC
6 bool "Enable support for Tegra20 family" 6 bool "Enable support for Tegra20 family"
7 select ARCH_REQUIRE_GPIOLIB 7 select ARCH_REQUIRE_GPIOLIB
8 select ARM_ERRATA_720789 8 select ARM_ERRATA_720789
9 select ARM_ERRATA_742230 9 select ARM_ERRATA_742230 if SMP
10 select ARM_ERRATA_751472 10 select ARM_ERRATA_751472
11 select ARM_ERRATA_754327 11 select ARM_ERRATA_754327 if SMP
12 select ARM_ERRATA_764369 if SMP 12 select ARM_ERRATA_764369 if SMP
13 select ARM_GIC 13 select ARM_GIC
14 select CPU_FREQ_TABLE if CPU_FREQ 14 select CPU_FREQ_TABLE if CPU_FREQ
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 0979e8bba78a..f0520961bafe 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -2,15 +2,16 @@ obj-y += common.o
2obj-y += io.o 2obj-y += io.o
3obj-y += irq.o 3obj-y += irq.o
4obj-y += clock.o 4obj-y += clock.o
5obj-y += timer.o
6obj-y += fuse.o 5obj-y += fuse.o
7obj-y += pmc.o 6obj-y += pmc.o
8obj-y += flowctrl.o 7obj-y += flowctrl.o
9obj-y += powergate.o 8obj-y += powergate.o
10obj-y += apbio.o 9obj-y += apbio.o
11obj-y += pm.o 10obj-y += pm.o
11obj-y += reset.o
12obj-y += reset-handler.o
13obj-y += sleep.o
12obj-$(CONFIG_CPU_IDLE) += cpuidle.o 14obj-$(CONFIG_CPU_IDLE) += cpuidle.o
13obj-$(CONFIG_CPU_IDLE) += sleep.o
14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o
15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o 16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o
16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
@@ -27,7 +28,6 @@ ifeq ($(CONFIG_CPU_IDLE),y)
27obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o 28obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
28endif 29endif
29obj-$(CONFIG_SMP) += platsmp.o headsmp.o 30obj-$(CONFIG_SMP) += platsmp.o headsmp.o
30obj-$(CONFIG_SMP) += reset.o
31obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 31obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
32obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 32obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
33obj-$(CONFIG_TEGRA_PCI) += pcie.o 33obj-$(CONFIG_TEGRA_PCI) += pcie.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index d091675ba376..d7aa52ea6cfc 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -38,7 +38,7 @@ static void tegra_apb_writel_direct(u32 value, unsigned long offset);
38static struct dma_chan *tegra_apb_dma_chan; 38static struct dma_chan *tegra_apb_dma_chan;
39static struct dma_slave_config dma_sconfig; 39static struct dma_slave_config dma_sconfig;
40 40
41bool tegra_apb_dma_init(void) 41static bool tegra_apb_dma_init(void)
42{ 42{
43 dma_cap_mask_t mask; 43 dma_cap_mask_t mask;
44 44
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 5ed81bab2d4b..d320f7ad7350 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -15,6 +15,7 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/clocksource.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -43,31 +44,31 @@
43#include "common.h" 44#include "common.h"
44#include "iomap.h" 45#include "iomap.h"
45 46
46struct tegra_ehci_platform_data tegra_ehci1_pdata = { 47static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
47 .operating_mode = TEGRA_USB_OTG, 48 .operating_mode = TEGRA_USB_OTG,
48 .power_down_on_bus_suspend = 1, 49 .power_down_on_bus_suspend = 1,
49 .vbus_gpio = -1, 50 .vbus_gpio = -1,
50}; 51};
51 52
52struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { 53static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
53 .reset_gpio = -1, 54 .reset_gpio = -1,
54 .clk = "cdev2", 55 .clk = "cdev2",
55}; 56};
56 57
57struct tegra_ehci_platform_data tegra_ehci2_pdata = { 58static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
58 .phy_config = &tegra_ehci2_ulpi_phy_config, 59 .phy_config = &tegra_ehci2_ulpi_phy_config,
59 .operating_mode = TEGRA_USB_HOST, 60 .operating_mode = TEGRA_USB_HOST,
60 .power_down_on_bus_suspend = 1, 61 .power_down_on_bus_suspend = 1,
61 .vbus_gpio = -1, 62 .vbus_gpio = -1,
62}; 63};
63 64
64struct tegra_ehci_platform_data tegra_ehci3_pdata = { 65static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
65 .operating_mode = TEGRA_USB_HOST, 66 .operating_mode = TEGRA_USB_HOST,
66 .power_down_on_bus_suspend = 1, 67 .power_down_on_bus_suspend = 1,
67 .vbus_gpio = -1, 68 .vbus_gpio = -1,
68}; 69};
69 70
70struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 71static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
71 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), 72 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
72 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), 73 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
73 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), 74 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
@@ -200,7 +201,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
200 .smp = smp_ops(tegra_smp_ops), 201 .smp = smp_ops(tegra_smp_ops),
201 .init_early = tegra20_init_early, 202 .init_early = tegra20_init_early,
202 .init_irq = tegra_dt_init_irq, 203 .init_irq = tegra_dt_init_irq,
203 .init_time = tegra_init_timer, 204 .init_time = clocksource_of_init,
204 .init_machine = tegra_dt_init, 205 .init_machine = tegra_dt_init,
205 .init_late = tegra_dt_init_late, 206 .init_late = tegra_dt_init_late,
206 .restart = tegra_assert_system_reset, 207 .restart = tegra_assert_system_reset,
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 12dc2ddeca64..97e1f67fc31d 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -23,6 +23,7 @@
23 * 23 *
24 */ 24 */
25 25
26#include <linux/clocksource.h>
26#include <linux/kernel.h> 27#include <linux/kernel.h>
27#include <linux/of.h> 28#include <linux/of.h>
28#include <linux/of_address.h> 29#include <linux/of_address.h>
@@ -37,7 +38,7 @@
37#include "common.h" 38#include "common.h"
38#include "iomap.h" 39#include "iomap.h"
39 40
40struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { 41static struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
41 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), 42 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
42 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), 43 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
43 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), 44 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
@@ -111,7 +112,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
111 .map_io = tegra_map_common_io, 112 .map_io = tegra_map_common_io,
112 .init_early = tegra30_init_early, 113 .init_early = tegra30_init_early,
113 .init_irq = tegra_dt_init_irq, 114 .init_irq = tegra_dt_init_irq,
114 .init_time = tegra_init_timer, 115 .init_time = clocksource_of_init,
115 .init_machine = tegra30_dt_init, 116 .init_machine = tegra30_dt_init,
116 .init_late = tegra_init_late, 117 .init_late = tegra_init_late,
117 .restart = tegra_assert_system_reset, 118 .restart = tegra_assert_system_reset,
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 744cdd246f6a..da8f5a3c4240 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -55,5 +55,4 @@ static inline int harmony_pcie_init(void) { return 0; }
55 55
56void __init tegra_paz00_wifikill_init(void); 56void __init tegra_paz00_wifikill_init(void);
57 57
58extern void tegra_init_timer(void);
59#endif 58#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 3599959517b3..8f0ffe97ffee 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -36,6 +36,7 @@
36#include "apbio.h" 36#include "apbio.h"
37#include "sleep.h" 37#include "sleep.h"
38#include "pm.h" 38#include "pm.h"
39#include "reset.h"
39 40
40/* 41/*
41 * Storage for debug-macro.S's state. 42 * Storage for debug-macro.S's state.
@@ -131,6 +132,7 @@ static void __init tegra_init_cache(void)
131#ifdef CONFIG_ARCH_TEGRA_2x_SOC 132#ifdef CONFIG_ARCH_TEGRA_2x_SOC
132void __init tegra20_init_early(void) 133void __init tegra20_init_early(void)
133{ 134{
135 tegra_cpu_reset_handler_init();
134 tegra_apb_io_init(); 136 tegra_apb_io_init();
135 tegra_init_fuse(); 137 tegra_init_fuse();
136 tegra2_init_clocks(); 138 tegra2_init_clocks();
@@ -144,6 +146,7 @@ void __init tegra20_init_early(void)
144#ifdef CONFIG_ARCH_TEGRA_3x_SOC 146#ifdef CONFIG_ARCH_TEGRA_3x_SOC
145void __init tegra30_init_early(void) 147void __init tegra30_init_early(void)
146{ 148{
149 tegra_cpu_reset_handler_init();
147 tegra_apb_io_init(); 150 tegra_apb_io_init();
148 tegra_init_fuse(); 151 tegra_init_fuse();
149 tegra30_init_clocks(); 152 tegra30_init_clocks();
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
index 02f71b4f1e51..32f8eb3fe344 100644
--- a/arch/arm/mach-tegra/common.h
+++ b/arch/arm/mach-tegra/common.h
@@ -1,4 +1,5 @@
1extern struct smp_operations tegra_smp_ops; 1extern struct smp_operations tegra_smp_ops;
2 2
3extern int tegra_cpu_kill(unsigned int cpu);
3extern void tegra_cpu_die(unsigned int cpu); 4extern void tegra_cpu_die(unsigned int cpu);
4extern int tegra_cpu_disable(unsigned int cpu); 5extern int tegra_cpu_disable(unsigned int cpu);
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index a74d3c7d2e26..85d4a23bba03 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -214,24 +214,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
214 if (policy->cpu >= NUM_CPUS) 214 if (policy->cpu >= NUM_CPUS)
215 return -EINVAL; 215 return -EINVAL;
216 216
217 cpu_clk = clk_get_sys(NULL, "cpu");
218 if (IS_ERR(cpu_clk))
219 return PTR_ERR(cpu_clk);
220
221 pll_x_clk = clk_get_sys(NULL, "pll_x");
222 if (IS_ERR(pll_x_clk))
223 return PTR_ERR(pll_x_clk);
224
225 pll_p_clk = clk_get_sys(NULL, "pll_p");
226 if (IS_ERR(pll_p_clk))
227 return PTR_ERR(pll_p_clk);
228
229 emc_clk = clk_get_sys("cpu", "emc");
230 if (IS_ERR(emc_clk)) {
231 clk_put(cpu_clk);
232 return PTR_ERR(emc_clk);
233 }
234
235 clk_prepare_enable(emc_clk); 217 clk_prepare_enable(emc_clk);
236 clk_prepare_enable(cpu_clk); 218 clk_prepare_enable(cpu_clk);
237 219
@@ -256,8 +238,6 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy)
256{ 238{
257 cpufreq_frequency_table_cpuinfo(policy, freq_table); 239 cpufreq_frequency_table_cpuinfo(policy, freq_table);
258 clk_disable_unprepare(emc_clk); 240 clk_disable_unprepare(emc_clk);
259 clk_put(emc_clk);
260 clk_put(cpu_clk);
261 return 0; 241 return 0;
262} 242}
263 243
@@ -278,12 +258,32 @@ static struct cpufreq_driver tegra_cpufreq_driver = {
278 258
279static int __init tegra_cpufreq_init(void) 259static int __init tegra_cpufreq_init(void)
280{ 260{
261 cpu_clk = clk_get_sys(NULL, "cpu");
262 if (IS_ERR(cpu_clk))
263 return PTR_ERR(cpu_clk);
264
265 pll_x_clk = clk_get_sys(NULL, "pll_x");
266 if (IS_ERR(pll_x_clk))
267 return PTR_ERR(pll_x_clk);
268
269 pll_p_clk = clk_get_sys(NULL, "pll_p");
270 if (IS_ERR(pll_p_clk))
271 return PTR_ERR(pll_p_clk);
272
273 emc_clk = clk_get_sys("cpu", "emc");
274 if (IS_ERR(emc_clk)) {
275 clk_put(cpu_clk);
276 return PTR_ERR(emc_clk);
277 }
278
281 return cpufreq_register_driver(&tegra_cpufreq_driver); 279 return cpufreq_register_driver(&tegra_cpufreq_driver);
282} 280}
283 281
284static void __exit tegra_cpufreq_exit(void) 282static void __exit tegra_cpufreq_exit(void)
285{ 283{
286 cpufreq_unregister_driver(&tegra_cpufreq_driver); 284 cpufreq_unregister_driver(&tegra_cpufreq_driver);
285 clk_put(emc_clk);
286 clk_put(cpu_clk);
287} 287}
288 288
289 289
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index 5e8cbf5b799f..82530bd9b8c2 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -121,9 +121,9 @@ static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
121} 121}
122#endif 122#endif
123 123
124static int __cpuinit tegra30_idle_lp2(struct cpuidle_device *dev, 124static int tegra30_idle_lp2(struct cpuidle_device *dev,
125 struct cpuidle_driver *drv, 125 struct cpuidle_driver *drv,
126 int index) 126 int index)
127{ 127{
128 u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; 128 u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
129 bool entered_lp2 = false; 129 bool entered_lp2 = false;
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index a2250ddae797..5393eb2cae21 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -26,14 +26,14 @@
26#include "flowctrl.h" 26#include "flowctrl.h"
27#include "iomap.h" 27#include "iomap.h"
28 28
29u8 flowctrl_offset_halt_cpu[] = { 29static u8 flowctrl_offset_halt_cpu[] = {
30 FLOW_CTRL_HALT_CPU0_EVENTS, 30 FLOW_CTRL_HALT_CPU0_EVENTS,
31 FLOW_CTRL_HALT_CPU1_EVENTS, 31 FLOW_CTRL_HALT_CPU1_EVENTS,
32 FLOW_CTRL_HALT_CPU1_EVENTS + 8, 32 FLOW_CTRL_HALT_CPU1_EVENTS + 8,
33 FLOW_CTRL_HALT_CPU1_EVENTS + 16, 33 FLOW_CTRL_HALT_CPU1_EVENTS + 16,
34}; 34};
35 35
36u8 flowctrl_offset_cpu_csr[] = { 36static u8 flowctrl_offset_cpu_csr[] = {
37 FLOW_CTRL_CPU0_CSR, 37 FLOW_CTRL_CPU0_CSR,
38 FLOW_CTRL_CPU1_CSR, 38 FLOW_CTRL_CPU1_CSR,
39 FLOW_CTRL_CPU1_CSR + 8, 39 FLOW_CTRL_CPU1_CSR + 8,
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 4a317fae6860..b2834810b02b 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -1,22 +1,9 @@
1#include <linux/linkage.h> 1#include <linux/linkage.h>
2#include <linux/init.h> 2#include <linux/init.h>
3 3
4#include <asm/cache.h>
5#include <asm/asm-offsets.h>
6#include <asm/hardware/cache-l2x0.h>
7
8#include "flowctrl.h"
9#include "iomap.h"
10#include "reset.h"
11#include "sleep.h" 4#include "sleep.h"
12 5
13#define APB_MISC_GP_HIDREV 0x804
14#define PMC_SCRATCH41 0x140
15
16#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
17
18 .section ".text.head", "ax" 6 .section ".text.head", "ax"
19 __CPUINIT
20 7
21/* 8/*
22 * Tegra specific entry point for secondary CPUs. 9 * Tegra specific entry point for secondary CPUs.
@@ -61,7 +48,6 @@ ENTRY(v7_invalidate_l1)
61 mov pc, lr 48 mov pc, lr
62ENDPROC(v7_invalidate_l1) 49ENDPROC(v7_invalidate_l1)
63 50
64
65ENTRY(tegra_secondary_startup) 51ENTRY(tegra_secondary_startup)
66 bl v7_invalidate_l1 52 bl v7_invalidate_l1
67 /* Enable coresight */ 53 /* Enable coresight */
@@ -69,210 +55,3 @@ ENTRY(tegra_secondary_startup)
69 mcr p14, 0, r0, c7, c12, 6 55 mcr p14, 0, r0, c7, c12, 6
70 b secondary_startup 56 b secondary_startup
71ENDPROC(tegra_secondary_startup) 57ENDPROC(tegra_secondary_startup)
72
73#ifdef CONFIG_PM_SLEEP
74/*
75 * tegra_resume
76 *
77 * CPU boot vector when restarting the a CPU following
78 * an LP2 transition. Also branched to by LP0 and LP1 resume after
79 * re-enabling sdram.
80 */
81ENTRY(tegra_resume)
82 bl v7_invalidate_l1
83 /* Enable coresight */
84 mov32 r0, 0xC5ACCE55
85 mcr p14, 0, r0, c7, c12, 6
86
87 cpu_id r0
88 cmp r0, #0 @ CPU0?
89 bne cpu_resume @ no
90
91#ifdef CONFIG_ARCH_TEGRA_3x_SOC
92 /* Are we on Tegra20? */
93 mov32 r6, TEGRA_APB_MISC_BASE
94 ldr r0, [r6, #APB_MISC_GP_HIDREV]
95 and r0, r0, #0xff00
96 cmp r0, #(0x20 << 8)
97 beq 1f @ Yes
98 /* Clear the flow controller flags for this CPU. */
99 mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR
100 ldr r1, [r2]
101 /* Clear event & intr flag */
102 orr r1, r1, \
103 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
104 movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps
105 bic r1, r1, r0
106 str r1, [r2]
1071:
108#endif
109
110#ifdef CONFIG_HAVE_ARM_SCU
111 /* enable SCU */
112 mov32 r0, TEGRA_ARM_PERIF_BASE
113 ldr r1, [r0]
114 orr r1, r1, #1
115 str r1, [r0]
116#endif
117
118 /* L2 cache resume & re-enable */
119 l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
120
121 b cpu_resume
122ENDPROC(tegra_resume)
123#endif
124
125#ifdef CONFIG_CACHE_L2X0
126 .globl l2x0_saved_regs_addr
127l2x0_saved_regs_addr:
128 .long 0
129#endif
130
131 .align L1_CACHE_SHIFT
132ENTRY(__tegra_cpu_reset_handler_start)
133
134/*
135 * __tegra_cpu_reset_handler:
136 *
137 * Common handler for all CPU reset events.
138 *
139 * Register usage within the reset handler:
140 *
141 * R7 = CPU present (to the OS) mask
142 * R8 = CPU in LP1 state mask
143 * R9 = CPU in LP2 state mask
144 * R10 = CPU number
145 * R11 = CPU mask
146 * R12 = pointer to reset handler data
147 *
148 * NOTE: This code is copied to IRAM. All code and data accesses
149 * must be position-independent.
150 */
151
152 .align L1_CACHE_SHIFT
153ENTRY(__tegra_cpu_reset_handler)
154
155 cpsid aif, 0x13 @ SVC mode, interrupts disabled
156 mrc p15, 0, r10, c0, c0, 5 @ MPIDR
157 and r10, r10, #0x3 @ R10 = CPU number
158 mov r11, #1
159 mov r11, r11, lsl r10 @ R11 = CPU mask
160 adr r12, __tegra_cpu_reset_handler_data
161
162#ifdef CONFIG_SMP
163 /* Does the OS know about this CPU? */
164 ldr r7, [r12, #RESET_DATA(MASK_PRESENT)]
165 tst r7, r11 @ if !present
166 bleq __die @ CPU not present (to OS)
167#endif
168
169#ifdef CONFIG_ARCH_TEGRA_2x_SOC
170 /* Are we on Tegra20? */
171 mov32 r6, TEGRA_APB_MISC_BASE
172 ldr r0, [r6, #APB_MISC_GP_HIDREV]
173 and r0, r0, #0xff00
174 cmp r0, #(0x20 << 8)
175 bne 1f
176 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
177 mov32 r6, TEGRA_PMC_BASE
178 mov r0, #0
179 cmp r10, #0
180 strne r0, [r6, #PMC_SCRATCH41]
1811:
182#endif
183
184 /* Waking up from LP2? */
185 ldr r9, [r12, #RESET_DATA(MASK_LP2)]
186 tst r9, r11 @ if in_lp2
187 beq __is_not_lp2
188 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)]
189 cmp lr, #0
190 bleq __die @ no LP2 startup handler
191 bx lr
192
193__is_not_lp2:
194
195#ifdef CONFIG_SMP
196 /*
197 * Can only be secondary boot (initial or hotplug) but CPU 0
198 * cannot be here.
199 */
200 cmp r10, #0
201 bleq __die @ CPU0 cannot be here
202 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
203 cmp lr, #0
204 bleq __die @ no secondary startup handler
205 bx lr
206#endif
207
208/*
209 * We don't know why the CPU reset. Just kill it.
210 * The LR register will contain the address we died at + 4.
211 */
212
213__die:
214 sub lr, lr, #4
215 mov32 r7, TEGRA_PMC_BASE
216 str lr, [r7, #PMC_SCRATCH41]
217
218 mov32 r7, TEGRA_CLK_RESET_BASE
219
220 /* Are we on Tegra20? */
221 mov32 r6, TEGRA_APB_MISC_BASE
222 ldr r0, [r6, #APB_MISC_GP_HIDREV]
223 and r0, r0, #0xff00
224 cmp r0, #(0x20 << 8)
225 bne 1f
226
227#ifdef CONFIG_ARCH_TEGRA_2x_SOC
228 mov32 r0, 0x1111
229 mov r1, r0, lsl r10
230 str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET
231#endif
2321:
233#ifdef CONFIG_ARCH_TEGRA_3x_SOC
234 mov32 r6, TEGRA_FLOW_CTRL_BASE
235
236 cmp r10, #0
237 moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS
238 moveq r2, #FLOW_CTRL_CPU0_CSR
239 movne r1, r10, lsl #3
240 addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
241 addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
242
243 /* Clear CPU "event" and "interrupt" flags and power gate
244 it when halting but not before it is in the "WFI" state. */
245 ldr r0, [r6, +r2]
246 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
247 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
248 str r0, [r6, +r2]
249
250 /* Unconditionally halt this CPU */
251 mov r0, #FLOW_CTRL_WAITEVENT
252 str r0, [r6, +r1]
253 ldr r0, [r6, +r1] @ memory barrier
254
255 dsb
256 isb
257 wfi @ CPU should be power gated here
258
259 /* If the CPU didn't power gate above just kill it's clock. */
260
261 mov r0, r11, lsl #8
262 str r0, [r7, #348] @ CLK_CPU_CMPLX_SET
263#endif
264
265 /* If the CPU still isn't dead, just spin here. */
266 b .
267ENDPROC(__tegra_cpu_reset_handler)
268
269 .align L1_CACHE_SHIFT
270 .type __tegra_cpu_reset_handler_data, %object
271 .globl __tegra_cpu_reset_handler_data
272__tegra_cpu_reset_handler_data:
273 .rept TEGRA_RESET_DATA_SIZE
274 .long 0
275 .endr
276 .align L1_CACHE_SHIFT
277
278ENTRY(__tegra_cpu_reset_handler_end)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index dca5141a2c31..6a27de4001ee 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -19,6 +19,17 @@
19 19
20static void (*tegra_hotplug_shutdown)(void); 20static void (*tegra_hotplug_shutdown)(void);
21 21
22int tegra_cpu_kill(unsigned cpu)
23{
24 cpu = cpu_logical_map(cpu);
25
26 /* Clock gate the CPU */
27 tegra_wait_cpu_in_reset(cpu);
28 tegra_disable_cpu_clock(cpu);
29
30 return 1;
31}
32
22/* 33/*
23 * platform-specific code to shutdown a CPU 34 * platform-specific code to shutdown a CPU
24 * 35 *
@@ -26,18 +37,12 @@ static void (*tegra_hotplug_shutdown)(void);
26 */ 37 */
27void __ref tegra_cpu_die(unsigned int cpu) 38void __ref tegra_cpu_die(unsigned int cpu)
28{ 39{
29 cpu = cpu_logical_map(cpu); 40 /* Clean L1 data cache */
30 41 tegra_disable_clean_inv_dcache();
31 /* Flush the L1 data cache. */
32 flush_cache_all();
33 42
34 /* Shut down the current CPU. */ 43 /* Shut down the current CPU. */
35 tegra_hotplug_shutdown(); 44 tegra_hotplug_shutdown();
36 45
37 /* Clock gate the CPU */
38 tegra_wait_cpu_in_reset(cpu);
39 tegra_disable_cpu_clock(cpu);
40
41 /* Should never return here. */ 46 /* Should never return here. */
42 BUG(); 47 BUG();
43} 48}
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 18d7290cf93b..3c4a43c892a5 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -23,6 +23,7 @@
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
26#include <asm/smp_plat.h>
26 27
27#include <mach/powergate.h> 28#include <mach/powergate.h>
28 29
@@ -36,6 +37,7 @@
36 37
37extern void tegra_secondary_startup(void); 38extern void tegra_secondary_startup(void);
38 39
40static cpumask_t tegra_cpu_init_mask;
39static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); 41static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
40 42
41#define EVP_CPU_RESET_VECTOR \ 43#define EVP_CPU_RESET_VECTOR \
@@ -50,6 +52,7 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu)
50 */ 52 */
51 gic_secondary_init(0); 53 gic_secondary_init(0);
52 54
55 cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
53} 56}
54 57
55static int tegra20_power_up_cpu(unsigned int cpu) 58static int tegra20_power_up_cpu(unsigned int cpu)
@@ -72,14 +75,42 @@ static int tegra30_power_up_cpu(unsigned int cpu)
72 if (pwrgateid < 0) 75 if (pwrgateid < 0)
73 return pwrgateid; 76 return pwrgateid;
74 77
75 /* If this is the first boot, toggle powergates directly. */ 78 /*
79 * The power up sequence of cold boot CPU and warm boot CPU
80 * was different.
81 *
82 * For warm boot CPU that was resumed from CPU hotplug, the
83 * power will be resumed automatically after un-halting the
84 * flow controller of the warm boot CPU. We need to wait for
85 * the confirmaiton that the CPU is powered then removing
86 * the IO clamps.
87 * For cold boot CPU, do not wait. After the cold boot CPU be
88 * booted, it will run to tegra_secondary_init() and set
89 * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
90 * next time around.
91 */
92 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
93 timeout = jiffies + msecs_to_jiffies(50);
94 do {
95 if (!tegra_powergate_is_powered(pwrgateid))
96 goto remove_clamps;
97 udelay(10);
98 } while (time_before(jiffies, timeout));
99 }
100
101 /*
102 * The power status of the cold boot CPU is power gated as
103 * default. To power up the cold boot CPU, the power should
104 * be un-gated by un-toggling the power gate register
105 * manually.
106 */
76 if (!tegra_powergate_is_powered(pwrgateid)) { 107 if (!tegra_powergate_is_powered(pwrgateid)) {
77 ret = tegra_powergate_power_on(pwrgateid); 108 ret = tegra_powergate_power_on(pwrgateid);
78 if (ret) 109 if (ret)
79 return ret; 110 return ret;
80 111
81 /* Wait for the power to come up. */ 112 /* Wait for the power to come up. */
82 timeout = jiffies + 10*HZ; 113 timeout = jiffies + msecs_to_jiffies(100);
83 while (tegra_powergate_is_powered(pwrgateid)) { 114 while (tegra_powergate_is_powered(pwrgateid)) {
84 if (time_after(jiffies, timeout)) 115 if (time_after(jiffies, timeout))
85 return -ETIMEDOUT; 116 return -ETIMEDOUT;
@@ -87,6 +118,7 @@ static int tegra30_power_up_cpu(unsigned int cpu)
87 } 118 }
88 } 119 }
89 120
121remove_clamps:
90 /* CPU partition is powered. Enable the CPU clock. */ 122 /* CPU partition is powered. Enable the CPU clock. */
91 tegra_enable_cpu_clock(cpu); 123 tegra_enable_cpu_clock(cpu);
92 udelay(10); 124 udelay(10);
@@ -105,6 +137,8 @@ static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *
105{ 137{
106 int status; 138 int status;
107 139
140 cpu = cpu_logical_map(cpu);
141
108 /* 142 /*
109 * Force the CPU into reset. The CPU must remain in reset when the 143 * Force the CPU into reset. The CPU must remain in reset when the
110 * flow controller state is cleared (which will cause the flow 144 * flow controller state is cleared (which will cause the flow
@@ -163,7 +197,9 @@ static void __init tegra_smp_init_cpus(void)
163 197
164static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 198static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
165{ 199{
166 tegra_cpu_reset_handler_init(); 200 /* Always mark the boot CPU (CPU0) as initialized. */
201 cpumask_set_cpu(0, &tegra_cpu_init_mask);
202
167 scu_enable(scu_base); 203 scu_enable(scu_base);
168} 204}
169 205
@@ -173,6 +209,7 @@ struct smp_operations tegra_smp_ops __initdata = {
173 .smp_secondary_init = tegra_secondary_init, 209 .smp_secondary_init = tegra_secondary_init,
174 .smp_boot_secondary = tegra_boot_secondary, 210 .smp_boot_secondary = tegra_boot_secondary,
175#ifdef CONFIG_HOTPLUG_CPU 211#ifdef CONFIG_HOTPLUG_CPU
212 .cpu_kill = tegra_cpu_kill,
176 .cpu_die = tegra_cpu_die, 213 .cpu_die = tegra_cpu_die,
177 .cpu_disable = tegra_cpu_disable, 214 .cpu_disable = tegra_cpu_disable,
178#endif 215#endif
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 1b11707eaca0..498d70b33775 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -148,7 +148,7 @@ static void suspend_cpu_complex(void)
148 save_cpu_arch_register(); 148 save_cpu_arch_register();
149} 149}
150 150
151void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id) 151void tegra_clear_cpu_in_lp2(int phy_cpu_id)
152{ 152{
153 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; 153 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
154 154
@@ -160,7 +160,7 @@ void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id)
160 spin_unlock(&tegra_lp2_lock); 160 spin_unlock(&tegra_lp2_lock);
161} 161}
162 162
163bool __cpuinit tegra_set_cpu_in_lp2(int phy_cpu_id) 163bool tegra_set_cpu_in_lp2(int phy_cpu_id)
164{ 164{
165 bool last_cpu = false; 165 bool last_cpu = false;
166 cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; 166 cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
new file mode 100644
index 000000000000..54382ceade4a
--- /dev/null
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <linux/init.h>
19
20#include <asm/cache.h>
21#include <asm/asm-offsets.h>
22#include <asm/hardware/cache-l2x0.h>
23
24#include "flowctrl.h"
25#include "iomap.h"
26#include "reset.h"
27#include "sleep.h"
28
29#define APB_MISC_GP_HIDREV 0x804
30#define PMC_SCRATCH41 0x140
31
32#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
33
34#ifdef CONFIG_PM_SLEEP
35/*
36 * tegra_resume
37 *
38 * CPU boot vector when restarting the a CPU following
39 * an LP2 transition. Also branched to by LP0 and LP1 resume after
40 * re-enabling sdram.
41 */
42ENTRY(tegra_resume)
43 bl v7_invalidate_l1
44 /* Enable coresight */
45 mov32 r0, 0xC5ACCE55
46 mcr p14, 0, r0, c7, c12, 6
47
48 cpu_id r0
49 cmp r0, #0 @ CPU0?
50 bne cpu_resume @ no
51
52#ifdef CONFIG_ARCH_TEGRA_3x_SOC
53 /* Are we on Tegra20? */
54 mov32 r6, TEGRA_APB_MISC_BASE
55 ldr r0, [r6, #APB_MISC_GP_HIDREV]
56 and r0, r0, #0xff00
57 cmp r0, #(0x20 << 8)
58 beq 1f @ Yes
59 /* Clear the flow controller flags for this CPU. */
60 mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR
61 ldr r1, [r2]
62 /* Clear event & intr flag */
63 orr r1, r1, \
64 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
65 movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps
66 bic r1, r1, r0
67 str r1, [r2]
681:
69#endif
70
71#ifdef CONFIG_HAVE_ARM_SCU
72 /* enable SCU */
73 mov32 r0, TEGRA_ARM_PERIF_BASE
74 ldr r1, [r0]
75 orr r1, r1, #1
76 str r1, [r0]
77#endif
78
79 /* L2 cache resume & re-enable */
80 l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
81
82 b cpu_resume
83ENDPROC(tegra_resume)
84#endif
85
86#ifdef CONFIG_CACHE_L2X0
87 .globl l2x0_saved_regs_addr
88l2x0_saved_regs_addr:
89 .long 0
90#endif
91
92 .align L1_CACHE_SHIFT
93ENTRY(__tegra_cpu_reset_handler_start)
94
95/*
96 * __tegra_cpu_reset_handler:
97 *
98 * Common handler for all CPU reset events.
99 *
100 * Register usage within the reset handler:
101 *
102 * R7 = CPU present (to the OS) mask
103 * R8 = CPU in LP1 state mask
104 * R9 = CPU in LP2 state mask
105 * R10 = CPU number
106 * R11 = CPU mask
107 * R12 = pointer to reset handler data
108 *
109 * NOTE: This code is copied to IRAM. All code and data accesses
110 * must be position-independent.
111 */
112
113 .align L1_CACHE_SHIFT
114ENTRY(__tegra_cpu_reset_handler)
115
116 cpsid aif, 0x13 @ SVC mode, interrupts disabled
117 mrc p15, 0, r10, c0, c0, 5 @ MPIDR
118 and r10, r10, #0x3 @ R10 = CPU number
119 mov r11, #1
120 mov r11, r11, lsl r10 @ R11 = CPU mask
121 adr r12, __tegra_cpu_reset_handler_data
122
123#ifdef CONFIG_SMP
124 /* Does the OS know about this CPU? */
125 ldr r7, [r12, #RESET_DATA(MASK_PRESENT)]
126 tst r7, r11 @ if !present
127 bleq __die @ CPU not present (to OS)
128#endif
129
130#ifdef CONFIG_ARCH_TEGRA_2x_SOC
131 /* Are we on Tegra20? */
132 mov32 r6, TEGRA_APB_MISC_BASE
133 ldr r0, [r6, #APB_MISC_GP_HIDREV]
134 and r0, r0, #0xff00
135 cmp r0, #(0x20 << 8)
136 bne 1f
137 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
138 mov32 r6, TEGRA_PMC_BASE
139 mov r0, #0
140 cmp r10, #0
141 strne r0, [r6, #PMC_SCRATCH41]
1421:
143#endif
144
145 /* Waking up from LP2? */
146 ldr r9, [r12, #RESET_DATA(MASK_LP2)]
147 tst r9, r11 @ if in_lp2
148 beq __is_not_lp2
149 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)]
150 cmp lr, #0
151 bleq __die @ no LP2 startup handler
152 bx lr
153
154__is_not_lp2:
155
156#ifdef CONFIG_SMP
157 /*
158 * Can only be secondary boot (initial or hotplug) but CPU 0
159 * cannot be here.
160 */
161 cmp r10, #0
162 bleq __die @ CPU0 cannot be here
163 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
164 cmp lr, #0
165 bleq __die @ no secondary startup handler
166 bx lr
167#endif
168
169/*
170 * We don't know why the CPU reset. Just kill it.
171 * The LR register will contain the address we died at + 4.
172 */
173
174__die:
175 sub lr, lr, #4
176 mov32 r7, TEGRA_PMC_BASE
177 str lr, [r7, #PMC_SCRATCH41]
178
179 mov32 r7, TEGRA_CLK_RESET_BASE
180
181 /* Are we on Tegra20? */
182 mov32 r6, TEGRA_APB_MISC_BASE
183 ldr r0, [r6, #APB_MISC_GP_HIDREV]
184 and r0, r0, #0xff00
185 cmp r0, #(0x20 << 8)
186 bne 1f
187
188#ifdef CONFIG_ARCH_TEGRA_2x_SOC
189 mov32 r0, 0x1111
190 mov r1, r0, lsl r10
191 str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET
192#endif
1931:
194#ifdef CONFIG_ARCH_TEGRA_3x_SOC
195 mov32 r6, TEGRA_FLOW_CTRL_BASE
196
197 cmp r10, #0
198 moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS
199 moveq r2, #FLOW_CTRL_CPU0_CSR
200 movne r1, r10, lsl #3
201 addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
202 addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
203
204 /* Clear CPU "event" and "interrupt" flags and power gate
205 it when halting but not before it is in the "WFI" state. */
206 ldr r0, [r6, +r2]
207 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
208 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
209 str r0, [r6, +r2]
210
211 /* Unconditionally halt this CPU */
212 mov r0, #FLOW_CTRL_WAITEVENT
213 str r0, [r6, +r1]
214 ldr r0, [r6, +r1] @ memory barrier
215
216 dsb
217 isb
218 wfi @ CPU should be power gated here
219
220 /* If the CPU didn't power gate above just kill it's clock. */
221
222 mov r0, r11, lsl #8
223 str r0, [r7, #348] @ CLK_CPU_CMPLX_SET
224#endif
225
226 /* If the CPU still isn't dead, just spin here. */
227 b .
228ENDPROC(__tegra_cpu_reset_handler)
229
230 .align L1_CACHE_SHIFT
231 .type __tegra_cpu_reset_handler_data, %object
232 .globl __tegra_cpu_reset_handler_data
233__tegra_cpu_reset_handler_data:
234 .rept TEGRA_RESET_DATA_SIZE
235 .long 0
236 .endr
237 .align L1_CACHE_SHIFT
238
239ENTRY(__tegra_cpu_reset_handler_end)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 3fd89ecd158e..1ac434e0068f 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -75,7 +75,7 @@ void __init tegra_cpu_reset_handler_init(void)
75 75
76#ifdef CONFIG_SMP 76#ifdef CONFIG_SMP
77 __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = 77 __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
78 *((u32 *)cpu_present_mask); 78 *((u32 *)cpu_possible_mask);
79 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = 79 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
80 virt_to_phys((void *)tegra_secondary_startup); 80 virt_to_phys((void *)tegra_secondary_startup);
81#endif 81#endif
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 72ce709799da..ad2ca07d0578 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -33,9 +33,6 @@
33 * should never return 33 * should never return
34 */ 34 */
35ENTRY(tegra20_hotplug_shutdown) 35ENTRY(tegra20_hotplug_shutdown)
36 /* Turn off SMP coherency */
37 exit_smp r4, r5
38
39 /* Put this CPU down */ 36 /* Put this CPU down */
40 cpu_id r0 37 cpu_id r0
41 bl tegra20_cpu_shutdown 38 bl tegra20_cpu_shutdown
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index 562a8e7e413d..63a15bd9b653 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -32,9 +32,6 @@
32 * Should never return. 32 * Should never return.
33 */ 33 */
34ENTRY(tegra30_hotplug_shutdown) 34ENTRY(tegra30_hotplug_shutdown)
35 /* Turn off SMP coherency */
36 exit_smp r4, r5
37
38 /* Powergate this CPU */ 35 /* Powergate this CPU */
39 mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN 36 mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
40 bl tegra30_cpu_shutdown 37 bl tegra30_cpu_shutdown
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 26afa7cbed11..addae357da3f 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -34,7 +34,7 @@
34#include "flowctrl.h" 34#include "flowctrl.h"
35#include "sleep.h" 35#include "sleep.h"
36 36
37#ifdef CONFIG_PM_SLEEP 37#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
38/* 38/*
39 * tegra_disable_clean_inv_dcache 39 * tegra_disable_clean_inv_dcache
40 * 40 *
@@ -60,7 +60,9 @@ ENTRY(tegra_disable_clean_inv_dcache)
60 60
61 ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} 61 ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc}
62ENDPROC(tegra_disable_clean_inv_dcache) 62ENDPROC(tegra_disable_clean_inv_dcache)
63#endif
63 64
65#ifdef CONFIG_PM_SLEEP
64/* 66/*
65 * tegra_sleep_cpu_finish(unsigned long v2p) 67 * tegra_sleep_cpu_finish(unsigned long v2p)
66 * 68 *
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 9821ee725420..56505c381ea8 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -106,6 +106,7 @@ exit_l2_resume:
106#else 106#else
107void tegra_resume(void); 107void tegra_resume(void);
108int tegra_sleep_cpu_finish(unsigned long); 108int tegra_sleep_cpu_finish(unsigned long);
109void tegra_disable_clean_inv_dcache(void);
109 110
110#ifdef CONFIG_HOTPLUG_CPU 111#ifdef CONFIG_HOTPLUG_CPU
111void tegra20_hotplug_init(void); 112void tegra20_hotplug_init(void);
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c
index 6942c7add3bb..741d264d5ecb 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -1183,7 +1183,7 @@ static struct clk tegra_dsib = {
1183 .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0), 1183 .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0),
1184}; 1184};
1185 1185
1186struct clk *tegra_list_clks[] = { 1186static struct clk *tegra_list_clks[] = {
1187 &tegra_apbdma, 1187 &tegra_apbdma,
1188 &tegra_rtc, 1188 &tegra_rtc,
1189 &tegra_kbc, 1189 &tegra_kbc,
@@ -1289,7 +1289,7 @@ struct clk *tegra_list_clks[] = {
1289 * configuration. List those here to register them twice in the clock lookup 1289 * configuration. List those here to register them twice in the clock lookup
1290 * table under two names. 1290 * table under two names.
1291 */ 1291 */
1292struct clk_duplicate tegra_clk_duplicates[] = { 1292static struct clk_duplicate tegra_clk_duplicates[] = {
1293 CLK_DUPLICATE("uarta", "serial8250.0", NULL), 1293 CLK_DUPLICATE("uarta", "serial8250.0", NULL),
1294 CLK_DUPLICATE("uartb", "serial8250.1", NULL), 1294 CLK_DUPLICATE("uartb", "serial8250.1", NULL),
1295 CLK_DUPLICATE("uartc", "serial8250.2", NULL), 1295 CLK_DUPLICATE("uartc", "serial8250.2", NULL),
@@ -1340,7 +1340,7 @@ struct clk_duplicate tegra_clk_duplicates[] = {
1340 CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"), 1340 CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"),
1341}; 1341};
1342 1342
1343struct clk *tegra_ptr_clks[] = { 1343static struct clk *tegra_ptr_clks[] = {
1344 &tegra_clk_32k, 1344 &tegra_clk_32k,
1345 &tegra_clk_m, 1345 &tegra_clk_m,
1346 &tegra_clk_m_div2, 1346 &tegra_clk_m_div2,
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 440449c1ca21..596c45c2f192 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
17obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o 17obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
18obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o 18obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
19obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o 19obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o
20obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
20obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o 21obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
21 22
22obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o 23obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o
diff --git a/arch/arm/mach-tegra/timer.c b/drivers/clocksource/tegra20_timer.c
index eba0969ded19..0bde03feb095 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/arch/mach-tegra/timer.c
3 *
4 * Copyright (C) 2010 Google, Inc. 2 * Copyright (C) 2010 Google, Inc.
5 * 3 *
6 * Author: 4 * Author:
@@ -33,8 +31,6 @@
33#include <asm/smp_twd.h> 31#include <asm/smp_twd.h>
34#include <asm/sched_clock.h> 32#include <asm/sched_clock.h>
35 33
36#include "board.h"
37
38#define RTC_SECONDS 0x08 34#define RTC_SECONDS 0x08
39#define RTC_SHADOW_SECONDS 0x0c 35#define RTC_SHADOW_SECONDS 0x0c
40#define RTC_MILLISECONDS 0x10 36#define RTC_MILLISECONDS 0x10
@@ -168,7 +164,7 @@ static const struct of_device_id rtc_match[] __initconst = {
168 {} 164 {}
169}; 165};
170 166
171void __init tegra_init_timer(void) 167static void __init tegra20_init_timer(void)
172{ 168{
173 struct device_node *np; 169 struct device_node *np;
174 struct clk *clk; 170 struct clk *clk;
@@ -183,7 +179,7 @@ void __init tegra_init_timer(void)
183 179
184 timer_reg_base = of_iomap(np, 0); 180 timer_reg_base = of_iomap(np, 0);
185 if (!timer_reg_base) { 181 if (!timer_reg_base) {
186 pr_err("Can't map timer registers"); 182 pr_err("Can't map timer registers\n");
187 BUG(); 183 BUG();
188 } 184 }
189 185
@@ -268,6 +264,7 @@ void __init tegra_init_timer(void)
268#endif 264#endif
269 register_persistent_clock(NULL, tegra_read_persistent_clock); 265 register_persistent_clock(NULL, tegra_read_persistent_clock);
270} 266}
267CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
271 268
272#ifdef CONFIG_PM 269#ifdef CONFIG_PM
273static u32 usec_config; 270static u32 usec_config;