1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/smp.h>
21#include <linux/io.h>
22
23#include <asm/cacheflush.h>
24#include <asm/hardware/gic.h>
25#include <asm/smp_scu.h>
26
27#include "omap-secure.h"
28#include "omap-wakeupgen.h"
29#include <asm/cputype.h>
30
31#include "soc.h"
32#include "iomap.h"
33#include "common.h"
34#include "clockdomain.h"
35#include "pm.h"
36
37#define CPU_MASK 0xff0ffff0
38#define CPU_CORTEX_A9 0x410FC090
39#define CPU_CORTEX_A15 0x410FC0F0
40
41#define OMAP5_CORE_COUNT 0x2
42
43u16 pm44xx_errata;
44
45
46static void __iomem *scu_base;
47
48static DEFINE_SPINLOCK(boot_lock);
49
50void __iomem *omap4_get_scu_base(void)
51{
52 return scu_base;
53}
54
55static void __cpuinit omap4_secondary_init(unsigned int cpu)
56{
57
58
59
60
61
62
63
64
65 if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
66 omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
67 4, 0, 0, 0, 0, 0);
68
69
70
71
72
73
74 gic_secondary_init(0);
75
76
77
78
79 spin_lock(&boot_lock);
80 spin_unlock(&boot_lock);
81}
82
83static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
84{
85 static struct clockdomain *cpu1_clkdm;
86 static bool booted;
87 void __iomem *base = omap_get_wakeupgen_base();
88
89
90
91
92
93 spin_lock(&boot_lock);
94
95
96
97
98
99
100
101 if (omap_secure_apis_support())
102 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
103 else
104 __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
105
106 flush_cache_all();
107 smp_wmb();
108
109 if (!cpu1_clkdm)
110 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
111
112
113
114
115
116
117
118
119
120
121
122
123 if (booted) {
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
140 local_irq_disable();
141 gic_dist_disable();
142 }
143
144 clkdm_wakeup(cpu1_clkdm);
145 clkdm_allow_idle(cpu1_clkdm);
146
147 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
148 while (gic_dist_disabled()) {
149 udelay(1);
150 cpu_relax();
151 }
152 gic_timer_retrigger();
153 local_irq_enable();
154 }
155 } else {
156 dsb_sev();
157 booted = true;
158 }
159
160 gic_raise_softirq(cpumask_of(cpu), 0);
161
162
163
164
165
166 spin_unlock(&boot_lock);
167
168 return 0;
169}
170
171static void __init wakeup_secondary(void)
172{
173 void *startup_addr = omap_secondary_startup;
174 void __iomem *base = omap_get_wakeupgen_base();
175
176 if (cpu_is_omap446x()) {
177 startup_addr = omap_secondary_startup_4460;
178 pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD;
179 }
180
181
182
183
184
185
186
187 if (omap_secure_apis_support())
188 omap_auxcoreboot_addr(virt_to_phys(startup_addr));
189 else
190 __raw_writel(virt_to_phys(omap5_secondary_startup),
191 base + OMAP_AUX_CORE_BOOT_1);
192
193 smp_wmb();
194
195
196
197
198
199 dsb_sev();
200 mb();
201}
202
203
204
205
206
207static void __init omap4_smp_init_cpus(void)
208{
209 unsigned int i = 0, ncores = 1, cpu_id;
210
211
212 cpu_id = read_cpuid(CPUID_ID) & CPU_MASK;
213 if (cpu_id == CPU_CORTEX_A9) {
214
215
216
217
218 scu_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE);
219 BUG_ON(!scu_base);
220 ncores = scu_get_core_count(scu_base);
221 } else if (cpu_id == CPU_CORTEX_A15) {
222 ncores = OMAP5_CORE_COUNT;
223 }
224
225
226 if (ncores > nr_cpu_ids) {
227 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
228 ncores, nr_cpu_ids);
229 ncores = nr_cpu_ids;
230 }
231
232 for (i = 0; i < ncores; i++)
233 set_cpu_possible(i, true);
234
235 set_smp_cross_call(gic_raise_softirq);
236}
237
238static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
239{
240
241
242
243
244
245 if (scu_base)
246 scu_enable(scu_base);
247 wakeup_secondary();
248}
249
250struct smp_operations omap4_smp_ops __initdata = {
251 .smp_init_cpus = omap4_smp_init_cpus,
252 .smp_prepare_cpus = omap4_smp_prepare_cpus,
253 .smp_secondary_init = omap4_secondary_init,
254 .smp_boot_secondary = omap4_boot_secondary,
255#ifdef CONFIG_HOTPLUG_CPU
256 .cpu_die = omap4_cpu_die,
257#endif
258};
259