0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/kernel.h>
0021 #include <linux/sched.h>
0022 #include <linux/sched/hotplug.h>
0023 #include <linux/smp.h>
0024 #include <linux/interrupt.h>
0025 #include <linux/irqdomain.h>
0026 #include <linux/kernel_stat.h>
0027 #include <linux/delay.h>
0028 #include <linux/init.h>
0029 #include <linux/spinlock.h>
0030 #include <linux/errno.h>
0031 #include <linux/hardirq.h>
0032 #include <linux/cpu.h>
0033 #include <linux/compiler.h>
0034 #include <linux/pgtable.h>
0035
0036 #include <asm/ptrace.h>
0037 #include <linux/atomic.h>
0038 #include <asm/code-patching.h>
0039 #include <asm/irq.h>
0040 #include <asm/page.h>
0041 #include <asm/sections.h>
0042 #include <asm/io.h>
0043 #include <asm/smp.h>
0044 #include <asm/machdep.h>
0045 #include <asm/pmac_feature.h>
0046 #include <asm/time.h>
0047 #include <asm/mpic.h>
0048 #include <asm/cacheflush.h>
0049 #include <asm/keylargo.h>
0050 #include <asm/pmac_low_i2c.h>
0051 #include <asm/pmac_pfunc.h>
0052 #include <asm/inst.h>
0053
0054 #include "pmac.h"
0055
0056 #undef DEBUG
0057
0058 #ifdef DEBUG
0059 #define DBG(fmt...) udbg_printf(fmt)
0060 #else
0061 #define DBG(fmt...)
0062 #endif
0063
0064 extern void __secondary_start_pmac_0(void);
0065
0066 static void (*pmac_tb_freeze)(int freeze);
0067 static u64 timebase;
0068 static int tb_req;
0069
0070 #ifdef CONFIG_PPC_PMAC32_PSURGE
0071
0072
0073
0074
0075
0076
0077 #define HAMMERHEAD_BASE 0xf8000000
0078 #define HHEAD_CONFIG 0x90
0079 #define HHEAD_SEC_INTR 0xc0
0080
0081
0082
0083 #define PSURGE_PRI_INTR 0xf3019000
0084
0085
0086
0087 #define PSURGE_START 0xf2800000
0088
0089
0090 #define PSURGE_QUAD_REG_ADDR 0xf8800000
0091
0092 #define PSURGE_QUAD_IRQ_SET 0
0093 #define PSURGE_QUAD_IRQ_CLR 1
0094 #define PSURGE_QUAD_IRQ_PRIMARY 2
0095 #define PSURGE_QUAD_CKSTOP_CTL 3
0096 #define PSURGE_QUAD_PRIMARY_ARB 4
0097 #define PSURGE_QUAD_BOARD_ID 6
0098 #define PSURGE_QUAD_WHICH_CPU 7
0099 #define PSURGE_QUAD_CKSTOP_RDBK 8
0100 #define PSURGE_QUAD_RESET_CTL 11
0101
0102 #define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
0103 #define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
0104 #define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
0105 #define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
0106
0107
0108 static volatile u8 __iomem *hhead_base;
0109 static volatile u8 __iomem *quad_base;
0110 static volatile u32 __iomem *psurge_pri_intr;
0111 static volatile u8 __iomem *psurge_sec_intr;
0112 static volatile u32 __iomem *psurge_start;
0113
0114
0115 #define PSURGE_NONE -1
0116 #define PSURGE_DUAL 0
0117 #define PSURGE_QUAD_OKEE 1
0118 #define PSURGE_QUAD_COTTON 2
0119 #define PSURGE_QUAD_ICEGRASS 3
0120
0121
0122 static int psurge_type = PSURGE_NONE;
0123
0124
0125 static struct irq_domain *psurge_host;
0126 int psurge_secondary_virq;
0127
0128
0129
0130
0131 static inline void psurge_set_ipi(int cpu)
0132 {
0133 if (psurge_type == PSURGE_NONE)
0134 return;
0135 if (cpu == 0)
0136 in_be32(psurge_pri_intr);
0137 else if (psurge_type == PSURGE_DUAL)
0138 out_8(psurge_sec_intr, 0);
0139 else
0140 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
0141 }
0142
0143 static inline void psurge_clr_ipi(int cpu)
0144 {
0145 if (cpu > 0) {
0146 switch(psurge_type) {
0147 case PSURGE_DUAL:
0148 out_8(psurge_sec_intr, ~0);
0149 break;
0150 case PSURGE_NONE:
0151 break;
0152 default:
0153 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
0154 }
0155 }
0156 }
0157
0158
0159
0160
0161
0162
0163
0164 static irqreturn_t psurge_ipi_intr(int irq, void *d)
0165 {
0166 psurge_clr_ipi(smp_processor_id());
0167 smp_ipi_demux();
0168
0169 return IRQ_HANDLED;
0170 }
0171
0172 static void smp_psurge_cause_ipi(int cpu)
0173 {
0174 psurge_set_ipi(cpu);
0175 }
0176
0177 static int psurge_host_map(struct irq_domain *h, unsigned int virq,
0178 irq_hw_number_t hw)
0179 {
0180 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
0181
0182 return 0;
0183 }
0184
0185 static const struct irq_domain_ops psurge_host_ops = {
0186 .map = psurge_host_map,
0187 };
0188
0189 static int __init psurge_secondary_ipi_init(void)
0190 {
0191 int rc = -ENOMEM;
0192
0193 psurge_host = irq_domain_add_nomap(NULL, ~0, &psurge_host_ops, NULL);
0194
0195 if (psurge_host)
0196 psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
0197
0198 if (psurge_secondary_virq)
0199 rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
0200 IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL);
0201
0202 if (rc)
0203 pr_err("Failed to setup secondary cpu IPI\n");
0204
0205 return rc;
0206 }
0207
0208
0209
0210
0211
0212
0213 static int __init psurge_quad_probe(void)
0214 {
0215 int type;
0216 unsigned int i;
0217
0218 type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
0219 if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
0220 || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
0221 return PSURGE_DUAL;
0222
0223
0224
0225
0226 for (i = 0; i < 100; i++) {
0227 volatile u32 bogus[8];
0228 bogus[(0+i)%8] = 0x00000000;
0229 bogus[(1+i)%8] = 0x55555555;
0230 bogus[(2+i)%8] = 0xFFFFFFFF;
0231 bogus[(3+i)%8] = 0xAAAAAAAA;
0232 bogus[(4+i)%8] = 0x33333333;
0233 bogus[(5+i)%8] = 0xCCCCCCCC;
0234 bogus[(6+i)%8] = 0xCCCCCCCC;
0235 bogus[(7+i)%8] = 0x33333333;
0236 wmb();
0237 asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
0238 mb();
0239 if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
0240 return PSURGE_DUAL;
0241 }
0242 return type;
0243 }
0244
0245 static void __init psurge_quad_init(void)
0246 {
0247 int procbits;
0248
0249 if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
0250 procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
0251 if (psurge_type == PSURGE_QUAD_ICEGRASS)
0252 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
0253 else
0254 PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
0255 mdelay(33);
0256 out_8(psurge_sec_intr, ~0);
0257 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
0258 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
0259 if (psurge_type != PSURGE_QUAD_ICEGRASS)
0260 PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
0261 PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
0262 mdelay(33);
0263 PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
0264 mdelay(33);
0265 PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
0266 mdelay(33);
0267 }
0268
0269 static void __init smp_psurge_probe(void)
0270 {
0271 int i, ncpus;
0272 struct device_node *dn;
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 dn = of_find_node_by_name(NULL, "hammerhead");
0285 if (dn == NULL)
0286 return;
0287 of_node_put(dn);
0288
0289 hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
0290 quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
0291 psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
0292
0293 psurge_type = psurge_quad_probe();
0294 if (psurge_type != PSURGE_DUAL) {
0295 psurge_quad_init();
0296
0297 ncpus = 4;
0298
0299 smp_ops->give_timebase = smp_generic_give_timebase;
0300 smp_ops->take_timebase = smp_generic_take_timebase;
0301 } else {
0302 iounmap(quad_base);
0303 if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
0304
0305 iounmap(hhead_base);
0306 psurge_type = PSURGE_NONE;
0307 return;
0308 }
0309 ncpus = 2;
0310 }
0311
0312 if (psurge_secondary_ipi_init())
0313 return;
0314
0315 psurge_start = ioremap(PSURGE_START, 4);
0316 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
0317
0318
0319
0320
0321
0322
0323 if (ncpus > NR_CPUS)
0324 ncpus = NR_CPUS;
0325 for (i = 1; i < ncpus ; ++i)
0326 set_cpu_present(i, true);
0327
0328 if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
0329 }
0330
0331 static int __init smp_psurge_kick_cpu(int nr)
0332 {
0333 unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
0334 unsigned long a, flags;
0335 int i, j;
0336
0337
0338
0339
0340
0341 extern volatile unsigned int cpu_callin_map[NR_CPUS];
0342
0343
0344 for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
0345 asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
0346 asm volatile("sync");
0347
0348 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
0349
0350
0351 local_irq_save(flags);
0352
0353 out_be32(psurge_start, start);
0354 mb();
0355
0356 psurge_set_ipi(nr);
0357
0358
0359
0360
0361 for (i = 0; i < 2000; ++i)
0362 asm volatile("nop" : : : "memory");
0363 psurge_clr_ipi(nr);
0364
0365
0366
0367
0368
0369
0370 for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) {
0371 for (j = 1; j < 10000; j++)
0372 asm volatile("nop" : : : "memory");
0373 asm volatile("sync" : : : "memory");
0374 }
0375 if (!cpu_callin_map[nr])
0376 goto stuck;
0377
0378
0379 if (psurge_type == PSURGE_DUAL) {
0380 while(!tb_req)
0381 barrier();
0382 tb_req = 0;
0383 mb();
0384 timebase = get_tb();
0385 mb();
0386 while (timebase)
0387 barrier();
0388 mb();
0389 }
0390 stuck:
0391
0392 if (psurge_type == PSURGE_DUAL)
0393 psurge_set_ipi(1);
0394
0395 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
0396
0397 return 0;
0398 }
0399
0400 static void __init smp_psurge_setup_cpu(int cpu_nr)
0401 {
0402 unsigned long flags = IRQF_PERCPU | IRQF_NO_THREAD;
0403 int irq;
0404
0405 if (cpu_nr != 0 || !psurge_start)
0406 return;
0407
0408
0409
0410 out_be32(psurge_start, 0x100);
0411 irq = irq_create_mapping(NULL, 30);
0412 if (request_irq(irq, psurge_ipi_intr, flags, "primary IPI", NULL))
0413 printk(KERN_ERR "Couldn't get primary IPI interrupt");
0414 }
0415
0416 void __init smp_psurge_take_timebase(void)
0417 {
0418 if (psurge_type != PSURGE_DUAL)
0419 return;
0420
0421 tb_req = 1;
0422 mb();
0423 while (!timebase)
0424 barrier();
0425 mb();
0426 set_tb(timebase >> 32, timebase & 0xffffffff);
0427 timebase = 0;
0428 mb();
0429 set_dec(tb_ticks_per_jiffy/2);
0430 }
0431
0432 void __init smp_psurge_give_timebase(void)
0433 {
0434
0435 }
0436
0437
0438 struct smp_ops_t psurge_smp_ops = {
0439 .message_pass = NULL,
0440 .cause_ipi = smp_psurge_cause_ipi,
0441 .cause_nmi_ipi = NULL,
0442 .probe = smp_psurge_probe,
0443 .kick_cpu = smp_psurge_kick_cpu,
0444 .setup_cpu = smp_psurge_setup_cpu,
0445 .give_timebase = smp_psurge_give_timebase,
0446 .take_timebase = smp_psurge_take_timebase,
0447 };
0448 #endif
0449
0450
0451
0452
0453
0454
0455 static void smp_core99_give_timebase(void)
0456 {
0457 unsigned long flags;
0458
0459 local_irq_save(flags);
0460
0461 while(!tb_req)
0462 barrier();
0463 tb_req = 0;
0464 (*pmac_tb_freeze)(1);
0465 mb();
0466 timebase = get_tb();
0467 mb();
0468 while (timebase)
0469 barrier();
0470 mb();
0471 (*pmac_tb_freeze)(0);
0472 mb();
0473
0474 local_irq_restore(flags);
0475 }
0476
0477
0478 static void smp_core99_take_timebase(void)
0479 {
0480 unsigned long flags;
0481
0482 local_irq_save(flags);
0483
0484 tb_req = 1;
0485 mb();
0486 while (!timebase)
0487 barrier();
0488 mb();
0489 set_tb(timebase >> 32, timebase & 0xffffffff);
0490 timebase = 0;
0491 mb();
0492
0493 local_irq_restore(flags);
0494 }
0495
0496 #ifdef CONFIG_PPC64
0497
0498
0499
0500 static struct pmac_i2c_bus *pmac_tb_clock_chip_host;
0501 static u8 pmac_tb_pulsar_addr;
0502
0503 static void smp_core99_cypress_tb_freeze(int freeze)
0504 {
0505 u8 data;
0506 int rc;
0507
0508
0509
0510
0511 pmac_i2c_setmode(pmac_tb_clock_chip_host,
0512 pmac_i2c_mode_combined);
0513 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
0514 0xd0 | pmac_i2c_read,
0515 1, 0x81, &data, 1);
0516 if (rc != 0)
0517 goto bail;
0518
0519 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
0520
0521 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
0522 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
0523 0xd0 | pmac_i2c_write,
0524 1, 0x81, &data, 1);
0525
0526 bail:
0527 if (rc != 0) {
0528 printk("Cypress Timebase %s rc: %d\n",
0529 freeze ? "freeze" : "unfreeze", rc);
0530 panic("Timebase freeze failed !\n");
0531 }
0532 }
0533
0534
0535 static void smp_core99_pulsar_tb_freeze(int freeze)
0536 {
0537 u8 data;
0538 int rc;
0539
0540 pmac_i2c_setmode(pmac_tb_clock_chip_host,
0541 pmac_i2c_mode_combined);
0542 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
0543 pmac_tb_pulsar_addr | pmac_i2c_read,
0544 1, 0x2e, &data, 1);
0545 if (rc != 0)
0546 goto bail;
0547
0548 data = (data & 0x88) | (freeze ? 0x11 : 0x22);
0549
0550 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
0551 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
0552 pmac_tb_pulsar_addr | pmac_i2c_write,
0553 1, 0x2e, &data, 1);
0554 bail:
0555 if (rc != 0) {
0556 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
0557 freeze ? "freeze" : "unfreeze", rc);
0558 panic("Timebase freeze failed !\n");
0559 }
0560 }
0561
0562 static void __init smp_core99_setup_i2c_hwsync(int ncpus)
0563 {
0564 struct device_node *cc = NULL;
0565 struct device_node *p;
0566 const char *name = NULL;
0567 const u32 *reg;
0568 int ok;
0569
0570
0571 for_each_node_by_name(cc, "i2c-hwclock") {
0572 p = of_get_parent(cc);
0573 ok = p && of_device_is_compatible(p, "uni-n-i2c");
0574 of_node_put(p);
0575 if (!ok)
0576 continue;
0577
0578 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
0579 if (pmac_tb_clock_chip_host == NULL)
0580 continue;
0581 reg = of_get_property(cc, "reg", NULL);
0582 if (reg == NULL)
0583 continue;
0584 switch (*reg) {
0585 case 0xd2:
0586 if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) {
0587 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
0588 pmac_tb_pulsar_addr = 0xd2;
0589 name = "Pulsar";
0590 } else if (of_device_is_compatible(cc, "cy28508")) {
0591 pmac_tb_freeze = smp_core99_cypress_tb_freeze;
0592 name = "Cypress";
0593 }
0594 break;
0595 case 0xd4:
0596 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
0597 pmac_tb_pulsar_addr = 0xd4;
0598 name = "Pulsar";
0599 break;
0600 }
0601 if (pmac_tb_freeze != NULL)
0602 break;
0603 }
0604 if (pmac_tb_freeze != NULL) {
0605
0606 if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) {
0607 printk(KERN_ERR "Failed top open i2c bus for clock"
0608 " sync, fallback to software sync !\n");
0609 goto no_i2c_sync;
0610 }
0611 printk(KERN_INFO "Processor timebase sync using %s i2c clock\n",
0612 name);
0613 return;
0614 }
0615 no_i2c_sync:
0616 pmac_tb_freeze = NULL;
0617 pmac_tb_clock_chip_host = NULL;
0618 }
0619
0620
0621
0622
0623
0624
0625
0626 static void smp_core99_pfunc_tb_freeze(int freeze)
0627 {
0628 struct device_node *cpus;
0629 struct pmf_args args;
0630
0631 cpus = of_find_node_by_path("/cpus");
0632 BUG_ON(cpus == NULL);
0633 args.count = 1;
0634 args.u[0].v = !freeze;
0635 pmf_call_function(cpus, "cpu-timebase", &args);
0636 of_node_put(cpus);
0637 }
0638
0639 #else
0640
0641
0642
0643
0644
0645 static unsigned int core99_tb_gpio;
0646
0647 static void smp_core99_gpio_tb_freeze(int freeze)
0648 {
0649 if (freeze)
0650 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
0651 else
0652 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
0653 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
0654 }
0655
0656
0657 #endif
0658
0659 static void core99_init_caches(int cpu)
0660 {
0661 #ifndef CONFIG_PPC64
0662
0663 static long int core99_l2_cache;
0664 static long int core99_l3_cache;
0665
0666 if (!cpu_has_feature(CPU_FTR_L2CR))
0667 return;
0668
0669 if (cpu == 0) {
0670 core99_l2_cache = _get_L2CR();
0671 printk("CPU0: L2CR is %lx\n", core99_l2_cache);
0672 } else {
0673 printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
0674 _set_L2CR(0);
0675 _set_L2CR(core99_l2_cache);
0676 printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
0677 }
0678
0679 if (!cpu_has_feature(CPU_FTR_L3CR))
0680 return;
0681
0682 if (cpu == 0){
0683 core99_l3_cache = _get_L3CR();
0684 printk("CPU0: L3CR is %lx\n", core99_l3_cache);
0685 } else {
0686 printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
0687 _set_L3CR(0);
0688 _set_L3CR(core99_l3_cache);
0689 printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
0690 }
0691 #endif
0692 }
0693
0694 static void __init smp_core99_setup(int ncpus)
0695 {
0696 #ifdef CONFIG_PPC64
0697
0698
0699 if (of_machine_is_compatible("PowerMac7,2") ||
0700 of_machine_is_compatible("PowerMac7,3") ||
0701 of_machine_is_compatible("RackMac3,1"))
0702 smp_core99_setup_i2c_hwsync(ncpus);
0703
0704
0705 if (pmac_tb_freeze == NULL) {
0706 struct device_node *cpus =
0707 of_find_node_by_path("/cpus");
0708 if (cpus &&
0709 of_get_property(cpus, "platform-cpu-timebase", NULL)) {
0710 pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
0711 printk(KERN_INFO "Processor timebase sync using"
0712 " platform function\n");
0713 }
0714 }
0715
0716 #else
0717
0718
0719 if (pmac_tb_freeze == NULL && !of_machine_is_compatible("MacRISC4")) {
0720 struct device_node *cpu;
0721 const u32 *tbprop = NULL;
0722
0723 core99_tb_gpio = KL_GPIO_TB_ENABLE;
0724 cpu = of_find_node_by_type(NULL, "cpu");
0725 if (cpu != NULL) {
0726 tbprop = of_get_property(cpu, "timebase-enable", NULL);
0727 if (tbprop)
0728 core99_tb_gpio = *tbprop;
0729 of_node_put(cpu);
0730 }
0731 pmac_tb_freeze = smp_core99_gpio_tb_freeze;
0732 printk(KERN_INFO "Processor timebase sync using"
0733 " GPIO 0x%02x\n", core99_tb_gpio);
0734 }
0735
0736 #endif
0737
0738
0739 if (pmac_tb_freeze == NULL) {
0740 smp_ops->give_timebase = smp_generic_give_timebase;
0741 smp_ops->take_timebase = smp_generic_take_timebase;
0742 printk(KERN_INFO "Processor timebase sync using software\n");
0743 }
0744
0745 #ifndef CONFIG_PPC64
0746 {
0747 int i;
0748
0749
0750 for (i = 1; i < ncpus; ++i)
0751 set_hard_smp_processor_id(i, i);
0752 }
0753 #endif
0754
0755
0756 if (!of_machine_is_compatible("MacRISC4"))
0757 powersave_nap = 0;
0758 }
0759
0760 static void __init smp_core99_probe(void)
0761 {
0762 struct device_node *cpus;
0763 int ncpus = 0;
0764
0765 if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
0766
0767
0768 for_each_node_by_type(cpus, "cpu")
0769 ++ncpus;
0770
0771 printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
0772
0773
0774 if (ncpus <= 1)
0775 return;
0776
0777
0778
0779
0780 pmac_pfunc_base_install();
0781 pmac_i2c_init();
0782
0783
0784 smp_core99_setup(ncpus);
0785
0786
0787 mpic_request_ipis();
0788
0789
0790 core99_init_caches(0);
0791 }
0792
0793 static int smp_core99_kick_cpu(int nr)
0794 {
0795 unsigned int save_vector;
0796 unsigned long target, flags;
0797 unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
0798
0799 if (nr < 0 || nr > 3)
0800 return -ENOENT;
0801
0802 if (ppc_md.progress)
0803 ppc_md.progress("smp_core99_kick_cpu", 0x346);
0804
0805 local_irq_save(flags);
0806
0807
0808 save_vector = *vector;
0809
0810
0811
0812
0813 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
0814 patch_branch(vector, target, BRANCH_SET_LINK);
0815
0816
0817 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
0818
0819
0820
0821
0822
0823
0824 mdelay(1);
0825
0826
0827 patch_instruction(vector, ppc_inst(save_vector));
0828
0829 local_irq_restore(flags);
0830 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
0831
0832 return 0;
0833 }
0834
0835 static void smp_core99_setup_cpu(int cpu_nr)
0836 {
0837
0838 if (cpu_nr != 0)
0839 core99_init_caches(cpu_nr);
0840
0841
0842 mpic_setup_this_cpu();
0843 }
0844
0845 #ifdef CONFIG_PPC64
0846 #ifdef CONFIG_HOTPLUG_CPU
0847 static unsigned int smp_core99_host_open;
0848
0849 static int smp_core99_cpu_prepare(unsigned int cpu)
0850 {
0851 int rc;
0852
0853
0854 if (pmac_tb_clock_chip_host && !smp_core99_host_open) {
0855 rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
0856 if (rc) {
0857 pr_err("Failed to open i2c bus for time sync\n");
0858 return notifier_from_errno(rc);
0859 }
0860 smp_core99_host_open = 1;
0861 }
0862 return 0;
0863 }
0864
0865 static int smp_core99_cpu_online(unsigned int cpu)
0866 {
0867
0868 if (pmac_tb_clock_chip_host && smp_core99_host_open) {
0869 pmac_i2c_close(pmac_tb_clock_chip_host);
0870 smp_core99_host_open = 0;
0871 }
0872 return 0;
0873 }
0874 #endif
0875
0876 static void __init smp_core99_bringup_done(void)
0877 {
0878
0879 if (pmac_tb_clock_chip_host)
0880 pmac_i2c_close(pmac_tb_clock_chip_host);
0881
0882
0883
0884
0885 if (of_machine_is_compatible("MacRISC4") &&
0886 num_online_cpus() < 2) {
0887 set_cpu_present(1, false);
0888 g5_phy_disable_cpu1();
0889 }
0890 #ifdef CONFIG_HOTPLUG_CPU
0891 cpuhp_setup_state_nocalls(CPUHP_POWERPC_PMAC_PREPARE,
0892 "powerpc/pmac:prepare", smp_core99_cpu_prepare,
0893 NULL);
0894 cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "powerpc/pmac:online",
0895 smp_core99_cpu_online, NULL);
0896 #endif
0897
0898 if (ppc_md.progress)
0899 ppc_md.progress("smp_core99_bringup_done", 0x349);
0900 }
0901 #endif
0902
0903 #ifdef CONFIG_HOTPLUG_CPU
0904
0905 static int smp_core99_cpu_disable(void)
0906 {
0907 int rc = generic_cpu_disable();
0908 if (rc)
0909 return rc;
0910
0911 mpic_cpu_set_priority(0xf);
0912
0913 cleanup_cpu_mmu_context();
0914
0915 return 0;
0916 }
0917
0918 #ifdef CONFIG_PPC32
0919
0920 static void pmac_cpu_offline_self(void)
0921 {
0922 int cpu = smp_processor_id();
0923
0924 local_irq_disable();
0925 idle_task_exit();
0926 pr_debug("CPU%d offline\n", cpu);
0927 generic_set_cpu_dead(cpu);
0928 smp_wmb();
0929 mb();
0930 low_cpu_offline_self();
0931 }
0932
0933 #else
0934
0935 static void pmac_cpu_offline_self(void)
0936 {
0937 int cpu = smp_processor_id();
0938
0939 local_irq_disable();
0940 idle_task_exit();
0941
0942
0943
0944
0945
0946
0947
0948 printk(KERN_INFO "CPU#%d offline\n", cpu);
0949 generic_set_cpu_dead(cpu);
0950 smp_wmb();
0951
0952
0953
0954
0955
0956
0957
0958
0959 local_irq_enable();
0960
0961 while (1) {
0962
0963 set_dec(0x7fffffff);
0964
0965
0966 power4_idle();
0967 }
0968 }
0969
0970 #endif
0971 #endif
0972
0973
0974 static struct smp_ops_t core99_smp_ops = {
0975 .message_pass = smp_mpic_message_pass,
0976 .probe = smp_core99_probe,
0977 #ifdef CONFIG_PPC64
0978 .bringup_done = smp_core99_bringup_done,
0979 #endif
0980 .kick_cpu = smp_core99_kick_cpu,
0981 .setup_cpu = smp_core99_setup_cpu,
0982 .give_timebase = smp_core99_give_timebase,
0983 .take_timebase = smp_core99_take_timebase,
0984 #if defined(CONFIG_HOTPLUG_CPU)
0985 .cpu_disable = smp_core99_cpu_disable,
0986 .cpu_die = generic_cpu_die,
0987 #endif
0988 };
0989
0990 void __init pmac_setup_smp(void)
0991 {
0992 struct device_node *np;
0993
0994
0995 np = of_find_node_by_name(NULL, "uni-n");
0996 if (!np)
0997 np = of_find_node_by_name(NULL, "u3");
0998 if (!np)
0999 np = of_find_node_by_name(NULL, "u4");
1000 if (np) {
1001 of_node_put(np);
1002 smp_ops = &core99_smp_ops;
1003 }
1004 #ifdef CONFIG_PPC_PMAC32_PSURGE
1005 else {
1006
1007
1008
1009
1010
1011 int cpu;
1012
1013 for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
1014 set_cpu_possible(cpu, true);
1015 smp_ops = &psurge_smp_ops;
1016 }
1017 #endif
1018
1019 #ifdef CONFIG_HOTPLUG_CPU
1020 smp_ops->cpu_offline_self = pmac_cpu_offline_self;
1021 #endif
1022 }
1023
1024