aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHiroshi Doyu <hdoyu@nvidia.com>2013-02-22 01:24:27 -0500
committerStephen Warren <swarren@nvidia.com>2013-03-11 16:29:44 -0400
commit0d1f79b033bb87091c65cd11bd2dcb6a583c8320 (patch)
tree2f040b497198ffb9a3db4639e049183062e4f137
parent6f88fb8af6c67f281b8e2cd607f08e0089c8ccbe (diff)
ARM: tegra: refactor tegra{20,30}_boot_secondary
"tegra_boot_secondary()" has many condition branches for some Tegra SoC generations in a single function so that it's not easy to compile a kernel only for a single SoC if one wants with some reason, debug purpose(?). This patch provides SoC specific version of boot_secondary(), tegra{20,30}_boot_secondary(). This could allow any combination of SoC to be built. Those boot_secondary functions can be preparation when we ntroduce chip specific function pointers in the future without having chip dependent branches around. Also removed unused definition/prototpye. Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com> [josephl: remove the Tegra114 part of the original patch] Signed-off-by: Joseph Lo <josephl@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/platsmp.c93
1 files changed, 38 insertions, 55 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index e78d52d83acd..41971ac9376f 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -35,13 +35,8 @@
35#include "common.h" 35#include "common.h"
36#include "iomap.h" 36#include "iomap.h"
37 37
38extern void tegra_secondary_startup(void);
39
40static cpumask_t tegra_cpu_init_mask; 38static cpumask_t tegra_cpu_init_mask;
41 39
42#define EVP_CPU_RESET_VECTOR \
43 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
44
45static void __cpuinit tegra_secondary_init(unsigned int cpu) 40static void __cpuinit tegra_secondary_init(unsigned int cpu)
46{ 41{
47 /* 42 /*
@@ -54,26 +49,48 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu)
54 cpumask_set_cpu(cpu, &tegra_cpu_init_mask); 49 cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
55} 50}
56 51
57static int tegra20_power_up_cpu(unsigned int cpu) 52
53static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
58{ 54{
59 /* Enable the CPU clock. */ 55 cpu = cpu_logical_map(cpu);
60 tegra_enable_cpu_clock(cpu);
61 56
62 /* Clear flow controller CSR. */ 57 /*
63 flowctrl_write_cpu_csr(cpu, 0); 58 * Force the CPU into reset. The CPU must remain in reset when
59 * the flow controller state is cleared (which will cause the
60 * flow controller to stop driving reset if the CPU has been
61 * power-gated via the flow controller). This will have no
62 * effect on first boot of the CPU since it should already be
63 * in reset.
64 */
65 tegra_put_cpu_in_reset(cpu);
64 66
67 /*
68 * Unhalt the CPU. If the flow controller was used to
69 * power-gate the CPU this will cause the flow controller to
70 * stop driving reset. The CPU will remain in reset because the
71 * clock and reset block is now driving reset.
72 */
73 flowctrl_write_cpu_halt(cpu, 0);
74
75 tegra_enable_cpu_clock(cpu);
76 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
77 tegra_cpu_out_of_reset(cpu);
65 return 0; 78 return 0;
66} 79}
67 80
68static int tegra30_power_up_cpu(unsigned int cpu) 81static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
69{ 82{
70 int ret, pwrgateid; 83 int ret, pwrgateid;
71 unsigned long timeout; 84 unsigned long timeout;
72 85
86 cpu = cpu_logical_map(cpu);
73 pwrgateid = tegra_cpu_powergate_id(cpu); 87 pwrgateid = tegra_cpu_powergate_id(cpu);
74 if (pwrgateid < 0) 88 if (pwrgateid < 0)
75 return pwrgateid; 89 return pwrgateid;
76 90
91 tegra_put_cpu_in_reset(cpu);
92 flowctrl_write_cpu_halt(cpu, 0);
93
77 /* 94 /*
78 * The power up sequence of cold boot CPU and warm boot CPU 95 * The power up sequence of cold boot CPU and warm boot CPU
79 * was different. 96 * was different.
@@ -85,7 +102,7 @@ static int tegra30_power_up_cpu(unsigned int cpu)
85 * the IO clamps. 102 * the IO clamps.
86 * For cold boot CPU, do not wait. After the cold boot CPU be 103 * For cold boot CPU, do not wait. After the cold boot CPU be
87 * booted, it will run to tegra_secondary_init() and set 104 * booted, it will run to tegra_secondary_init() and set
88 * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() 105 * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
89 * next time around. 106 * next time around.
90 */ 107 */
91 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 108 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
@@ -129,54 +146,20 @@ remove_clamps:
129 146
130 udelay(10); 147 udelay(10);
131 148
132 /* Clear flow controller CSR. */ 149 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
133 flowctrl_write_cpu_csr(cpu, 0); 150 tegra_cpu_out_of_reset(cpu);
134
135 return 0; 151 return 0;
136} 152}
137 153
138static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) 154static int __cpuinit tegra_boot_secondary(unsigned int cpu,
155 struct task_struct *idle)
139{ 156{
140 int status; 157 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
141 158 return tegra20_boot_secondary(cpu, idle);
142 cpu = cpu_logical_map(cpu); 159 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
143 160 return tegra30_boot_secondary(cpu, idle);
144 /*
145 * Force the CPU into reset. The CPU must remain in reset when the
146 * flow controller state is cleared (which will cause the flow
147 * controller to stop driving reset if the CPU has been power-gated
148 * via the flow controller). This will have no effect on first boot
149 * of the CPU since it should already be in reset.
150 */
151 tegra_put_cpu_in_reset(cpu);
152 161
153 /* 162 return -EINVAL;
154 * Unhalt the CPU. If the flow controller was used to power-gate the
155 * CPU this will cause the flow controller to stop driving reset.
156 * The CPU will remain in reset because the clock and reset block
157 * is now driving reset.
158 */
159 flowctrl_write_cpu_halt(cpu, 0);
160
161 switch (tegra_chip_id) {
162 case TEGRA20:
163 status = tegra20_power_up_cpu(cpu);
164 break;
165 case TEGRA30:
166 status = tegra30_power_up_cpu(cpu);
167 break;
168 default:
169 status = -EINVAL;
170 break;
171 }
172
173 if (status)
174 goto done;
175
176 /* Take the CPU out of reset. */
177 tegra_cpu_out_of_reset(cpu);
178done:
179 return status;
180} 163}
181 164
182static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 165static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)