40
40
41
41
#define OMAP5_CORE_COUNT 0x2
42
42
43
- /* SCU base address */
44
- static void __iomem * scu_base ;
43
+ struct omap_smp_config {
44
+ unsigned long cpu1_rstctrl_pa ;
45
+ void __iomem * cpu1_rstctrl_va ;
46
+ void __iomem * scu_base ;
47
+ void * startup_addr ;
48
+ };
49
+
50
+ static struct omap_smp_config cfg ;
51
+
52
+ static const struct omap_smp_config omap443x_cfg __initconst = {
53
+ .cpu1_rstctrl_pa = 0x4824380c ,
54
+ .startup_addr = omap4_secondary_startup ,
55
+ };
56
+
57
+ static const struct omap_smp_config omap446x_cfg __initconst = {
58
+ .cpu1_rstctrl_pa = 0x4824380c ,
59
+ .startup_addr = omap4460_secondary_startup ,
60
+ };
61
+
62
+ static const struct omap_smp_config omap5_cfg __initconst = {
63
+ .cpu1_rstctrl_pa = 0x48243810 ,
64
+ .startup_addr = omap5_secondary_startup ,
65
+ };
45
66
46
67
static DEFINE_SPINLOCK (boot_lock );
47
68
48
69
void __iomem * omap4_get_scu_base (void )
49
70
{
50
- return scu_base ;
71
+ return cfg . scu_base ;
51
72
}
52
73
53
74
#ifdef CONFIG_OMAP5_ERRATA_801819
@@ -93,7 +114,7 @@ static void omap4_secondary_init(unsigned int cpu)
93
114
* OMAP443X GP devices- SMP bit isn't accessible.
94
115
* OMAP446X GP devices - SMP bit access is enabled on both CPUs.
95
116
*/
96
- if (cpu_is_omap443x () && (omap_type () != OMAP2_DEVICE_TYPE_GP ))
117
+ if (soc_is_omap443x () && (omap_type () != OMAP2_DEVICE_TYPE_GP ))
97
118
omap_secure_dispatcher (OMAP4_PPA_CPU_ACTRL_SMP_INDEX ,
98
119
4 , 0 , 0 , 0 , 0 , 0 );
99
120
@@ -222,9 +243,9 @@ static void __init omap4_smp_init_cpus(void)
222
243
* Currently we can't call ioremap here because
223
244
* SoC detection won't work until after init_early.
224
245
*/
225
- scu_base = OMAP2_L4_IO_ADDRESS (scu_a9_get_base ());
226
- BUG_ON (!scu_base );
227
- ncores = scu_get_core_count (scu_base );
246
+ cfg . scu_base = OMAP2_L4_IO_ADDRESS (scu_a9_get_base ());
247
+ BUG_ON (!cfg . scu_base );
248
+ ncores = scu_get_core_count (cfg . scu_base );
228
249
} else if (cpu_id == CPU_CORTEX_A15 ) {
229
250
ncores = OMAP5_CORE_COUNT ;
230
251
}
@@ -242,20 +263,51 @@ static void __init omap4_smp_init_cpus(void)
242
263
243
264
static void __init omap4_smp_prepare_cpus (unsigned int max_cpus )
244
265
{
245
- void * startup_addr = omap4_secondary_startup ;
246
266
void __iomem * base = omap_get_wakeupgen_base ();
267
+ const struct omap_smp_config * c = NULL ;
268
+
269
+ if (soc_is_omap443x ())
270
+ c = & omap443x_cfg ;
271
+ else if (soc_is_omap446x ())
272
+ c = & omap446x_cfg ;
273
+ else if (soc_is_dra74x () || soc_is_omap54xx ())
274
+ c = & omap5_cfg ;
275
+
276
+ if (!c ) {
277
+ pr_err ("%s Unknown SMP SoC?\n" , __func__ );
278
+ return ;
279
+ }
280
+
281
+ /* Must preserve cfg.scu_base set earlier */
282
+ cfg .cpu1_rstctrl_pa = c -> cpu1_rstctrl_pa ;
283
+ cfg .startup_addr = c -> startup_addr ;
284
+
285
+ if (soc_is_dra74x () || soc_is_omap54xx ()) {
286
+ if ((__boot_cpu_mode & MODE_MASK ) == HYP_MODE )
287
+ cfg .startup_addr = omap5_secondary_hyp_startup ;
288
+ omap5_erratum_workaround_801819 ();
289
+ }
290
+
291
+ cfg .cpu1_rstctrl_va = ioremap (cfg .cpu1_rstctrl_pa , 4 );
292
+ if (!cfg .cpu1_rstctrl_va )
293
+ return ;
247
294
248
295
/*
249
296
* Initialise the SCU and wake up the secondary core using
250
297
* wakeup_secondary().
251
298
*/
252
- if (scu_base )
253
- scu_enable (scu_base );
299
+ if (cfg . scu_base )
300
+ scu_enable (cfg . scu_base );
254
301
255
- if (cpu_is_omap446x ())
256
- startup_addr = omap4460_secondary_startup ;
257
- if (soc_is_dra74x () || soc_is_omap54xx ())
258
- omap5_erratum_workaround_801819 ();
302
+ /*
303
+ * Reset CPU1 before configuring, otherwise kexec will
304
+ * end up trying to use old kernel startup address.
305
+ */
306
+ if (cfg .cpu1_rstctrl_va ) {
307
+ writel_relaxed (1 , cfg .cpu1_rstctrl_va );
308
+ readl_relaxed (cfg .cpu1_rstctrl_va );
309
+ writel_relaxed (0 , cfg .cpu1_rstctrl_va );
310
+ }
259
311
260
312
/*
261
313
* Write the address of secondary startup routine into the
@@ -264,19 +316,10 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
264
316
* A barrier is added to ensure that write buffer is drained
265
317
*/
266
318
if (omap_secure_apis_support ())
267
- omap_auxcoreboot_addr (virt_to_phys (startup_addr ));
319
+ omap_auxcoreboot_addr (virt_to_phys (cfg . startup_addr ));
268
320
else
269
- /*
270
- * If the boot CPU is in HYP mode then start secondary
271
- * CPU in HYP mode as well.
272
- */
273
- if ((__boot_cpu_mode & MODE_MASK ) == HYP_MODE )
274
- writel_relaxed (virt_to_phys (omap5_secondary_hyp_startup ),
275
- base + OMAP_AUX_CORE_BOOT_1 );
276
- else
277
- writel_relaxed (virt_to_phys (omap5_secondary_startup ),
278
- base + OMAP_AUX_CORE_BOOT_1 );
279
-
321
+ writel_relaxed (virt_to_phys (cfg .startup_addr ),
322
+ base + OMAP_AUX_CORE_BOOT_1 );
280
323
}
281
324
282
325
const struct smp_operations omap4_smp_ops __initconst = {
@@ -286,5 +329,6 @@ const struct smp_operations omap4_smp_ops __initconst = {
286
329
.smp_boot_secondary = omap4_boot_secondary ,
287
330
#ifdef CONFIG_HOTPLUG_CPU
288
331
.cpu_die = omap4_cpu_die ,
332
+ .cpu_kill = omap4_cpu_kill ,
289
333
#endif
290
334
};
0 commit comments