aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smp-bmips.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/smp-bmips.c')
-rw-r--r--arch/mips/kernel/smp-bmips.c312
1 files changed, 189 insertions, 123 deletions
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 2362665ba496..ea4c2dc31692 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -49,8 +49,10 @@ cpumask_t bmips_booted_mask;
49unsigned long bmips_smp_boot_sp; 49unsigned long bmips_smp_boot_sp;
50unsigned long bmips_smp_boot_gp; 50unsigned long bmips_smp_boot_gp;
51 51
52static void bmips_send_ipi_single(int cpu, unsigned int action); 52static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
53static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id); 53static void bmips5000_send_ipi_single(int cpu, unsigned int action);
54static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
55static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
54 56
55/* SW interrupts 0,1 are used for interprocessor signaling */ 57/* SW interrupts 0,1 are used for interprocessor signaling */
56#define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0) 58#define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
@@ -64,49 +66,58 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
64static void __init bmips_smp_setup(void) 66static void __init bmips_smp_setup(void)
65{ 67{
66 int i, cpu = 1, boot_cpu = 0; 68 int i, cpu = 1, boot_cpu = 0;
67
68#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
69 int cpu_hw_intr; 69 int cpu_hw_intr;
70 70
71 /* arbitration priority */ 71 switch (current_cpu_type()) {
72 clear_c0_brcm_cmt_ctrl(0x30); 72 case CPU_BMIPS4350:
73 73 case CPU_BMIPS4380:
74 /* NBK and weak order flags */ 74 /* arbitration priority */
75 set_c0_brcm_config_0(0x30000); 75 clear_c0_brcm_cmt_ctrl(0x30);
76 76
77 /* Find out if we are running on TP0 or TP1 */ 77 /* NBK and weak order flags */
78 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); 78 set_c0_brcm_config_0(0x30000);
79 79
80 /* 80 /* Find out if we are running on TP0 or TP1 */
81 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread 81 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
82 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output 82
83 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output 83 /*
84 */ 84 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
85 if (boot_cpu == 0) 85 * thread
86 cpu_hw_intr = 0x02; 86 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
87 else 87 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
88 cpu_hw_intr = 0x1d; 88 */
89 89 if (boot_cpu == 0)
90 change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15)); 90 cpu_hw_intr = 0x02;
91 91 else
92 /* single core, 2 threads (2 pipelines) */ 92 cpu_hw_intr = 0x1d;
93 max_cpus = 2; 93
94#elif defined(CONFIG_CPU_BMIPS5000) 94 change_c0_brcm_cmt_intr(0xf8018000,
95 /* enable raceless SW interrupts */ 95 (cpu_hw_intr << 27) | (0x03 << 15));
96 set_c0_brcm_config(0x03 << 22); 96
97 97 /* single core, 2 threads (2 pipelines) */
98 /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */ 98 max_cpus = 2;
99 change_c0_brcm_mode(0x1f << 27, 0x02 << 27); 99
100 100 break;
101 /* N cores, 2 threads per core */ 101 case CPU_BMIPS5000:
102 max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1; 102 /* enable raceless SW interrupts */
103 set_c0_brcm_config(0x03 << 22);
104
105 /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
106 change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
107
108 /* N cores, 2 threads per core */
109 max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
110
111 /* clear any pending SW interrupts */
112 for (i = 0; i < max_cpus; i++) {
113 write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
114 write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
115 }
103 116
104 /* clear any pending SW interrupts */ 117 break;
105 for (i = 0; i < max_cpus; i++) { 118 default:
106 write_c0_brcm_action(ACTION_CLR_IPI(i, 0)); 119 max_cpus = 1;
107 write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
108 } 120 }
109#endif
110 121
111 if (!bmips_smp_enabled) 122 if (!bmips_smp_enabled)
112 max_cpus = 1; 123 max_cpus = 1;
@@ -134,6 +145,20 @@ static void __init bmips_smp_setup(void)
134 */ 145 */
135static void bmips_prepare_cpus(unsigned int max_cpus) 146static void bmips_prepare_cpus(unsigned int max_cpus)
136{ 147{
148 irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
149
150 switch (current_cpu_type()) {
151 case CPU_BMIPS4350:
152 case CPU_BMIPS4380:
153 bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
154 break;
155 case CPU_BMIPS5000:
156 bmips_ipi_interrupt = bmips5000_ipi_interrupt;
157 break;
158 default:
159 return;
160 }
161
137 if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, 162 if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
138 "smp_ipi0", NULL)) 163 "smp_ipi0", NULL))
139 panic("Can't request IPI0 interrupt"); 164 panic("Can't request IPI0 interrupt");
@@ -168,26 +193,39 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
168 193
169 pr_info("SMP: Booting CPU%d...\n", cpu); 194 pr_info("SMP: Booting CPU%d...\n", cpu);
170 195
171 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) 196 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
172 bmips_send_ipi_single(cpu, 0); 197 switch (current_cpu_type()) {
198 case CPU_BMIPS4350:
199 case CPU_BMIPS4380:
200 bmips43xx_send_ipi_single(cpu, 0);
201 break;
202 case CPU_BMIPS5000:
203 bmips5000_send_ipi_single(cpu, 0);
204 break;
205 }
206 }
173 else { 207 else {
174#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) 208 switch (current_cpu_type()) {
175 /* Reset slave TP1 if booting from TP0 */ 209 case CPU_BMIPS4350:
176 if (cpu_logical_map(cpu) == 1) 210 case CPU_BMIPS4380:
177 set_c0_brcm_cmt_ctrl(0x01); 211 /* Reset slave TP1 if booting from TP0 */
178#elif defined(CONFIG_CPU_BMIPS5000) 212 if (cpu_logical_map(cpu) == 1)
179 if (cpu & 0x01) 213 set_c0_brcm_cmt_ctrl(0x01);
180 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); 214 break;
181 else { 215 case CPU_BMIPS5000:
182 /* 216 if (cpu & 0x01)
183 * core N thread 0 was already booted; just 217 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
184 * pulse the NMI line 218 else {
185 */ 219 /*
186 bmips_write_zscm_reg(0x210, 0xc0000000); 220 * core N thread 0 was already booted; just
187 udelay(10); 221 * pulse the NMI line
188 bmips_write_zscm_reg(0x210, 0x00); 222 */
223 bmips_write_zscm_reg(0x210, 0xc0000000);
224 udelay(10);
225 bmips_write_zscm_reg(0x210, 0x00);
226 }
227 break;
189 } 228 }
190#endif
191 cpumask_set_cpu(cpu, &bmips_booted_mask); 229 cpumask_set_cpu(cpu, &bmips_booted_mask);
192 } 230 }
193} 231}
@@ -199,26 +237,32 @@ static void bmips_init_secondary(void)
199{ 237{
200 /* move NMI vector to kseg0, in case XKS01 is enabled */ 238 /* move NMI vector to kseg0, in case XKS01 is enabled */
201 239
202#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) 240 void __iomem *cbr;
203 void __iomem *cbr = BMIPS_GET_CBR();
204 unsigned long old_vec; 241 unsigned long old_vec;
205 unsigned long relo_vector; 242 unsigned long relo_vector;
206 int boot_cpu; 243 int boot_cpu;
207 244
208 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); 245 switch (current_cpu_type()) {
209 relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 : 246 case CPU_BMIPS4350:
210 BMIPS_RELO_VECTOR_CONTROL_1; 247 case CPU_BMIPS4380:
248 cbr = BMIPS_GET_CBR();
211 249
212 old_vec = __raw_readl(cbr + relo_vector); 250 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
213 __raw_writel(old_vec & ~0x20000000, cbr + relo_vector); 251 relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
252 BMIPS_RELO_VECTOR_CONTROL_1;
214 253
215 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); 254 old_vec = __raw_readl(cbr + relo_vector);
216#elif defined(CONFIG_CPU_BMIPS5000) 255 __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
217 write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
218 (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
219 256
220 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); 257 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
221#endif 258 break;
259 case CPU_BMIPS5000:
260 write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
261 (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
262
263 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
264 break;
265 }
222} 266}
223 267
224/* 268/*
@@ -243,8 +287,6 @@ static void bmips_cpus_done(void)
243{ 287{
244} 288}
245 289
246#if defined(CONFIG_CPU_BMIPS5000)
247
248/* 290/*
249 * BMIPS5000 raceless IPIs 291 * BMIPS5000 raceless IPIs
250 * 292 *
@@ -253,12 +295,12 @@ static void bmips_cpus_done(void)
253 * IPI1 is used for SMP_CALL_FUNCTION 295 * IPI1 is used for SMP_CALL_FUNCTION
254 */ 296 */
255 297
256static void bmips_send_ipi_single(int cpu, unsigned int action) 298static void bmips5000_send_ipi_single(int cpu, unsigned int action)
257{ 299{
258 write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION)); 300 write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
259} 301}
260 302
261static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id) 303static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
262{ 304{
263 int action = irq - IPI0_IRQ; 305 int action = irq - IPI0_IRQ;
264 306
@@ -272,7 +314,14 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
272 return IRQ_HANDLED; 314 return IRQ_HANDLED;
273} 315}
274 316
275#else 317static void bmips5000_send_ipi_mask(const struct cpumask *mask,
318 unsigned int action)
319{
320 unsigned int i;
321
322 for_each_cpu(i, mask)
323 bmips5000_send_ipi_single(i, action);
324}
276 325
277/* 326/*
278 * BMIPS43xx racey IPIs 327 * BMIPS43xx racey IPIs
@@ -287,7 +336,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
287static DEFINE_SPINLOCK(ipi_lock); 336static DEFINE_SPINLOCK(ipi_lock);
288static DEFINE_PER_CPU(int, ipi_action_mask); 337static DEFINE_PER_CPU(int, ipi_action_mask);
289 338
290static void bmips_send_ipi_single(int cpu, unsigned int action) 339static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
291{ 340{
292 unsigned long flags; 341 unsigned long flags;
293 342
@@ -298,7 +347,7 @@ static void bmips_send_ipi_single(int cpu, unsigned int action)
298 spin_unlock_irqrestore(&ipi_lock, flags); 347 spin_unlock_irqrestore(&ipi_lock, flags);
299} 348}
300 349
301static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id) 350static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
302{ 351{
303 unsigned long flags; 352 unsigned long flags;
304 int action, cpu = irq - IPI0_IRQ; 353 int action, cpu = irq - IPI0_IRQ;
@@ -317,15 +366,13 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
317 return IRQ_HANDLED; 366 return IRQ_HANDLED;
318} 367}
319 368
320#endif /* BMIPS type */ 369static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
321
322static void bmips_send_ipi_mask(const struct cpumask *mask,
323 unsigned int action) 370 unsigned int action)
324{ 371{
325 unsigned int i; 372 unsigned int i;
326 373
327 for_each_cpu(i, mask) 374 for_each_cpu(i, mask)
328 bmips_send_ipi_single(i, action); 375 bmips43xx_send_ipi_single(i, action);
329} 376}
330 377
331#ifdef CONFIG_HOTPLUG_CPU 378#ifdef CONFIG_HOTPLUG_CPU
@@ -381,15 +428,30 @@ void __ref play_dead(void)
381 428
382#endif /* CONFIG_HOTPLUG_CPU */ 429#endif /* CONFIG_HOTPLUG_CPU */
383 430
384struct plat_smp_ops bmips_smp_ops = { 431struct plat_smp_ops bmips43xx_smp_ops = {
432 .smp_setup = bmips_smp_setup,
433 .prepare_cpus = bmips_prepare_cpus,
434 .boot_secondary = bmips_boot_secondary,
435 .smp_finish = bmips_smp_finish,
436 .init_secondary = bmips_init_secondary,
437 .cpus_done = bmips_cpus_done,
438 .send_ipi_single = bmips43xx_send_ipi_single,
439 .send_ipi_mask = bmips43xx_send_ipi_mask,
440#ifdef CONFIG_HOTPLUG_CPU
441 .cpu_disable = bmips_cpu_disable,
442 .cpu_die = bmips_cpu_die,
443#endif
444};
445
446struct plat_smp_ops bmips5000_smp_ops = {
385 .smp_setup = bmips_smp_setup, 447 .smp_setup = bmips_smp_setup,
386 .prepare_cpus = bmips_prepare_cpus, 448 .prepare_cpus = bmips_prepare_cpus,
387 .boot_secondary = bmips_boot_secondary, 449 .boot_secondary = bmips_boot_secondary,
388 .smp_finish = bmips_smp_finish, 450 .smp_finish = bmips_smp_finish,
389 .init_secondary = bmips_init_secondary, 451 .init_secondary = bmips_init_secondary,
390 .cpus_done = bmips_cpus_done, 452 .cpus_done = bmips_cpus_done,
391 .send_ipi_single = bmips_send_ipi_single, 453 .send_ipi_single = bmips5000_send_ipi_single,
392 .send_ipi_mask = bmips_send_ipi_mask, 454 .send_ipi_mask = bmips5000_send_ipi_mask,
393#ifdef CONFIG_HOTPLUG_CPU 455#ifdef CONFIG_HOTPLUG_CPU
394 .cpu_disable = bmips_cpu_disable, 456 .cpu_disable = bmips_cpu_disable,
395 .cpu_die = bmips_cpu_die, 457 .cpu_die = bmips_cpu_die,
@@ -427,43 +489,47 @@ void bmips_ebase_setup(void)
427 489
428 BUG_ON(ebase != CKSEG0); 490 BUG_ON(ebase != CKSEG0);
429 491
430#if defined(CONFIG_CPU_BMIPS4350) 492 switch (current_cpu_type()) {
431 /* 493 case CPU_BMIPS4350:
432 * BMIPS4350 cannot relocate the normal vectors, but it 494 /*
433 * can relocate the BEV=1 vectors. So CPU1 starts up at 495 * BMIPS4350 cannot relocate the normal vectors, but it
434 * the relocated BEV=1, IV=0 general exception vector @ 496 * can relocate the BEV=1 vectors. So CPU1 starts up at
435 * 0xa000_0380. 497 * the relocated BEV=1, IV=0 general exception vector @
436 * 498 * 0xa000_0380.
437 * set_uncached_handler() is used here because: 499 *
438 * - CPU1 will run this from uncached space 500 * set_uncached_handler() is used here because:
439 * - None of the cacheflush functions are set up yet 501 * - CPU1 will run this from uncached space
440 */ 502 * - None of the cacheflush functions are set up yet
441 set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0, 503 */
442 &bmips_smp_int_vec, 0x80); 504 set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
443 __sync(); 505 &bmips_smp_int_vec, 0x80);
444 return; 506 __sync();
445#elif defined(CONFIG_CPU_BMIPS4380) 507 return;
446 /* 508 case CPU_BMIPS4380:
447 * 0x8000_0000: reset/NMI (initially in kseg1) 509 /*
448 * 0x8000_0400: normal vectors 510 * 0x8000_0000: reset/NMI (initially in kseg1)
449 */ 511 * 0x8000_0400: normal vectors
450 new_ebase = 0x80000400; 512 */
451 cbr = BMIPS_GET_CBR(); 513 new_ebase = 0x80000400;
452 __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0); 514 cbr = BMIPS_GET_CBR();
453 __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1); 515 __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
454#elif defined(CONFIG_CPU_BMIPS5000) 516 __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
455 /* 517 break;
456 * 0x8000_0000: reset/NMI (initially in kseg1) 518 case CPU_BMIPS5000:
457 * 0x8000_1000: normal vectors 519 /*
458 */ 520 * 0x8000_0000: reset/NMI (initially in kseg1)
459 new_ebase = 0x80001000; 521 * 0x8000_1000: normal vectors
460 write_c0_brcm_bootvec(0xa0088008); 522 */
461 write_c0_ebase(new_ebase); 523 new_ebase = 0x80001000;
462 if (max_cpus > 2) 524 write_c0_brcm_bootvec(0xa0088008);
463 bmips_write_zscm_reg(0xa0, 0xa008a008); 525 write_c0_ebase(new_ebase);
464#else 526 if (max_cpus > 2)
465 return; 527 bmips_write_zscm_reg(0xa0, 0xa008a008);
466#endif 528 break;
529 default:
530 return;
531 }
532
467 board_nmi_handler_setup = &bmips_nmi_handler_setup; 533 board_nmi_handler_setup = &bmips_nmi_handler_setup;
468 ebase = new_ebase; 534 ebase = new_ebase;
469} 535}