diff options
author | Hiroshi Doyu <hdoyu@nvidia.com> | 2013-02-22 01:24:27 -0500 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2013-03-11 16:29:44 -0400 |
commit | 0d1f79b033bb87091c65cd11bd2dcb6a583c8320 (patch) | |
tree | 2f040b497198ffb9a3db4639e049183062e4f137 | |
parent | 6f88fb8af6c67f281b8e2cd607f08e0089c8ccbe (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.c | 93 |
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 | ||
38 | extern void tegra_secondary_startup(void); | ||
39 | |||
40 | static cpumask_t tegra_cpu_init_mask; | 38 | static cpumask_t tegra_cpu_init_mask; |
41 | 39 | ||
42 | #define EVP_CPU_RESET_VECTOR \ | ||
43 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) | ||
44 | |||
45 | static void __cpuinit tegra_secondary_init(unsigned int cpu) | 40 | static 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 | ||
57 | static int tegra20_power_up_cpu(unsigned int cpu) | 52 | |
53 | static 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 | ||
68 | static int tegra30_power_up_cpu(unsigned int cpu) | 81 | static 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 | ||
138 | static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) | 154 | static 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); | ||
178 | done: | ||
179 | return status; | ||
180 | } | 163 | } |
181 | 164 | ||
182 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) | 165 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |