diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-04-09 09:27:52 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-04-09 09:27:52 -0400 |
commit | 8024206dbf4e0701f0cdf259a122ea23db3a7a16 (patch) | |
tree | 11d2f30d0c9209036613ec8f78d682ae31c89315 /arch/arm | |
parent | 5be8f6368800d9e3e570373d2aaff8a48be36574 (diff) | |
parent | 6affb4826405dc1f53bae0e5c302a18f734a44ca (diff) |
Merge tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/cleanup
From Stephen Warren <swarren@wwwdotorg.org>:
ARM: tegra: cleanup
This branch includes various cleanup of the core Tegra support.
* Unification of the separate board-dt-tegra*.c files into a single
tegra.c, now that everything is DT-driven and basically identical.
* Use of_clk_get() in the Tegra clocksource driver so that clocks are
described in DT rather than hard-coding clock names.
* Some cleanup of the PMC-related code, with the aim that the PMC
"driver" contains more of the code that touches PMC registers, rather
than spreading PMC register accesses through other files.
* Conversion of the "PMC" driver to acquire resources describe in device
tree rather than hard-coding them.
* Use of common code for the CPU sleep TLB invalidation.
This branch is based on the previous fixes pull request.
* tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
ARM: tegra: use setup_mm_for_reboot rather than explicit pgd switch
ARM: tegra: replace the CPU power on function with PMC call
ARM: tegra: pmc: add power on function for secondary CPUs
ARM: tegra: pmc: convert PMC driver to support DT only
ARM: tegra: fix the PMC compatible string in DT
ARM: tegra: pmc: add specific compatible DT string for Tegra30 and Tegra114
ARM: tegra: refactor tegra{20,30}_boot_secondary
clocksource: tegra: move to of_clk_get
ARM: tegra: Unify Device tree board files
ARM: tegra: Rename board-dt-tegra20.c to tegra.c
ARM: tegra: Unify tegra{20,30,114}_init_early()
Conflicts:
drivers/clocksource/tegra20_timer.c
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boot/dts/tegra114.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/tegra20.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/tegra30.dtsi | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-dt-tegra114.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-dt-tegra30.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-tegra/hotplug.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 110 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pmc.c | 152 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pmc.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra.c (renamed from arch/arm/mach-tegra/board-dt-tegra20.c) | 16 |
15 files changed, 205 insertions, 265 deletions
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 1dfaf2874c57..e4ddeddcd437 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi | |||
@@ -99,7 +99,7 @@ | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | pmc { | 101 | pmc { |
102 | compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc"; | 102 | compatible = "nvidia,tegra114-pmc"; |
103 | reg = <0x7000e400 0x400>; | 103 | reg = <0x7000e400 0x400>; |
104 | }; | 104 | }; |
105 | 105 | ||
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 48d00a099ce3..de3f5d7530bc 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -145,6 +145,7 @@ | |||
145 | 0 1 0x04 | 145 | 0 1 0x04 |
146 | 0 41 0x04 | 146 | 0 41 0x04 |
147 | 0 42 0x04>; | 147 | 0 42 0x04>; |
148 | clocks = <&tegra_car 5>; | ||
148 | }; | 149 | }; |
149 | 150 | ||
150 | tegra_car: clock { | 151 | tegra_car: clock { |
@@ -304,6 +305,7 @@ | |||
304 | compatible = "nvidia,tegra20-rtc"; | 305 | compatible = "nvidia,tegra20-rtc"; |
305 | reg = <0x7000e000 0x100>; | 306 | reg = <0x7000e000 0x100>; |
306 | interrupts = <0 2 0x04>; | 307 | interrupts = <0 2 0x04>; |
308 | clocks = <&tegra_car 4>; | ||
307 | }; | 309 | }; |
308 | 310 | ||
309 | i2c@7000c000 { | 311 | i2c@7000c000 { |
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 9d87a3ffe998..eddd0f9f7b5e 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi | |||
@@ -148,6 +148,7 @@ | |||
148 | 0 42 0x04 | 148 | 0 42 0x04 |
149 | 0 121 0x04 | 149 | 0 121 0x04 |
150 | 0 122 0x04>; | 150 | 0 122 0x04>; |
151 | clocks = <&tegra_car 5>; | ||
151 | }; | 152 | }; |
152 | 153 | ||
153 | tegra_car: clock { | 154 | tegra_car: clock { |
@@ -291,6 +292,7 @@ | |||
291 | compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; | 292 | compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; |
292 | reg = <0x7000e000 0x100>; | 293 | reg = <0x7000e000 0x100>; |
293 | interrupts = <0 2 0x04>; | 294 | interrupts = <0 2 0x04>; |
295 | clocks = <&tegra_car 4>; | ||
294 | }; | 296 | }; |
295 | 297 | ||
296 | i2c@7000c000 { | 298 | i2c@7000c000 { |
@@ -423,7 +425,7 @@ | |||
423 | }; | 425 | }; |
424 | 426 | ||
425 | pmc { | 427 | pmc { |
426 | compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; | 428 | compatible = "nvidia,tegra30-pmc"; |
427 | reg = <0x7000e400 0x400>; | 429 | reg = <0x7000e400 0x400>; |
428 | }; | 430 | }; |
429 | 431 | ||
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index f6b46ae2b7f8..92703f955a37 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -10,6 +10,7 @@ obj-y += pm.o | |||
10 | obj-y += reset.o | 10 | obj-y += reset.o |
11 | obj-y += reset-handler.o | 11 | obj-y += reset-handler.o |
12 | obj-y += sleep.o | 12 | obj-y += sleep.o |
13 | obj-y += tegra.o | ||
13 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 14 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o | 15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o |
15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o | 16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o |
@@ -27,9 +28,6 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | |||
27 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o | 28 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o |
28 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | 29 | obj-$(CONFIG_TEGRA_PCI) += pcie.o |
29 | 30 | ||
30 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o | ||
31 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o | ||
32 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o | ||
33 | ifeq ($(CONFIG_CPU_IDLE),y) | 31 | ifeq ($(CONFIG_CPU_IDLE),y) |
34 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o | 32 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o |
35 | endif | 33 | endif |
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c deleted file mode 100644 index 085d63637b62..000000000000 --- a/arch/arm/mach-tegra/board-dt-tegra114.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * NVIDIA Tegra114 device tree board support | ||
3 | * | ||
4 | * Copyright (C) 2013 NVIDIA Corporation | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/clocksource.h> | ||
20 | |||
21 | #include <asm/mach/arch.h> | ||
22 | |||
23 | #include "board.h" | ||
24 | #include "common.h" | ||
25 | |||
26 | static void __init tegra114_dt_init(void) | ||
27 | { | ||
28 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
29 | } | ||
30 | |||
31 | static const char * const tegra114_dt_board_compat[] = { | ||
32 | "nvidia,tegra114", | ||
33 | NULL, | ||
34 | }; | ||
35 | |||
36 | DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)") | ||
37 | .smp = smp_ops(tegra_smp_ops), | ||
38 | .map_io = tegra_map_common_io, | ||
39 | .init_early = tegra114_init_early, | ||
40 | .init_irq = tegra_dt_init_irq, | ||
41 | .init_time = clocksource_of_init, | ||
42 | .init_machine = tegra114_dt_init, | ||
43 | .init_late = tegra_init_late, | ||
44 | .restart = tegra_assert_system_reset, | ||
45 | .dt_compat = tegra114_dt_board_compat, | ||
46 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c deleted file mode 100644 index bf68567e549d..000000000000 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-dt-tegra30.c | ||
3 | * | ||
4 | * NVIDIA Tegra30 device tree board support | ||
5 | * | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * Derived from: | ||
9 | * | ||
10 | * arch/arm/mach-tegra/board-dt-tegra20.c | ||
11 | * | ||
12 | * Copyright (C) 2010 Secret Lab Technologies, Ltd. | ||
13 | * Copyright (C) 2010 Google, Inc. | ||
14 | * | ||
15 | * This software is licensed under the terms of the GNU General Public | ||
16 | * License version 2, as published by the Free Software Foundation, and | ||
17 | * may be copied, distributed, and modified under those terms. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/clocksource.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/of_fdt.h> | ||
31 | #include <linux/of_irq.h> | ||
32 | #include <linux/of_platform.h> | ||
33 | |||
34 | #include <asm/mach/arch.h> | ||
35 | |||
36 | #include "board.h" | ||
37 | #include "common.h" | ||
38 | #include "iomap.h" | ||
39 | |||
40 | static void __init tegra30_dt_init(void) | ||
41 | { | ||
42 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
43 | } | ||
44 | |||
45 | static const char *tegra30_dt_board_compat[] = { | ||
46 | "nvidia,tegra30", | ||
47 | NULL | ||
48 | }; | ||
49 | |||
50 | DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") | ||
51 | .smp = smp_ops(tegra_smp_ops), | ||
52 | .map_io = tegra_map_common_io, | ||
53 | .init_early = tegra30_init_early, | ||
54 | .init_irq = tegra_dt_init_irq, | ||
55 | .init_time = clocksource_of_init, | ||
56 | .init_machine = tegra30_dt_init, | ||
57 | .init_late = tegra_init_late, | ||
58 | .restart = tegra_assert_system_reset, | ||
59 | .dt_compat = tegra30_dt_board_compat, | ||
60 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 86851c81a350..60431de585ca 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h | |||
@@ -26,9 +26,7 @@ | |||
26 | 26 | ||
27 | void tegra_assert_system_reset(char mode, const char *cmd); | 27 | void tegra_assert_system_reset(char mode, const char *cmd); |
28 | 28 | ||
29 | void __init tegra20_init_early(void); | 29 | void __init tegra_init_early(void); |
30 | void __init tegra30_init_early(void); | ||
31 | void __init tegra114_init_early(void); | ||
32 | void __init tegra_map_common_io(void); | 30 | void __init tegra_map_common_io(void); |
33 | void __init tegra_init_irq(void); | 31 | void __init tegra_init_irq(void); |
34 | void __init tegra_dt_init_irq(void); | 32 | void __init tegra_dt_init_irq(void); |
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 5449a3f2977b..f0315c95c76d 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -94,7 +94,7 @@ static void __init tegra_init_cache(void) | |||
94 | 94 | ||
95 | } | 95 | } |
96 | 96 | ||
97 | static void __init tegra_init_early(void) | 97 | void __init tegra_init_early(void) |
98 | { | 98 | { |
99 | tegra_cpu_reset_handler_init(); | 99 | tegra_cpu_reset_handler_init(); |
100 | tegra_apb_io_init(); | 100 | tegra_apb_io_init(); |
@@ -102,31 +102,9 @@ static void __init tegra_init_early(void) | |||
102 | tegra_init_cache(); | 102 | tegra_init_cache(); |
103 | tegra_pmc_init(); | 103 | tegra_pmc_init(); |
104 | tegra_powergate_init(); | 104 | tegra_powergate_init(); |
105 | tegra_hotplug_init(); | ||
105 | } | 106 | } |
106 | 107 | ||
107 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
108 | void __init tegra20_init_early(void) | ||
109 | { | ||
110 | tegra_init_early(); | ||
111 | tegra20_hotplug_init(); | ||
112 | } | ||
113 | #endif | ||
114 | |||
115 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
116 | void __init tegra30_init_early(void) | ||
117 | { | ||
118 | tegra_init_early(); | ||
119 | tegra30_hotplug_init(); | ||
120 | } | ||
121 | #endif | ||
122 | |||
123 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | ||
124 | void __init tegra114_init_early(void) | ||
125 | { | ||
126 | tegra_init_early(); | ||
127 | } | ||
128 | #endif | ||
129 | |||
130 | void __init tegra_init_late(void) | 108 | void __init tegra_init_late(void) |
131 | { | 109 | { |
132 | tegra_powergate_debugfs_init(); | 110 | tegra_powergate_debugfs_init(); |
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index a599f6e36dea..8da9f78475da 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -1,8 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * Copyright (C) 2002 ARM Ltd. | 2 | * Copyright (C) 2002 ARM Ltd. |
4 | * All Rights Reserved | 3 | * All Rights Reserved |
5 | * Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved. | 4 | * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved. |
6 | * | 5 | * |
7 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -15,6 +14,7 @@ | |||
15 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
16 | #include <asm/smp_plat.h> | 15 | #include <asm/smp_plat.h> |
17 | 16 | ||
17 | #include "fuse.h" | ||
18 | #include "sleep.h" | 18 | #include "sleep.h" |
19 | 19 | ||
20 | static void (*tegra_hotplug_shutdown)(void); | 20 | static void (*tegra_hotplug_shutdown)(void); |
@@ -56,18 +56,13 @@ int tegra_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 | 59 | void __init tegra_hotplug_init(void) |
60 | extern void tegra20_hotplug_shutdown(void); | ||
61 | void __init tegra20_hotplug_init(void) | ||
62 | { | 60 | { |
63 | tegra_hotplug_shutdown = tegra20_hotplug_shutdown; | 61 | if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) |
64 | } | 62 | return; |
65 | #endif | ||
66 | 63 | ||
67 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | 64 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) |
68 | extern void tegra30_hotplug_shutdown(void); | 65 | tegra_hotplug_shutdown = tegra20_hotplug_shutdown; |
69 | void __init tegra30_hotplug_init(void) | 66 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) |
70 | { | 67 | tegra_hotplug_shutdown = tegra30_hotplug_shutdown; |
71 | tegra_hotplug_shutdown = tegra30_hotplug_shutdown; | ||
72 | } | 68 | } |
73 | #endif | ||
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index fb86a00ce254..c31db797e199 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -25,46 +25,58 @@ | |||
25 | #include <asm/smp_scu.h> | 25 | #include <asm/smp_scu.h> |
26 | #include <asm/smp_plat.h> | 26 | #include <asm/smp_plat.h> |
27 | 27 | ||
28 | #include <mach/powergate.h> | ||
29 | |||
30 | #include "fuse.h" | 28 | #include "fuse.h" |
31 | #include "flowctrl.h" | 29 | #include "flowctrl.h" |
32 | #include "reset.h" | 30 | #include "reset.h" |
31 | #include "pmc.h" | ||
33 | 32 | ||
34 | #include "common.h" | 33 | #include "common.h" |
35 | #include "iomap.h" | 34 | #include "iomap.h" |
36 | 35 | ||
37 | extern void tegra_secondary_startup(void); | ||
38 | |||
39 | static cpumask_t tegra_cpu_init_mask; | 36 | static cpumask_t tegra_cpu_init_mask; |
40 | 37 | ||
41 | #define EVP_CPU_RESET_VECTOR \ | ||
42 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) | ||
43 | |||
44 | static void __cpuinit tegra_secondary_init(unsigned int cpu) | 38 | static void __cpuinit tegra_secondary_init(unsigned int cpu) |
45 | { | 39 | { |
46 | cpumask_set_cpu(cpu, &tegra_cpu_init_mask); | 40 | cpumask_set_cpu(cpu, &tegra_cpu_init_mask); |
47 | } | 41 | } |
48 | 42 | ||
49 | static int tegra20_power_up_cpu(unsigned int cpu) | 43 | |
44 | static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
50 | { | 45 | { |
51 | /* Enable the CPU clock. */ | 46 | cpu = cpu_logical_map(cpu); |
52 | tegra_enable_cpu_clock(cpu); | ||
53 | 47 | ||
54 | /* Clear flow controller CSR. */ | 48 | /* |
55 | flowctrl_write_cpu_csr(cpu, 0); | 49 | * Force the CPU into reset. The CPU must remain in reset when |
50 | * the flow controller state is cleared (which will cause the | ||
51 | * flow controller to stop driving reset if the CPU has been | ||
52 | * power-gated via the flow controller). This will have no | ||
53 | * effect on first boot of the CPU since it should already be | ||
54 | * in reset. | ||
55 | */ | ||
56 | tegra_put_cpu_in_reset(cpu); | ||
56 | 57 | ||
58 | /* | ||
59 | * Unhalt the CPU. If the flow controller was used to | ||
60 | * power-gate the CPU this will cause the flow controller to | ||
61 | * stop driving reset. The CPU will remain in reset because the | ||
62 | * clock and reset block is now driving reset. | ||
63 | */ | ||
64 | flowctrl_write_cpu_halt(cpu, 0); | ||
65 | |||
66 | tegra_enable_cpu_clock(cpu); | ||
67 | flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ | ||
68 | tegra_cpu_out_of_reset(cpu); | ||
57 | return 0; | 69 | return 0; |
58 | } | 70 | } |
59 | 71 | ||
60 | static int tegra30_power_up_cpu(unsigned int cpu) | 72 | static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle) |
61 | { | 73 | { |
62 | int ret, pwrgateid; | 74 | int ret; |
63 | unsigned long timeout; | 75 | unsigned long timeout; |
64 | 76 | ||
65 | pwrgateid = tegra_cpu_powergate_id(cpu); | 77 | cpu = cpu_logical_map(cpu); |
66 | if (pwrgateid < 0) | 78 | tegra_put_cpu_in_reset(cpu); |
67 | return pwrgateid; | 79 | flowctrl_write_cpu_halt(cpu, 0); |
68 | 80 | ||
69 | /* | 81 | /* |
70 | * The power up sequence of cold boot CPU and warm boot CPU | 82 | * The power up sequence of cold boot CPU and warm boot CPU |
@@ -77,13 +89,13 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
77 | * the IO clamps. | 89 | * the IO clamps. |
78 | * For cold boot CPU, do not wait. After the cold boot CPU be | 90 | * For cold boot CPU, do not wait. After the cold boot CPU be |
79 | * booted, it will run to tegra_secondary_init() and set | 91 | * booted, it will run to tegra_secondary_init() and set |
80 | * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() | 92 | * tegra_cpu_init_mask which influences what tegra30_boot_secondary() |
81 | * next time around. | 93 | * next time around. |
82 | */ | 94 | */ |
83 | if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { | 95 | if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { |
84 | timeout = jiffies + msecs_to_jiffies(50); | 96 | timeout = jiffies + msecs_to_jiffies(50); |
85 | do { | 97 | do { |
86 | if (tegra_powergate_is_powered(pwrgateid)) | 98 | if (tegra_pmc_cpu_is_powered(cpu)) |
87 | goto remove_clamps; | 99 | goto remove_clamps; |
88 | udelay(10); | 100 | udelay(10); |
89 | } while (time_before(jiffies, timeout)); | 101 | } while (time_before(jiffies, timeout)); |
@@ -95,14 +107,14 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
95 | * be un-gated by un-toggling the power gate register | 107 | * be un-gated by un-toggling the power gate register |
96 | * manually. | 108 | * manually. |
97 | */ | 109 | */ |
98 | if (!tegra_powergate_is_powered(pwrgateid)) { | 110 | if (!tegra_pmc_cpu_is_powered(cpu)) { |
99 | ret = tegra_powergate_power_on(pwrgateid); | 111 | ret = tegra_pmc_cpu_power_on(cpu); |
100 | if (ret) | 112 | if (ret) |
101 | return ret; | 113 | return ret; |
102 | 114 | ||
103 | /* Wait for the power to come up. */ | 115 | /* Wait for the power to come up. */ |
104 | timeout = jiffies + msecs_to_jiffies(100); | 116 | timeout = jiffies + msecs_to_jiffies(100); |
105 | while (tegra_powergate_is_powered(pwrgateid)) { | 117 | while (tegra_pmc_cpu_is_powered(cpu)) { |
106 | if (time_after(jiffies, timeout)) | 118 | if (time_after(jiffies, timeout)) |
107 | return -ETIMEDOUT; | 119 | return -ETIMEDOUT; |
108 | udelay(10); | 120 | udelay(10); |
@@ -115,60 +127,26 @@ remove_clamps: | |||
115 | udelay(10); | 127 | udelay(10); |
116 | 128 | ||
117 | /* Remove I/O clamps. */ | 129 | /* Remove I/O clamps. */ |
118 | ret = tegra_powergate_remove_clamping(pwrgateid); | 130 | ret = tegra_pmc_cpu_remove_clamping(cpu); |
119 | if (ret) | 131 | if (ret) |
120 | return ret; | 132 | return ret; |
121 | 133 | ||
122 | udelay(10); | 134 | udelay(10); |
123 | 135 | ||
124 | /* Clear flow controller CSR. */ | 136 | flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ |
125 | flowctrl_write_cpu_csr(cpu, 0); | 137 | tegra_cpu_out_of_reset(cpu); |
126 | |||
127 | return 0; | 138 | return 0; |
128 | } | 139 | } |
129 | 140 | ||
130 | static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) | 141 | static int __cpuinit tegra_boot_secondary(unsigned int cpu, |
142 | struct task_struct *idle) | ||
131 | { | 143 | { |
132 | int status; | 144 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) |
133 | 145 | return tegra20_boot_secondary(cpu, idle); | |
134 | cpu = cpu_logical_map(cpu); | 146 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) |
135 | 147 | return tegra30_boot_secondary(cpu, idle); | |
136 | /* | ||
137 | * Force the CPU into reset. The CPU must remain in reset when the | ||
138 | * flow controller state is cleared (which will cause the flow | ||
139 | * controller to stop driving reset if the CPU has been power-gated | ||
140 | * via the flow controller). This will have no effect on first boot | ||
141 | * of the CPU since it should already be in reset. | ||
142 | */ | ||
143 | tegra_put_cpu_in_reset(cpu); | ||
144 | 148 | ||
145 | /* | 149 | return -EINVAL; |
146 | * Unhalt the CPU. If the flow controller was used to power-gate the | ||
147 | * CPU this will cause the flow controller to stop driving reset. | ||
148 | * The CPU will remain in reset because the clock and reset block | ||
149 | * is now driving reset. | ||
150 | */ | ||
151 | flowctrl_write_cpu_halt(cpu, 0); | ||
152 | |||
153 | switch (tegra_chip_id) { | ||
154 | case TEGRA20: | ||
155 | status = tegra20_power_up_cpu(cpu); | ||
156 | break; | ||
157 | case TEGRA30: | ||
158 | status = tegra30_power_up_cpu(cpu); | ||
159 | break; | ||
160 | default: | ||
161 | status = -EINVAL; | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | if (status) | ||
166 | goto done; | ||
167 | |||
168 | /* Take the CPU out of reset. */ | ||
169 | tegra_cpu_out_of_reset(cpu); | ||
170 | done: | ||
171 | return status; | ||
172 | } | 150 | } |
173 | 151 | ||
174 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) | 152 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 0494f739c95f..acacbe8d1afc 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c | |||
@@ -164,12 +164,7 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id) | |||
164 | 164 | ||
165 | static int tegra_sleep_cpu(unsigned long v2p) | 165 | static int tegra_sleep_cpu(unsigned long v2p) |
166 | { | 166 | { |
167 | /* Switch to the identity mapping. */ | 167 | setup_mm_for_reboot(); |
168 | cpu_switch_mm(idmap_pgd, &init_mm); | ||
169 | |||
170 | /* Flush the TLB. */ | ||
171 | local_flush_tlb_all(); | ||
172 | |||
173 | tegra_sleep_cpu_finish(v2p); | 168 | tegra_sleep_cpu_finish(v2p); |
174 | 169 | ||
175 | /* should never here */ | 170 | /* should never here */ |
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c index d4fdb5fcec20..b30e921cc3a9 100644 --- a/arch/arm/mach-tegra/pmc.c +++ b/arch/arm/mach-tegra/pmc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 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, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -18,57 +18,149 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | ||
21 | 22 | ||
22 | #include "iomap.h" | 23 | #define PMC_CTRL 0x0 |
24 | #define PMC_CTRL_INTR_LOW (1 << 17) | ||
25 | #define PMC_PWRGATE_TOGGLE 0x30 | ||
26 | #define PMC_PWRGATE_TOGGLE_START (1 << 8) | ||
27 | #define PMC_REMOVE_CLAMPING 0x34 | ||
28 | #define PMC_PWRGATE_STATUS 0x38 | ||
23 | 29 | ||
24 | #define PMC_CTRL 0x0 | 30 | #define TEGRA_POWERGATE_PCIE 3 |
25 | #define PMC_CTRL_INTR_LOW (1 << 17) | 31 | #define TEGRA_POWERGATE_VDEC 4 |
32 | #define TEGRA_POWERGATE_CPU1 9 | ||
33 | #define TEGRA_POWERGATE_CPU2 10 | ||
34 | #define TEGRA_POWERGATE_CPU3 11 | ||
35 | |||
36 | static u8 tegra_cpu_domains[] = { | ||
37 | 0xFF, /* not available for CPU0 */ | ||
38 | TEGRA_POWERGATE_CPU1, | ||
39 | TEGRA_POWERGATE_CPU2, | ||
40 | TEGRA_POWERGATE_CPU3, | ||
41 | }; | ||
42 | static DEFINE_SPINLOCK(tegra_powergate_lock); | ||
43 | |||
44 | static void __iomem *tegra_pmc_base; | ||
45 | static bool tegra_pmc_invert_interrupt; | ||
26 | 46 | ||
27 | static inline u32 tegra_pmc_readl(u32 reg) | 47 | static inline u32 tegra_pmc_readl(u32 reg) |
28 | { | 48 | { |
29 | return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg)); | 49 | return readl(tegra_pmc_base + reg); |
30 | } | 50 | } |
31 | 51 | ||
32 | static inline void tegra_pmc_writel(u32 val, u32 reg) | 52 | static inline void tegra_pmc_writel(u32 val, u32 reg) |
33 | { | 53 | { |
34 | writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg)); | 54 | writel(val, tegra_pmc_base + reg); |
55 | } | ||
56 | |||
57 | static int tegra_pmc_get_cpu_powerdomain_id(int cpuid) | ||
58 | { | ||
59 | if (cpuid <= 0 || cpuid >= num_possible_cpus()) | ||
60 | return -EINVAL; | ||
61 | return tegra_cpu_domains[cpuid]; | ||
62 | } | ||
63 | |||
64 | static bool tegra_pmc_powergate_is_powered(int id) | ||
65 | { | ||
66 | return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1; | ||
67 | } | ||
68 | |||
69 | static int tegra_pmc_powergate_set(int id, bool new_state) | ||
70 | { | ||
71 | bool old_state; | ||
72 | unsigned long flags; | ||
73 | |||
74 | spin_lock_irqsave(&tegra_powergate_lock, flags); | ||
75 | |||
76 | old_state = tegra_pmc_powergate_is_powered(id); | ||
77 | WARN_ON(old_state == new_state); | ||
78 | |||
79 | tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE); | ||
80 | |||
81 | spin_unlock_irqrestore(&tegra_powergate_lock, flags); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int tegra_pmc_powergate_remove_clamping(int id) | ||
87 | { | ||
88 | u32 mask; | ||
89 | |||
90 | /* | ||
91 | * Tegra has a bug where PCIE and VDE clamping masks are | ||
92 | * swapped relatively to the partition ids. | ||
93 | */ | ||
94 | if (id == TEGRA_POWERGATE_VDEC) | ||
95 | mask = (1 << TEGRA_POWERGATE_PCIE); | ||
96 | else if (id == TEGRA_POWERGATE_PCIE) | ||
97 | mask = (1 << TEGRA_POWERGATE_VDEC); | ||
98 | else | ||
99 | mask = (1 << id); | ||
100 | |||
101 | tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | bool tegra_pmc_cpu_is_powered(int cpuid) | ||
107 | { | ||
108 | int id; | ||
109 | |||
110 | id = tegra_pmc_get_cpu_powerdomain_id(cpuid); | ||
111 | if (id < 0) | ||
112 | return false; | ||
113 | return tegra_pmc_powergate_is_powered(id); | ||
114 | } | ||
115 | |||
116 | int tegra_pmc_cpu_power_on(int cpuid) | ||
117 | { | ||
118 | int id; | ||
119 | |||
120 | id = tegra_pmc_get_cpu_powerdomain_id(cpuid); | ||
121 | if (id < 0) | ||
122 | return id; | ||
123 | return tegra_pmc_powergate_set(id, true); | ||
124 | } | ||
125 | |||
126 | int tegra_pmc_cpu_remove_clamping(int cpuid) | ||
127 | { | ||
128 | int id; | ||
129 | |||
130 | id = tegra_pmc_get_cpu_powerdomain_id(cpuid); | ||
131 | if (id < 0) | ||
132 | return id; | ||
133 | return tegra_pmc_powergate_remove_clamping(id); | ||
35 | } | 134 | } |
36 | 135 | ||
37 | #ifdef CONFIG_OF | ||
38 | static const struct of_device_id matches[] __initconst = { | 136 | static const struct of_device_id matches[] __initconst = { |
137 | { .compatible = "nvidia,tegra114-pmc" }, | ||
138 | { .compatible = "nvidia,tegra30-pmc" }, | ||
39 | { .compatible = "nvidia,tegra20-pmc" }, | 139 | { .compatible = "nvidia,tegra20-pmc" }, |
40 | { } | 140 | { } |
41 | }; | 141 | }; |
42 | #endif | ||
43 | 142 | ||
44 | void __init tegra_pmc_init(void) | 143 | static void tegra_pmc_parse_dt(void) |
45 | { | 144 | { |
46 | /* | 145 | struct device_node *np; |
47 | * For now, Harmony is the only board that uses the PMC, and it wants | ||
48 | * the signal inverted. Seaboard would too if it used the PMC. | ||
49 | * Hopefully by the time other boards want to use the PMC, everything | ||
50 | * will be device-tree, or they also want it inverted. | ||
51 | */ | ||
52 | bool invert_interrupt = true; | ||
53 | u32 val; | ||
54 | 146 | ||
55 | #ifdef CONFIG_OF | 147 | np = of_find_matching_node(NULL, matches); |
56 | if (of_have_populated_dt()) { | 148 | BUG_ON(!np); |
57 | struct device_node *np; | ||
58 | 149 | ||
59 | invert_interrupt = false; | 150 | tegra_pmc_base = of_iomap(np, 0); |
151 | |||
152 | tegra_pmc_invert_interrupt = of_property_read_bool(np, | ||
153 | "nvidia,invert-interrupt"); | ||
154 | } | ||
155 | |||
156 | void __init tegra_pmc_init(void) | ||
157 | { | ||
158 | u32 val; | ||
60 | 159 | ||
61 | np = of_find_matching_node(NULL, matches); | 160 | tegra_pmc_parse_dt(); |
62 | if (np) { | ||
63 | if (of_find_property(np, "nvidia,invert-interrupt", | ||
64 | NULL)) | ||
65 | invert_interrupt = true; | ||
66 | } | ||
67 | } | ||
68 | #endif | ||
69 | 161 | ||
70 | val = tegra_pmc_readl(PMC_CTRL); | 162 | val = tegra_pmc_readl(PMC_CTRL); |
71 | if (invert_interrupt) | 163 | if (tegra_pmc_invert_interrupt) |
72 | val |= PMC_CTRL_INTR_LOW; | 164 | val |= PMC_CTRL_INTR_LOW; |
73 | else | 165 | else |
74 | val &= ~PMC_CTRL_INTR_LOW; | 166 | val &= ~PMC_CTRL_INTR_LOW; |
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h index 8995ee4a8768..7d44710368be 100644 --- a/arch/arm/mach-tegra/pmc.h +++ b/arch/arm/mach-tegra/pmc.h | |||
@@ -18,6 +18,10 @@ | |||
18 | #ifndef __MACH_TEGRA_PMC_H | 18 | #ifndef __MACH_TEGRA_PMC_H |
19 | #define __MACH_TEGRA_PMC_H | 19 | #define __MACH_TEGRA_PMC_H |
20 | 20 | ||
21 | bool tegra_pmc_cpu_is_powered(int cpuid); | ||
22 | int tegra_pmc_cpu_power_on(int cpuid); | ||
23 | int tegra_pmc_cpu_remove_clamping(int cpuid); | ||
24 | |||
21 | void tegra_pmc_init(void); | 25 | void tegra_pmc_init(void); |
22 | 26 | ||
23 | #endif | 27 | #endif |
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 4ffae541726e..970ebd5138b9 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. | 2 | * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 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, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long); | |||
124 | void tegra_disable_clean_inv_dcache(void); | 124 | void tegra_disable_clean_inv_dcache(void); |
125 | 125 | ||
126 | #ifdef CONFIG_HOTPLUG_CPU | 126 | #ifdef CONFIG_HOTPLUG_CPU |
127 | void tegra20_hotplug_init(void); | 127 | void tegra20_hotplug_shutdown(void); |
128 | void tegra30_hotplug_init(void); | 128 | void tegra30_hotplug_shutdown(void); |
129 | void tegra_hotplug_init(void); | ||
129 | #else | 130 | #else |
130 | static inline void tegra20_hotplug_init(void) {} | 131 | static inline void tegra_hotplug_init(void) {} |
131 | static inline void tegra30_hotplug_init(void) {} | ||
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | void tegra20_cpu_shutdown(int cpu); | 134 | void tegra20_cpu_shutdown(int cpu); |
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/tegra.c index a0edf2510280..27232c901a22 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/tegra.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * nVidia Tegra device tree board support | 2 | * NVIDIA Tegra SoC device tree board support |
3 | * | 3 | * |
4 | * Copyright (C) 2011, 2013, NVIDIA Corporation | ||
4 | * Copyright (C) 2010 Secret Lab Technologies, Ltd. | 5 | * Copyright (C) 2010 Secret Lab Technologies, Ltd. |
5 | * Copyright (C) 2010 Google, Inc. | 6 | * Copyright (C) 2010 Google, Inc. |
6 | * | 7 | * |
@@ -111,7 +112,8 @@ static void __init harmony_init(void) | |||
111 | 112 | ||
112 | static void __init paz00_init(void) | 113 | static void __init paz00_init(void) |
113 | { | 114 | { |
114 | tegra_paz00_wifikill_init(); | 115 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) |
116 | tegra_paz00_wifikill_init(); | ||
115 | } | 117 | } |
116 | 118 | ||
117 | static struct { | 119 | static struct { |
@@ -137,19 +139,21 @@ static void __init tegra_dt_init_late(void) | |||
137 | } | 139 | } |
138 | } | 140 | } |
139 | 141 | ||
140 | static const char *tegra20_dt_board_compat[] = { | 142 | static const char * const tegra_dt_board_compat[] = { |
143 | "nvidia,tegra114", | ||
144 | "nvidia,tegra30", | ||
141 | "nvidia,tegra20", | 145 | "nvidia,tegra20", |
142 | NULL | 146 | NULL |
143 | }; | 147 | }; |
144 | 148 | ||
145 | DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") | 149 | DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") |
146 | .map_io = tegra_map_common_io, | 150 | .map_io = tegra_map_common_io, |
147 | .smp = smp_ops(tegra_smp_ops), | 151 | .smp = smp_ops(tegra_smp_ops), |
148 | .init_early = tegra20_init_early, | 152 | .init_early = tegra_init_early, |
149 | .init_irq = tegra_dt_init_irq, | 153 | .init_irq = tegra_dt_init_irq, |
150 | .init_time = clocksource_of_init, | 154 | .init_time = clocksource_of_init, |
151 | .init_machine = tegra_dt_init, | 155 | .init_machine = tegra_dt_init, |
152 | .init_late = tegra_dt_init_late, | 156 | .init_late = tegra_dt_init_late, |
153 | .restart = tegra_assert_system_reset, | 157 | .restart = tegra_assert_system_reset, |
154 | .dt_compat = tegra20_dt_board_compat, | 158 | .dt_compat = tegra_dt_board_compat, |
155 | MACHINE_END | 159 | MACHINE_END |