0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/init.h>
0012 #include <linux/sched.h>
0013 #include <linux/sched/hotplug.h>
0014 #include <linux/sched/task_stack.h>
0015 #include <linux/mm.h>
0016 #include <linux/delay.h>
0017 #include <linux/smp.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/spinlock.h>
0020 #include <linux/cpu.h>
0021 #include <linux/cpumask.h>
0022 #include <linux/reboot.h>
0023 #include <linux/io.h>
0024 #include <linux/compiler.h>
0025 #include <linux/linkage.h>
0026 #include <linux/bug.h>
0027 #include <linux/kernel.h>
0028 #include <linux/kexec.h>
0029 #include <linux/irq.h>
0030
0031 #include <asm/time.h>
0032 #include <asm/processor.h>
0033 #include <asm/bootinfo.h>
0034 #include <asm/cacheflush.h>
0035 #include <asm/tlbflush.h>
0036 #include <asm/mipsregs.h>
0037 #include <asm/bmips.h>
0038 #include <asm/traps.h>
0039 #include <asm/barrier.h>
0040 #include <asm/cpu-features.h>
0041
0042 static int __maybe_unused max_cpus = 1;
0043
0044
0045 int bmips_smp_enabled = 1;
0046 int bmips_cpu_offset;
0047 cpumask_t bmips_booted_mask;
0048 unsigned long bmips_tp1_irqs = IE_IRQ1;
0049
0050 #define RESET_FROM_KSEG0 0x80080800
0051 #define RESET_FROM_KSEG1 0xa0080800
0052
0053 static void bmips_set_reset_vec(int cpu, u32 val);
0054
0055 #ifdef CONFIG_SMP
0056
0057
0058 unsigned long bmips_smp_boot_sp;
0059 unsigned long bmips_smp_boot_gp;
0060
0061 static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
0062 static void bmips5000_send_ipi_single(int cpu, unsigned int action);
0063 static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
0064 static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
0065
0066
0067 #define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
0068 #define IPI1_IRQ (MIPS_CPU_IRQ_BASE + 1)
0069
0070 #define CPUNUM(cpu, shift) (((cpu) + bmips_cpu_offset) << (shift))
0071 #define ACTION_CLR_IPI(cpu, ipi) (0x2000 | CPUNUM(cpu, 9) | ((ipi) << 8))
0072 #define ACTION_SET_IPI(cpu, ipi) (0x3000 | CPUNUM(cpu, 9) | ((ipi) << 8))
0073 #define ACTION_BOOT_THREAD(cpu) (0x08 | CPUNUM(cpu, 0))
0074
0075 static void __init bmips_smp_setup(void)
0076 {
0077 int i, cpu = 1, boot_cpu = 0;
0078 int cpu_hw_intr;
0079
0080 switch (current_cpu_type()) {
0081 case CPU_BMIPS4350:
0082 case CPU_BMIPS4380:
0083
0084 clear_c0_brcm_cmt_ctrl(0x30);
0085
0086
0087 set_c0_brcm_config_0(0x30000);
0088
0089
0090 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
0091
0092
0093
0094
0095
0096
0097
0098 if (boot_cpu == 0)
0099 cpu_hw_intr = 0x02;
0100 else
0101 cpu_hw_intr = 0x1d;
0102
0103 change_c0_brcm_cmt_intr(0xf8018000,
0104 (cpu_hw_intr << 27) | (0x03 << 15));
0105
0106
0107 max_cpus = 2;
0108
0109 break;
0110 case CPU_BMIPS5000:
0111
0112 set_c0_brcm_config(0x03 << 22);
0113
0114
0115 change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
0116
0117
0118 max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
0119
0120
0121 for (i = 0; i < max_cpus; i++) {
0122 write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
0123 write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
0124 }
0125
0126 break;
0127 default:
0128 max_cpus = 1;
0129 }
0130
0131 if (!bmips_smp_enabled)
0132 max_cpus = 1;
0133
0134
0135 if (!board_ebase_setup)
0136 board_ebase_setup = &bmips_ebase_setup;
0137
0138 if (max_cpus > 1) {
0139 __cpu_number_map[boot_cpu] = 0;
0140 __cpu_logical_map[0] = boot_cpu;
0141
0142 for (i = 0; i < max_cpus; i++) {
0143 if (i != boot_cpu) {
0144 __cpu_number_map[i] = cpu;
0145 __cpu_logical_map[cpu] = i;
0146 cpu++;
0147 }
0148 set_cpu_possible(i, 1);
0149 set_cpu_present(i, 1);
0150 }
0151 } else {
0152 __cpu_number_map[0] = boot_cpu;
0153 __cpu_logical_map[0] = 0;
0154 set_cpu_possible(0, 1);
0155 set_cpu_present(0, 1);
0156 }
0157 }
0158
0159
0160
0161
0162 static void bmips_prepare_cpus(unsigned int max_cpus)
0163 {
0164 irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
0165
0166 switch (current_cpu_type()) {
0167 case CPU_BMIPS4350:
0168 case CPU_BMIPS4380:
0169 bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
0170 break;
0171 case CPU_BMIPS5000:
0172 bmips_ipi_interrupt = bmips5000_ipi_interrupt;
0173 break;
0174 default:
0175 return;
0176 }
0177
0178 if (request_irq(IPI0_IRQ, bmips_ipi_interrupt,
0179 IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL))
0180 panic("Can't request IPI0 interrupt");
0181 if (request_irq(IPI1_IRQ, bmips_ipi_interrupt,
0182 IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL))
0183 panic("Can't request IPI1 interrupt");
0184 }
0185
0186
0187
0188
0189 static int bmips_boot_secondary(int cpu, struct task_struct *idle)
0190 {
0191 bmips_smp_boot_sp = __KSTK_TOS(idle);
0192 bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
0193 mb();
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 pr_info("SMP: Booting CPU%d...\n", cpu);
0211
0212 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
0213
0214 bmips_set_reset_vec(cpu, RESET_FROM_KSEG0);
0215
0216 switch (current_cpu_type()) {
0217 case CPU_BMIPS4350:
0218 case CPU_BMIPS4380:
0219 bmips43xx_send_ipi_single(cpu, 0);
0220 break;
0221 case CPU_BMIPS5000:
0222 bmips5000_send_ipi_single(cpu, 0);
0223 break;
0224 }
0225 } else {
0226 bmips_set_reset_vec(cpu, RESET_FROM_KSEG1);
0227
0228 switch (current_cpu_type()) {
0229 case CPU_BMIPS4350:
0230 case CPU_BMIPS4380:
0231
0232 if (cpu_logical_map(cpu) == 1)
0233 set_c0_brcm_cmt_ctrl(0x01);
0234 break;
0235 case CPU_BMIPS5000:
0236 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
0237 break;
0238 }
0239 cpumask_set_cpu(cpu, &bmips_booted_mask);
0240 }
0241
0242 return 0;
0243 }
0244
0245
0246
0247
0248 static void bmips_init_secondary(void)
0249 {
0250 bmips_cpu_setup();
0251
0252 switch (current_cpu_type()) {
0253 case CPU_BMIPS4350:
0254 case CPU_BMIPS4380:
0255 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
0256 break;
0257 case CPU_BMIPS5000:
0258 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
0259 cpu_set_core(¤t_cpu_data, (read_c0_brcm_config() >> 25) & 3);
0260 break;
0261 }
0262 }
0263
0264
0265
0266
0267 static void bmips_smp_finish(void)
0268 {
0269 pr_info("SMP: CPU%d is running\n", smp_processor_id());
0270
0271
0272 write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
0273
0274 irq_enable_hazard();
0275 set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE);
0276 irq_enable_hazard();
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 static void bmips5000_send_ipi_single(int cpu, unsigned int action)
0288 {
0289 write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
0290 }
0291
0292 static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
0293 {
0294 int action = irq - IPI0_IRQ;
0295
0296 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), action));
0297
0298 if (action == 0)
0299 scheduler_ipi();
0300 else
0301 generic_smp_call_function_interrupt();
0302
0303 return IRQ_HANDLED;
0304 }
0305
0306 static void bmips5000_send_ipi_mask(const struct cpumask *mask,
0307 unsigned int action)
0308 {
0309 unsigned int i;
0310
0311 for_each_cpu(i, mask)
0312 bmips5000_send_ipi_single(i, action);
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 static DEFINE_SPINLOCK(ipi_lock);
0326 static DEFINE_PER_CPU(int, ipi_action_mask);
0327
0328 static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
0329 {
0330 unsigned long flags;
0331
0332 spin_lock_irqsave(&ipi_lock, flags);
0333 set_c0_cause(cpu ? C_SW1 : C_SW0);
0334 per_cpu(ipi_action_mask, cpu) |= action;
0335 irq_enable_hazard();
0336 spin_unlock_irqrestore(&ipi_lock, flags);
0337 }
0338
0339 static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
0340 {
0341 unsigned long flags;
0342 int action, cpu = irq - IPI0_IRQ;
0343
0344 spin_lock_irqsave(&ipi_lock, flags);
0345 action = __this_cpu_read(ipi_action_mask);
0346 per_cpu(ipi_action_mask, cpu) = 0;
0347 clear_c0_cause(cpu ? C_SW1 : C_SW0);
0348 spin_unlock_irqrestore(&ipi_lock, flags);
0349
0350 if (action & SMP_RESCHEDULE_YOURSELF)
0351 scheduler_ipi();
0352 if (action & SMP_CALL_FUNCTION)
0353 generic_smp_call_function_interrupt();
0354
0355 return IRQ_HANDLED;
0356 }
0357
0358 static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
0359 unsigned int action)
0360 {
0361 unsigned int i;
0362
0363 for_each_cpu(i, mask)
0364 bmips43xx_send_ipi_single(i, action);
0365 }
0366
0367 #ifdef CONFIG_HOTPLUG_CPU
0368
0369 static int bmips_cpu_disable(void)
0370 {
0371 unsigned int cpu = smp_processor_id();
0372
0373 pr_info("SMP: CPU%d is offline\n", cpu);
0374
0375 set_cpu_online(cpu, false);
0376 calculate_cpu_foreign_map();
0377 irq_migrate_all_off_this_cpu();
0378 clear_c0_status(IE_IRQ5);
0379
0380 local_flush_tlb_all();
0381 local_flush_icache_range(0, ~0);
0382
0383 return 0;
0384 }
0385
0386 static void bmips_cpu_die(unsigned int cpu)
0387 {
0388 }
0389
0390 void __ref play_dead(void)
0391 {
0392 idle_task_exit();
0393
0394
0395 _dma_cache_wback_inv(0, ~0);
0396
0397
0398
0399
0400
0401
0402 clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1);
0403 change_c0_status(
0404 IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV,
0405 IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV);
0406 irq_disable_hazard();
0407
0408
0409
0410
0411
0412 __asm__ __volatile__(
0413 " wait\n"
0414 " j bmips_secondary_reentry\n"
0415 : : : "memory");
0416 }
0417
0418 #endif
0419
0420 const struct plat_smp_ops bmips43xx_smp_ops = {
0421 .smp_setup = bmips_smp_setup,
0422 .prepare_cpus = bmips_prepare_cpus,
0423 .boot_secondary = bmips_boot_secondary,
0424 .smp_finish = bmips_smp_finish,
0425 .init_secondary = bmips_init_secondary,
0426 .send_ipi_single = bmips43xx_send_ipi_single,
0427 .send_ipi_mask = bmips43xx_send_ipi_mask,
0428 #ifdef CONFIG_HOTPLUG_CPU
0429 .cpu_disable = bmips_cpu_disable,
0430 .cpu_die = bmips_cpu_die,
0431 #endif
0432 #ifdef CONFIG_KEXEC
0433 .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
0434 #endif
0435 };
0436
0437 const struct plat_smp_ops bmips5000_smp_ops = {
0438 .smp_setup = bmips_smp_setup,
0439 .prepare_cpus = bmips_prepare_cpus,
0440 .boot_secondary = bmips_boot_secondary,
0441 .smp_finish = bmips_smp_finish,
0442 .init_secondary = bmips_init_secondary,
0443 .send_ipi_single = bmips5000_send_ipi_single,
0444 .send_ipi_mask = bmips5000_send_ipi_mask,
0445 #ifdef CONFIG_HOTPLUG_CPU
0446 .cpu_disable = bmips_cpu_disable,
0447 .cpu_die = bmips_cpu_die,
0448 #endif
0449 #ifdef CONFIG_KEXEC
0450 .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
0451 #endif
0452 };
0453
0454 #endif
0455
0456
0457
0458
0459
0460
0461
0462 static void bmips_wr_vec(unsigned long dst, char *start, char *end)
0463 {
0464 memcpy((void *)dst, start, end - start);
0465 dma_cache_wback(dst, end - start);
0466 local_flush_icache_range(dst, dst + (end - start));
0467 instruction_hazard();
0468 }
0469
0470 static inline void bmips_nmi_handler_setup(void)
0471 {
0472 bmips_wr_vec(BMIPS_NMI_RESET_VEC, bmips_reset_nmi_vec,
0473 bmips_reset_nmi_vec_end);
0474 bmips_wr_vec(BMIPS_WARM_RESTART_VEC, bmips_smp_int_vec,
0475 bmips_smp_int_vec_end);
0476 }
0477
0478 struct reset_vec_info {
0479 int cpu;
0480 u32 val;
0481 };
0482
0483 static void bmips_set_reset_vec_remote(void *vinfo)
0484 {
0485 struct reset_vec_info *info = vinfo;
0486 int shift = info->cpu & 0x01 ? 16 : 0;
0487 u32 mask = ~(0xffff << shift), val = info->val >> 16;
0488
0489 preempt_disable();
0490 if (smp_processor_id() > 0) {
0491 smp_call_function_single(0, &bmips_set_reset_vec_remote,
0492 info, 1);
0493 } else {
0494 if (info->cpu & 0x02) {
0495
0496 bmips_write_zscm_reg(0xa0, (val << 16) | val);
0497 bmips_read_zscm_reg(0xa0);
0498 } else {
0499 write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) |
0500 (val << shift));
0501 }
0502 }
0503 preempt_enable();
0504 }
0505
0506 static void bmips_set_reset_vec(int cpu, u32 val)
0507 {
0508 struct reset_vec_info info;
0509
0510 if (current_cpu_type() == CPU_BMIPS5000) {
0511
0512 info.cpu = cpu;
0513 info.val = val;
0514 bmips_set_reset_vec_remote(&info);
0515 } else {
0516 void __iomem *cbr = BMIPS_GET_CBR();
0517
0518 if (cpu == 0)
0519 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
0520 else {
0521 if (current_cpu_type() != CPU_BMIPS4380)
0522 return;
0523 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
0524 }
0525 }
0526 __sync();
0527 back_to_back_c0_hazard();
0528 }
0529
0530 void bmips_ebase_setup(void)
0531 {
0532 unsigned long new_ebase = ebase;
0533
0534 BUG_ON(ebase != CKSEG0);
0535
0536 switch (current_cpu_type()) {
0537 case CPU_BMIPS4350:
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
0549 &bmips_smp_int_vec, 0x80);
0550 __sync();
0551 return;
0552 case CPU_BMIPS3300:
0553 case CPU_BMIPS4380:
0554
0555
0556
0557
0558 new_ebase = 0x80000400;
0559 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
0560 break;
0561 case CPU_BMIPS5000:
0562
0563
0564
0565
0566 new_ebase = 0x80001000;
0567 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
0568 write_c0_ebase(new_ebase);
0569 break;
0570 default:
0571 return;
0572 }
0573
0574 board_nmi_handler_setup = &bmips_nmi_handler_setup;
0575 ebase = new_ebase;
0576 }
0577
0578 asmlinkage void __weak plat_wired_tlb_setup(void)
0579 {
0580
0581
0582
0583
0584
0585 }
0586
0587 void bmips_cpu_setup(void)
0588 {
0589 void __iomem __maybe_unused *cbr = BMIPS_GET_CBR();
0590 u32 __maybe_unused cfg;
0591
0592 switch (current_cpu_type()) {
0593 case CPU_BMIPS3300:
0594
0595 set_c0_brcm_bus_pll(BIT(22));
0596 __sync();
0597
0598
0599 clear_c0_brcm_bus_pll(BIT(22));
0600
0601
0602 clear_c0_brcm_reset(BIT(16));
0603
0604
0605 cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
0606 __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
0607 __raw_readl(cbr + BMIPS_RAC_CONFIG);
0608
0609 cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
0610 __raw_writel(cfg | 0xf, cbr + BMIPS_RAC_CONFIG);
0611 __raw_readl(cbr + BMIPS_RAC_CONFIG);
0612
0613 cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE);
0614 __raw_writel(cfg | 0x0fff0000, cbr + BMIPS_RAC_ADDRESS_RANGE);
0615 __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE);
0616 break;
0617
0618 case CPU_BMIPS4380:
0619
0620 switch (read_c0_prid()) {
0621 case 0x2a040:
0622 case 0x2a042:
0623 case 0x2a044:
0624 case 0x2a060:
0625 cfg = __raw_readl(cbr + BMIPS_L2_CONFIG);
0626 __raw_writel(cfg & ~0x07000000, cbr + BMIPS_L2_CONFIG);
0627 __raw_readl(cbr + BMIPS_L2_CONFIG);
0628 }
0629
0630
0631 clear_c0_brcm_config_0(BIT(21));
0632
0633
0634 set_c0_brcm_config_0(BIT(23));
0635 set_c0_brcm_cmt_ctrl(BIT(15));
0636 break;
0637
0638 case CPU_BMIPS5000:
0639
0640 set_c0_brcm_config(BIT(17) | BIT(21));
0641
0642
0643 __asm__ __volatile__(
0644 " .set noreorder\n"
0645 " li $8, 0x5a455048\n"
0646 " .word 0x4088b00f\n"
0647 " .word 0x4008b008\n"
0648 " li $9, 0x00008000\n"
0649 " or $8, $8, $9\n"
0650 " .word 0x4088b008\n"
0651 " sync\n"
0652 " li $8, 0x0\n"
0653 " .word 0x4088b00f\n"
0654 " .set reorder\n"
0655 : : : "$8", "$9");
0656
0657
0658 set_c0_brcm_config(BIT(27));
0659
0660
0661 __asm__ __volatile__(
0662 " li $8, 0x5a455048\n"
0663 " .word 0x4088b00f\n"
0664 " nop; nop; nop\n"
0665 " .word 0x4008b008\n"
0666 " lui $9, 0x0100\n"
0667 " or $8, $9\n"
0668 " .word 0x4088b008\n"
0669 : : : "$8", "$9");
0670 break;
0671 }
0672 }