diff options
author | Olof Johansson <olof@lixom.net> | 2013-06-14 21:11:31 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-06-14 21:11:31 -0400 |
commit | 7bf15412250747277cc53301d550d4894f749b12 (patch) | |
tree | 6362b5b4d68a5eb641981b0f64d472b970d03ff5 /arch/arm/mach-tegra | |
parent | 677b5c48bd524b40120269d973d0633d0d22ee90 (diff) | |
parent | 8f6a0b6528820f9efec36e5843181cc178fa9de8 (diff) |
Merge tag 'tegra-for-3.11-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/soc
From Stephen Warren:
ARM: tegra: core SoC support enhancements
This branch contains fixes and enhancement for core Tegra Soc support:
* CPU hotplug support for Tegra114.
* Some preliminary work on Tegra114 CPU sleep modes.
* Minor fix for EMC table DT parsing.
* tag 'tegra-for-3.11-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
ARM: tegra: don't pass CPU ID to tegra_{set,clear}_cpu_in_lp2
ARM: tegra: cpuidle: using IS_ENABLED for multi SoCs management in init func
ARM: tegra: hook tegra_tear_down_cpu function in the PM suspend init function
ARM: tegra: cpuidle: move the init function behind the suspend init function
ARM: tegra: remove ifdef in the tegra_resume
ARM: tegra: add cpu_disable for hotplug
ARM: tegra114: add CPU hotplug support
clk: tegra114: implement wait_for_reset and disable_clock for tegra_cpu_car_ops
ARM: tegra114: add power up sequence for warm boot CPU
ARM: tegra: make tegra_resume can work for Tegra114
ARM: tegra: skip SCU and PL310 code when CPU is not Cortex-A9
ARM: tegra: add an assembly marco to check Tegra SoC ID
ARM: tegra: emc: correction of ram-code parsing from dt
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle-tegra20.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle-tegra30.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-tegra/flowctrl.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/fuse.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-tegra/hotplug.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.c | 25 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/reset-handler.S | 51 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra30.S | 30 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep.S | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep.h | 35 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_emc.c | 2 |
18 files changed, 182 insertions, 93 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 | |||
30 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | 30 | obj-$(CONFIG_TEGRA_PCI) += pcie.o |
31 | 31 | ||
32 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o | 32 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o |
33 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o | ||
33 | ifeq ($(CONFIG_CPU_IDLE),y) | 34 | ifeq ($(CONFIG_CPU_IDLE),y) |
34 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o | 35 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o |
35 | endif | 36 | endif |
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 9f852c6fe5b9..ec5836b1e713 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include "board.h" | 30 | #include "board.h" |
31 | #include "common.h" | 31 | #include "common.h" |
32 | #include "cpuidle.h" | ||
32 | #include "fuse.h" | 33 | #include "fuse.h" |
33 | #include "iomap.h" | 34 | #include "iomap.h" |
34 | #include "irq.h" | 35 | #include "irq.h" |
@@ -108,5 +109,6 @@ void __init tegra_init_early(void) | |||
108 | void __init tegra_init_late(void) | 109 | void __init tegra_init_late(void) |
109 | { | 110 | { |
110 | tegra_init_suspend(); | 111 | tegra_init_suspend(); |
112 | tegra_cpuidle_init(); | ||
111 | tegra_powergate_debugfs_init(); | 113 | tegra_powergate_debugfs_init(); |
112 | } | 114 | } |
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h index 5900cc44f780..32f8eb3fe344 100644 --- a/arch/arm/mach-tegra/common.h +++ b/arch/arm/mach-tegra/common.h | |||
@@ -2,3 +2,4 @@ extern struct smp_operations tegra_smp_ops; | |||
2 | 2 | ||
3 | extern int tegra_cpu_kill(unsigned int cpu); | 3 | extern int tegra_cpu_kill(unsigned int cpu); |
4 | extern void tegra_cpu_die(unsigned int cpu); | 4 | extern void tegra_cpu_die(unsigned int cpu); |
5 | extern int tegra_cpu_disable(unsigned int cpu); | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c index 0cdba8de8c77..706aa4215c36 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra20.c +++ b/arch/arm/mach-tegra/cpuidle-tegra20.c | |||
@@ -177,7 +177,6 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, | |||
177 | struct cpuidle_driver *drv, | 177 | struct cpuidle_driver *drv, |
178 | int index) | 178 | int index) |
179 | { | 179 | { |
180 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; | ||
181 | bool entered_lp2 = false; | 180 | bool entered_lp2 = false; |
182 | 181 | ||
183 | if (tegra_pending_sgi()) | 182 | if (tegra_pending_sgi()) |
@@ -193,16 +192,16 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, | |||
193 | 192 | ||
194 | local_fiq_disable(); | 193 | local_fiq_disable(); |
195 | 194 | ||
196 | tegra_set_cpu_in_lp2(cpu); | 195 | tegra_set_cpu_in_lp2(); |
197 | cpu_pm_enter(); | 196 | cpu_pm_enter(); |
198 | 197 | ||
199 | if (cpu == 0) | 198 | if (dev->cpu == 0) |
200 | entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index); | 199 | entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index); |
201 | else | 200 | else |
202 | entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index); | 201 | entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index); |
203 | 202 | ||
204 | cpu_pm_exit(); | 203 | cpu_pm_exit(); |
205 | tegra_clear_cpu_in_lp2(cpu); | 204 | tegra_clear_cpu_in_lp2(); |
206 | 205 | ||
207 | local_fiq_enable(); | 206 | local_fiq_enable(); |
208 | 207 | ||
@@ -214,8 +213,5 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, | |||
214 | 213 | ||
215 | int __init tegra20_cpuidle_init(void) | 214 | int __init tegra20_cpuidle_init(void) |
216 | { | 215 | { |
217 | #ifdef CONFIG_PM_SLEEP | ||
218 | tegra_tear_down_cpu = tegra20_tear_down_cpu; | ||
219 | #endif | ||
220 | return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); | 216 | return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); |
221 | } | 217 | } |
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c index 3cf9aca5f3ea..ed2a2a7bae4d 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c | |||
@@ -114,16 +114,15 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev, | |||
114 | struct cpuidle_driver *drv, | 114 | struct cpuidle_driver *drv, |
115 | int index) | 115 | int index) |
116 | { | 116 | { |
117 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; | ||
118 | bool entered_lp2 = false; | 117 | bool entered_lp2 = false; |
119 | bool last_cpu; | 118 | bool last_cpu; |
120 | 119 | ||
121 | local_fiq_disable(); | 120 | local_fiq_disable(); |
122 | 121 | ||
123 | last_cpu = tegra_set_cpu_in_lp2(cpu); | 122 | last_cpu = tegra_set_cpu_in_lp2(); |
124 | cpu_pm_enter(); | 123 | cpu_pm_enter(); |
125 | 124 | ||
126 | if (cpu == 0) { | 125 | if (dev->cpu == 0) { |
127 | if (last_cpu) | 126 | if (last_cpu) |
128 | entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv, | 127 | entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv, |
129 | index); | 128 | index); |
@@ -134,7 +133,7 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev, | |||
134 | } | 133 | } |
135 | 134 | ||
136 | cpu_pm_exit(); | 135 | cpu_pm_exit(); |
137 | tegra_clear_cpu_in_lp2(cpu); | 136 | tegra_clear_cpu_in_lp2(); |
138 | 137 | ||
139 | local_fiq_enable(); | 138 | local_fiq_enable(); |
140 | 139 | ||
@@ -146,8 +145,5 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev, | |||
146 | 145 | ||
147 | int __init tegra30_cpuidle_init(void) | 146 | int __init tegra30_cpuidle_init(void) |
148 | { | 147 | { |
149 | #ifdef CONFIG_PM_SLEEP | ||
150 | tegra_tear_down_cpu = tegra30_tear_down_cpu; | ||
151 | #endif | ||
152 | return cpuidle_register(&tegra_idle_driver, NULL); | 148 | return cpuidle_register(&tegra_idle_driver, NULL); |
153 | } | 149 | } |
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index 4b744c4661e2..e85973cef037 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c | |||
@@ -27,25 +27,20 @@ | |||
27 | #include "fuse.h" | 27 | #include "fuse.h" |
28 | #include "cpuidle.h" | 28 | #include "cpuidle.h" |
29 | 29 | ||
30 | static int __init tegra_cpuidle_init(void) | 30 | void __init tegra_cpuidle_init(void) |
31 | { | 31 | { |
32 | int ret; | ||
33 | |||
34 | switch (tegra_chip_id) { | 32 | switch (tegra_chip_id) { |
35 | case TEGRA20: | 33 | case TEGRA20: |
36 | ret = tegra20_cpuidle_init(); | 34 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) |
35 | tegra20_cpuidle_init(); | ||
37 | break; | 36 | break; |
38 | case TEGRA30: | 37 | case TEGRA30: |
39 | ret = tegra30_cpuidle_init(); | 38 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC)) |
39 | tegra30_cpuidle_init(); | ||
40 | break; | 40 | break; |
41 | case TEGRA114: | 41 | case TEGRA114: |
42 | ret = tegra114_cpuidle_init(); | 42 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) |
43 | break; | 43 | tegra114_cpuidle_init(); |
44 | default: | ||
45 | ret = -ENODEV; | ||
46 | break; | 44 | break; |
47 | } | 45 | } |
48 | |||
49 | return ret; | ||
50 | } | 46 | } |
51 | device_initcall(tegra_cpuidle_init); | ||
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h index d733f75d0208..9ec2c1ab0fa4 100644 --- a/arch/arm/mach-tegra/cpuidle.h +++ b/arch/arm/mach-tegra/cpuidle.h | |||
@@ -17,22 +17,13 @@ | |||
17 | #ifndef __MACH_TEGRA_CPUIDLE_H | 17 | #ifndef __MACH_TEGRA_CPUIDLE_H |
18 | #define __MACH_TEGRA_CPUIDLE_H | 18 | #define __MACH_TEGRA_CPUIDLE_H |
19 | 19 | ||
20 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 20 | #ifdef CONFIG_CPU_IDLE |
21 | int tegra20_cpuidle_init(void); | 21 | int tegra20_cpuidle_init(void); |
22 | #else | ||
23 | static inline int tegra20_cpuidle_init(void) { return -ENODEV; } | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
27 | int tegra30_cpuidle_init(void); | 22 | int tegra30_cpuidle_init(void); |
28 | #else | ||
29 | static inline int tegra30_cpuidle_init(void) { return -ENODEV; } | ||
30 | #endif | ||
31 | |||
32 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | ||
33 | int tegra114_cpuidle_init(void); | 23 | int tegra114_cpuidle_init(void); |
24 | void tegra_cpuidle_init(void); | ||
34 | #else | 25 | #else |
35 | static inline int tegra114_cpuidle_init(void) { return -ENODEV; } | 26 | static inline void tegra_cpuidle_init(void) {} |
36 | #endif | 27 | #endif |
37 | 28 | ||
38 | #endif | 29 | #endif |
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h index 67eab56699bd..7a29bae799a7 100644 --- a/arch/arm/mach-tegra/flowctrl.h +++ b/arch/arm/mach-tegra/flowctrl.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define FLOW_CTRL_WAITEVENT (2 << 29) | 25 | #define FLOW_CTRL_WAITEVENT (2 << 29) |
26 | #define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29) | 26 | #define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29) |
27 | #define FLOW_CTRL_JTAG_RESUME (1 << 28) | 27 | #define FLOW_CTRL_JTAG_RESUME (1 << 28) |
28 | #define FLOW_CTRL_SCLK_RESUME (1 << 27) | ||
28 | #define FLOW_CTRL_HALT_CPU_IRQ (1 << 10) | 29 | #define FLOW_CTRL_HALT_CPU_IRQ (1 << 10) |
29 | #define FLOW_CTRL_HALT_CPU_FIQ (1 << 8) | 30 | #define FLOW_CTRL_HALT_CPU_FIQ (1 << 8) |
30 | #define FLOW_CTRL_CPU0_CSR 0x8 | 31 | #define FLOW_CTRL_CPU0_CSR 0x8 |
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h index aacc00d05980..def79683bef6 100644 --- a/arch/arm/mach-tegra/fuse.h +++ b/arch/arm/mach-tegra/fuse.h | |||
@@ -19,16 +19,6 @@ | |||
19 | #ifndef __MACH_TEGRA_FUSE_H | 19 | #ifndef __MACH_TEGRA_FUSE_H |
20 | #define __MACH_TEGRA_FUSE_H | 20 | #define __MACH_TEGRA_FUSE_H |
21 | 21 | ||
22 | enum tegra_revision { | ||
23 | TEGRA_REVISION_UNKNOWN = 0, | ||
24 | TEGRA_REVISION_A01, | ||
25 | TEGRA_REVISION_A02, | ||
26 | TEGRA_REVISION_A03, | ||
27 | TEGRA_REVISION_A03p, | ||
28 | TEGRA_REVISION_A04, | ||
29 | TEGRA_REVISION_MAX, | ||
30 | }; | ||
31 | |||
32 | #define SKU_ID_T20 8 | 22 | #define SKU_ID_T20 8 |
33 | #define SKU_ID_T25SE 20 | 23 | #define SKU_ID_T25SE 20 |
34 | #define SKU_ID_AP25 23 | 24 | #define SKU_ID_AP25 23 |
@@ -40,6 +30,17 @@ enum tegra_revision { | |||
40 | #define TEGRA30 0x30 | 30 | #define TEGRA30 0x30 |
41 | #define TEGRA114 0x35 | 31 | #define TEGRA114 0x35 |
42 | 32 | ||
33 | #ifndef __ASSEMBLY__ | ||
34 | enum tegra_revision { | ||
35 | TEGRA_REVISION_UNKNOWN = 0, | ||
36 | TEGRA_REVISION_A01, | ||
37 | TEGRA_REVISION_A02, | ||
38 | TEGRA_REVISION_A03, | ||
39 | TEGRA_REVISION_A03p, | ||
40 | TEGRA_REVISION_A04, | ||
41 | TEGRA_REVISION_MAX, | ||
42 | }; | ||
43 | |||
43 | extern int tegra_sku_id; | 44 | extern int tegra_sku_id; |
44 | extern int tegra_cpu_process_id; | 45 | extern int tegra_cpu_process_id; |
45 | extern int tegra_core_process_id; | 46 | extern int tegra_core_process_id; |
@@ -72,5 +73,6 @@ void tegra114_init_speedo_data(void); | |||
72 | #else | 73 | #else |
73 | static inline void tegra114_init_speedo_data(void) {} | 74 | static inline void tegra114_init_speedo_data(void) {} |
74 | #endif | 75 | #endif |
76 | #endif /* __ASSEMBLY__ */ | ||
75 | 77 | ||
76 | #endif | 78 | #endif |
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index 184914a68d73..a52c10e0a857 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -46,6 +46,17 @@ void __ref tegra_cpu_die(unsigned int cpu) | |||
46 | BUG(); | 46 | BUG(); |
47 | } | 47 | } |
48 | 48 | ||
49 | int tegra_cpu_disable(unsigned int cpu) | ||
50 | { | ||
51 | switch (tegra_chip_id) { | ||
52 | case TEGRA20: | ||
53 | case TEGRA30: | ||
54 | return cpu == 0 ? -EPERM : 0; | ||
55 | default: | ||
56 | return 0; | ||
57 | } | ||
58 | } | ||
59 | |||
49 | void __init tegra_hotplug_init(void) | 60 | void __init tegra_hotplug_init(void) |
50 | { | 61 | { |
51 | if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) | 62 | if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) |
@@ -55,4 +66,6 @@ void __init tegra_hotplug_init(void) | |||
55 | tegra_hotplug_shutdown = tegra20_hotplug_shutdown; | 66 | tegra_hotplug_shutdown = tegra20_hotplug_shutdown; |
56 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) | 67 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) |
57 | tegra_hotplug_shutdown = tegra30_hotplug_shutdown; | 68 | tegra_hotplug_shutdown = tegra30_hotplug_shutdown; |
69 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) | ||
70 | tegra_hotplug_shutdown = tegra30_hotplug_shutdown; | ||
58 | } | 71 | } |
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index fad4226ef710..24db4ac428ae 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -140,8 +140,31 @@ remove_clamps: | |||
140 | 140 | ||
141 | static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) | 141 | static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) |
142 | { | 142 | { |
143 | int ret = 0; | ||
144 | |||
143 | cpu = cpu_logical_map(cpu); | 145 | cpu = cpu_logical_map(cpu); |
144 | return tegra_pmc_cpu_power_on(cpu); | 146 | |
147 | if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { | ||
148 | /* | ||
149 | * Warm boot flow | ||
150 | * The flow controller in charge of the power state and | ||
151 | * control for each CPU. | ||
152 | */ | ||
153 | /* set SCLK as event trigger for flow controller */ | ||
154 | flowctrl_write_cpu_csr(cpu, 1); | ||
155 | flowctrl_write_cpu_halt(cpu, | ||
156 | FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME); | ||
157 | } else { | ||
158 | /* | ||
159 | * Cold boot flow | ||
160 | * The CPU is powered up by toggling PMC directly. It will | ||
161 | * also initial power state in flow controller. After that, | ||
162 | * the CPU's power state is maintained by flow controller. | ||
163 | */ | ||
164 | ret = tegra_pmc_cpu_power_on(cpu); | ||
165 | } | ||
166 | |||
167 | return ret; | ||
145 | } | 168 | } |
146 | 169 | ||
147 | static int __cpuinit tegra_boot_secondary(unsigned int cpu, | 170 | static int __cpuinit tegra_boot_secondary(unsigned int cpu, |
@@ -173,5 +196,6 @@ struct smp_operations tegra_smp_ops __initdata = { | |||
173 | #ifdef CONFIG_HOTPLUG_CPU | 196 | #ifdef CONFIG_HOTPLUG_CPU |
174 | .cpu_kill = tegra_cpu_kill, | 197 | .cpu_kill = tegra_cpu_kill, |
175 | .cpu_die = tegra_cpu_die, | 198 | .cpu_die = tegra_cpu_die, |
199 | .cpu_disable = tegra_cpu_disable, | ||
176 | #endif | 200 | #endif |
177 | }; | 201 | }; |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 45cf52c7e528..94e69bee3da5 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c | |||
@@ -44,6 +44,20 @@ | |||
44 | static DEFINE_SPINLOCK(tegra_lp2_lock); | 44 | static DEFINE_SPINLOCK(tegra_lp2_lock); |
45 | void (*tegra_tear_down_cpu)(void); | 45 | void (*tegra_tear_down_cpu)(void); |
46 | 46 | ||
47 | static void tegra_tear_down_cpu_init(void) | ||
48 | { | ||
49 | switch (tegra_chip_id) { | ||
50 | case TEGRA20: | ||
51 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) | ||
52 | tegra_tear_down_cpu = tegra20_tear_down_cpu; | ||
53 | break; | ||
54 | case TEGRA30: | ||
55 | if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC)) | ||
56 | tegra_tear_down_cpu = tegra30_tear_down_cpu; | ||
57 | break; | ||
58 | } | ||
59 | } | ||
60 | |||
47 | /* | 61 | /* |
48 | * restore_cpu_complex | 62 | * restore_cpu_complex |
49 | * | 63 | * |
@@ -91,8 +105,9 @@ static void suspend_cpu_complex(void) | |||
91 | flowctrl_cpu_suspend_enter(cpu); | 105 | flowctrl_cpu_suspend_enter(cpu); |
92 | } | 106 | } |
93 | 107 | ||
94 | void tegra_clear_cpu_in_lp2(int phy_cpu_id) | 108 | void tegra_clear_cpu_in_lp2(void) |
95 | { | 109 | { |
110 | int phy_cpu_id = cpu_logical_map(smp_processor_id()); | ||
96 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; | 111 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; |
97 | 112 | ||
98 | spin_lock(&tegra_lp2_lock); | 113 | spin_lock(&tegra_lp2_lock); |
@@ -103,8 +118,9 @@ void tegra_clear_cpu_in_lp2(int phy_cpu_id) | |||
103 | spin_unlock(&tegra_lp2_lock); | 118 | spin_unlock(&tegra_lp2_lock); |
104 | } | 119 | } |
105 | 120 | ||
106 | bool tegra_set_cpu_in_lp2(int phy_cpu_id) | 121 | bool tegra_set_cpu_in_lp2(void) |
107 | { | 122 | { |
123 | int phy_cpu_id = cpu_logical_map(smp_processor_id()); | ||
108 | bool last_cpu = false; | 124 | bool last_cpu = false; |
109 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; | 125 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; |
110 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; | 126 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; |
@@ -192,7 +208,7 @@ static int __cpuinit tegra_suspend_enter(suspend_state_t state) | |||
192 | suspend_cpu_complex(); | 208 | suspend_cpu_complex(); |
193 | switch (mode) { | 209 | switch (mode) { |
194 | case TEGRA_SUSPEND_LP2: | 210 | case TEGRA_SUSPEND_LP2: |
195 | tegra_set_cpu_in_lp2(0); | 211 | tegra_set_cpu_in_lp2(); |
196 | break; | 212 | break; |
197 | default: | 213 | default: |
198 | break; | 214 | break; |
@@ -202,7 +218,7 @@ static int __cpuinit tegra_suspend_enter(suspend_state_t state) | |||
202 | 218 | ||
203 | switch (mode) { | 219 | switch (mode) { |
204 | case TEGRA_SUSPEND_LP2: | 220 | case TEGRA_SUSPEND_LP2: |
205 | tegra_clear_cpu_in_lp2(0); | 221 | tegra_clear_cpu_in_lp2(); |
206 | break; | 222 | break; |
207 | default: | 223 | default: |
208 | break; | 224 | break; |
@@ -224,6 +240,7 @@ void __init tegra_init_suspend(void) | |||
224 | if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE) | 240 | if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE) |
225 | return; | 241 | return; |
226 | 242 | ||
243 | tegra_tear_down_cpu_init(); | ||
227 | tegra_pmc_suspend_init(); | 244 | tegra_pmc_suspend_init(); |
228 | 245 | ||
229 | suspend_set_ops(&tegra_suspend_ops); | 246 | suspend_set_ops(&tegra_suspend_ops); |
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index 778a4aa7c3fa..94c4b9d9077c 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h | |||
@@ -28,8 +28,8 @@ extern unsigned long l2x0_saved_regs_addr; | |||
28 | void save_cpu_arch_register(void); | 28 | void save_cpu_arch_register(void); |
29 | void restore_cpu_arch_register(void); | 29 | void restore_cpu_arch_register(void); |
30 | 30 | ||
31 | void tegra_clear_cpu_in_lp2(int phy_cpu_id); | 31 | void tegra_clear_cpu_in_lp2(void); |
32 | bool tegra_set_cpu_in_lp2(int phy_cpu_id); | 32 | bool tegra_set_cpu_in_lp2(void); |
33 | 33 | ||
34 | void tegra_idle_lp2_last(void); | 34 | void tegra_idle_lp2_last(void); |
35 | extern void (*tegra_tear_down_cpu)(void); | 35 | extern void (*tegra_tear_down_cpu)(void); |
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S index e6de88a2ea06..39dc9e7834f3 100644 --- a/arch/arm/mach-tegra/reset-handler.S +++ b/arch/arm/mach-tegra/reset-handler.S | |||
@@ -22,11 +22,11 @@ | |||
22 | #include <asm/hardware/cache-l2x0.h> | 22 | #include <asm/hardware/cache-l2x0.h> |
23 | 23 | ||
24 | #include "flowctrl.h" | 24 | #include "flowctrl.h" |
25 | #include "fuse.h" | ||
25 | #include "iomap.h" | 26 | #include "iomap.h" |
26 | #include "reset.h" | 27 | #include "reset.h" |
27 | #include "sleep.h" | 28 | #include "sleep.h" |
28 | 29 | ||
29 | #define APB_MISC_GP_HIDREV 0x804 | ||
30 | #define PMC_SCRATCH41 0x140 | 30 | #define PMC_SCRATCH41 0x140 |
31 | 31 | ||
32 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) | 32 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) |
@@ -38,34 +38,40 @@ | |||
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 | */ |
42 | ENTRY(tegra_resume) | 44 | ENTRY(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 |
55 | no_cpu0_chk: | ||
49 | 56 | ||
50 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
51 | /* Are we on Tegra20? */ | 57 | /* Are we on Tegra20? */ |
52 | mov32 r6, TEGRA_APB_MISC_BASE | 58 | cmp r6, #TEGRA20 |
53 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
54 | and r0, r0, #0xff00 | ||
55 | cmp r0, #(0x20 << 8) | ||
56 | beq 1f @ Yes | 59 | beq 1f @ Yes |
57 | /* Clear the flow controller flags for this CPU. */ | 60 | /* Clear the flow controller flags for this CPU. */ |
58 | mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR | 61 | cpu_to_csr_reg r1, r0 |
59 | ldr r1, [r2] | 62 | mov32 r2, TEGRA_FLOW_CTRL_BASE |
63 | ldr r1, [r2, r1] | ||
60 | /* Clear event & intr flag */ | 64 | /* Clear event & intr flag */ |
61 | orr r1, r1, \ | 65 | orr r1, r1, \ |
62 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | 66 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG |
63 | movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps | 67 | movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps |
68 | @ & ext flags for CPU power mgnt | ||
64 | bic r1, r1, r0 | 69 | bic r1, r1, r0 |
65 | str r1, [r2] | 70 | str r1, [r2] |
66 | 1: | 71 | 1: |
67 | #endif | ||
68 | 72 | ||
73 | check_cpu_part_num 0xc09, r8, r9 | ||
74 | bne not_ca9 | ||
69 | #ifdef CONFIG_HAVE_ARM_SCU | 75 | #ifdef CONFIG_HAVE_ARM_SCU |
70 | /* enable SCU */ | 76 | /* enable SCU */ |
71 | mov32 r0, TEGRA_ARM_PERIF_BASE | 77 | mov32 r0, TEGRA_ARM_PERIF_BASE |
@@ -76,6 +82,7 @@ ENTRY(tegra_resume) | |||
76 | 82 | ||
77 | /* L2 cache resume & re-enable */ | 83 | /* L2 cache resume & re-enable */ |
78 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr | 84 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr |
85 | not_ca9: | ||
79 | 86 | ||
80 | b cpu_resume | 87 | b cpu_resume |
81 | ENDPROC(tegra_resume) | 88 | ENDPROC(tegra_resume) |
@@ -98,7 +105,7 @@ ENTRY(__tegra_cpu_reset_handler_start) | |||
98 | * Register usage within the reset handler: | 105 | * Register usage within the reset handler: |
99 | * | 106 | * |
100 | * Others: scratch | 107 | * Others: scratch |
101 | * R6 = SoC ID << 8 | 108 | * R6 = SoC ID |
102 | * R7 = CPU present (to the OS) mask | 109 | * R7 = CPU present (to the OS) mask |
103 | * R8 = CPU in LP1 state mask | 110 | * R8 = CPU in LP1 state mask |
104 | * R9 = CPU in LP2 state mask | 111 | * R9 = CPU in LP2 state mask |
@@ -115,12 +122,10 @@ ENTRY(__tegra_cpu_reset_handler) | |||
115 | 122 | ||
116 | cpsid aif, 0x13 @ SVC mode, interrupts disabled | 123 | cpsid aif, 0x13 @ SVC mode, interrupts disabled |
117 | 124 | ||
118 | mov32 r6, TEGRA_APB_MISC_BASE | 125 | tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 |
119 | ldr r6, [r6, #APB_MISC_GP_HIDREV] | ||
120 | and r6, r6, #0xff00 | ||
121 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 126 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
122 | t20_check: | 127 | t20_check: |
123 | cmp r6, #(0x20 << 8) | 128 | cmp r6, #TEGRA20 |
124 | bne after_t20_check | 129 | bne after_t20_check |
125 | t20_errata: | 130 | t20_errata: |
126 | # Tegra20 is a Cortex-A9 r1p1 | 131 | # Tegra20 is a Cortex-A9 r1p1 |
@@ -136,7 +141,7 @@ after_t20_check: | |||
136 | #endif | 141 | #endif |
137 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | 142 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC |
138 | t30_check: | 143 | t30_check: |
139 | cmp r6, #(0x30 << 8) | 144 | cmp r6, #TEGRA30 |
140 | bne after_t30_check | 145 | bne after_t30_check |
141 | t30_errata: | 146 | t30_errata: |
142 | # Tegra30 is a Cortex-A9 r2p9 | 147 | # Tegra30 is a Cortex-A9 r2p9 |
@@ -163,7 +168,7 @@ after_errata: | |||
163 | 168 | ||
164 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 169 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
165 | /* Are we on Tegra20? */ | 170 | /* Are we on Tegra20? */ |
166 | cmp r6, #(0x20 << 8) | 171 | cmp r6, #TEGRA20 |
167 | bne 1f | 172 | bne 1f |
168 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ | 173 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ |
169 | mov32 r5, TEGRA_PMC_BASE | 174 | mov32 r5, TEGRA_PMC_BASE |
@@ -186,11 +191,14 @@ __is_not_lp2: | |||
186 | 191 | ||
187 | #ifdef CONFIG_SMP | 192 | #ifdef CONFIG_SMP |
188 | /* | 193 | /* |
189 | * Can only be secondary boot (initial or hotplug) but CPU 0 | 194 | * Can only be secondary boot (initial or hotplug) |
190 | * cannot be here. | 195 | * CPU0 can't be here for Tegra20/30 |
191 | */ | 196 | */ |
197 | cmp r6, #TEGRA114 | ||
198 | beq __no_cpu0_chk | ||
192 | cmp r10, #0 | 199 | cmp r10, #0 |
193 | bleq __die @ CPU0 cannot be here | 200 | bleq __die @ CPU0 cannot be here |
201 | __no_cpu0_chk: | ||
194 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] | 202 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] |
195 | cmp lr, #0 | 203 | cmp lr, #0 |
196 | bleq __die @ no secondary startup handler | 204 | bleq __die @ no secondary startup handler |
@@ -210,10 +218,7 @@ __die: | |||
210 | mov32 r7, TEGRA_CLK_RESET_BASE | 218 | mov32 r7, TEGRA_CLK_RESET_BASE |
211 | 219 | ||
212 | /* Are we on Tegra20? */ | 220 | /* Are we on Tegra20? */ |
213 | mov32 r6, TEGRA_APB_MISC_BASE | 221 | cmp r6, #TEGRA20 |
214 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
215 | and r0, r0, #0xff00 | ||
216 | cmp r0, #(0x20 << 8) | ||
217 | bne 1f | 222 | bne 1f |
218 | 223 | ||
219 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 224 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
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 | */ |
50 | ENTRY(tegra30_cpu_shutdown) | 51 | ENTRY(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 | ||
97 | flow_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 |
102 | flow_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 | ||
93 | wfe_war: | 113 | wfe_war: |
94 | b __cpu_reset_again | 114 | b __cpu_reset_again |
95 | 115 | ||
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 364d84523fba..9daaef26b0f6 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S | |||
@@ -106,9 +106,11 @@ ENTRY(tegra_shut_off_mmu) | |||
106 | isb | 106 | isb |
107 | #ifdef CONFIG_CACHE_L2X0 | 107 | #ifdef CONFIG_CACHE_L2X0 |
108 | /* Disable L2 cache */ | 108 | /* Disable L2 cache */ |
109 | mov32 r4, TEGRA_ARM_PERIF_BASE + 0x3000 | 109 | check_cpu_part_num 0xc09, r9, r10 |
110 | mov r5, #0 | 110 | movweq r4, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000) |
111 | str r5, [r4, #L2X0_CTRL] | 111 | movteq r4, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000) |
112 | moveq r5, #0 | ||
113 | streq r5, [r4, #L2X0_CTRL] | ||
112 | #endif | 114 | #endif |
113 | mov pc, r0 | 115 | mov pc, r0 |
114 | ENDPROC(tegra_shut_off_mmu) | 116 | ENDPROC(tegra_shut_off_mmu) |
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 2080fb12ce26..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 */ |
@@ -70,19 +72,40 @@ | |||
70 | movt \reg, #:upper16:\val | 72 | movt \reg, #:upper16:\val |
71 | .endm | 73 | .endm |
72 | 74 | ||
75 | /* Marco to check CPU part num */ | ||
76 | .macro check_cpu_part_num part_num, tmp1, tmp2 | ||
77 | mrc p15, 0, \tmp1, c0, c0, 0 | ||
78 | ubfx \tmp1, \tmp1, #4, #12 | ||
79 | mov32 \tmp2, \part_num | ||
80 | cmp \tmp1, \tmp2 | ||
81 | .endm | ||
82 | |||
73 | /* Macro to exit SMP coherency. */ | 83 | /* Macro to exit SMP coherency. */ |
74 | .macro exit_smp, tmp1, tmp2 | 84 | .macro exit_smp, tmp1, tmp2 |
75 | mrc p15, 0, \tmp1, c1, c0, 1 @ ACTLR | 85 | mrc p15, 0, \tmp1, c1, c0, 1 @ ACTLR |
76 | bic \tmp1, \tmp1, #(1<<6) | (1<<0) @ clear ACTLR.SMP | ACTLR.FW | 86 | bic \tmp1, \tmp1, #(1<<6) | (1<<0) @ clear ACTLR.SMP | ACTLR.FW |
77 | mcr p15, 0, \tmp1, c1, c0, 1 @ ACTLR | 87 | mcr p15, 0, \tmp1, c1, c0, 1 @ ACTLR |
78 | isb | 88 | isb |
79 | cpu_id \tmp1 | 89 | #ifdef CONFIG_HAVE_ARM_SCU |
80 | mov \tmp1, \tmp1, lsl #2 | 90 | check_cpu_part_num 0xc09, \tmp1, \tmp2 |
81 | mov \tmp2, #0xf | 91 | mrceq p15, 0, \tmp1, c0, c0, 5 |
82 | mov \tmp2, \tmp2, lsl \tmp1 | 92 | andeq \tmp1, \tmp1, #0xF |
83 | mov32 \tmp1, TEGRA_ARM_PERIF_VIRT + 0xC | 93 | moveq \tmp1, \tmp1, lsl #2 |
84 | str \tmp2, [\tmp1] @ invalidate SCU tags for CPU | 94 | moveq \tmp2, #0xf |
95 | moveq \tmp2, \tmp2, lsl \tmp1 | ||
96 | ldreq \tmp1, =(TEGRA_ARM_PERIF_VIRT + 0xC) | ||
97 | streq \tmp2, [\tmp1] @ invalidate SCU tags for CPU | ||
85 | dsb | 98 | dsb |
99 | #endif | ||
100 | .endm | ||
101 | |||
102 | /* Macro to check Tegra revision */ | ||
103 | #define APB_MISC_GP_HIDREV 0x804 | ||
104 | .macro tegra_get_soc_id base, tmp1 | ||
105 | mov32 \tmp1, \base | ||
106 | ldr \tmp1, [\tmp1, #APB_MISC_GP_HIDREV] | ||
107 | and \tmp1, \tmp1, #0xff00 | ||
108 | mov \tmp1, \tmp1, lsr #8 | ||
86 | .endm | 109 | .endm |
87 | 110 | ||
88 | /* Macro to resume & re-enable L2 cache */ | 111 | /* Macro to resume & re-enable L2 cache */ |
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c index 31e69a019bdd..3ae4a7f1a2fb 100644 --- a/arch/arm/mach-tegra/tegra2_emc.c +++ b/arch/arm/mach-tegra/tegra2_emc.c | |||
@@ -183,7 +183,7 @@ static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np) | |||
183 | u32 reg; | 183 | u32 reg; |
184 | 184 | ||
185 | for_each_child_of_node(np, iter) { | 185 | for_each_child_of_node(np, iter) { |
186 | if (of_property_read_u32(np, "nvidia,ram-code", ®)) | 186 | if (of_property_read_u32(iter, "nvidia,ram-code", ®)) |
187 | continue; | 187 | continue; |
188 | if (reg == tegra_bct_strapping) | 188 | if (reg == tegra_bct_strapping) |
189 | return of_node_get(iter); | 189 | return of_node_get(iter); |