Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * SMP support for power macintosh.
0004  *
0005  * We support both the old "powersurge" SMP architecture
0006  * and the current Core99 (G4 PowerMac) machines.
0007  *
0008  * Note that we don't support the very first rev. of
0009  * Apple/DayStar 2 CPUs board, the one with the funky
0010  * watchdog. Hopefully, none of these should be there except
0011  * maybe internally to Apple. I should probably still add some
0012  * code to detect this card though and disable SMP. --BenH.
0013  *
0014  * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
0015  * and Ben Herrenschmidt <benh@kernel.crashing.org>.
0016  *
0017  * Support for DayStar quad CPU cards
0018  * Copyright (C) XLR8, Inc. 1994-2000
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  * Powersurge (old powermac SMP) support.
0074  */
0075 
0076 /* Addresses for powersurge registers */
0077 #define HAMMERHEAD_BASE     0xf8000000
0078 #define HHEAD_CONFIG        0x90
0079 #define HHEAD_SEC_INTR      0xc0
0080 
0081 /* register for interrupting the primary processor on the powersurge */
0082 /* N.B. this is actually the ethernet ROM! */
0083 #define PSURGE_PRI_INTR     0xf3019000
0084 
0085 /* register for storing the start address for the secondary processor */
0086 /* N.B. this is the PCI config space address register for the 1st bridge */
0087 #define PSURGE_START        0xf2800000
0088 
0089 /* Daystar/XLR8 4-CPU card */
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 /* virtual addresses for the above */
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 /* values for psurge_type */
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 /* what sort of powersurge board we have */
0122 static int psurge_type = PSURGE_NONE;
0123 
0124 /* irq for secondary cpus to report */
0125 static struct irq_domain *psurge_host;
0126 int psurge_secondary_virq;
0127 
0128 /*
0129  * Set and clear IPIs for powersurge.
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  * On powersurge (old SMP powermac architecture) we don't have
0160  * separate IPIs for separate messages like openpic does.  Instead
0161  * use the generic demux helpers
0162  *  -- paulus.
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  * Determine a quad card presence. We read the board ID register, we
0210  * force the data bus to change to something else, and we read it again.
0211  * It it's stable, then the register probably exist (ugh !)
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     /* looks OK, try a slightly more rigorous test */
0224     /* bogus is not necessarily cacheline-aligned,
0225        though I don't suppose that really matters.  -- paulus */
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      * The powersurge cpu board can be used in the generation
0276      * of powermacs that have a socket for an upgradeable cpu card,
0277      * including the 7500, 8500, 9500, 9600.
0278      * The device tree doesn't tell you if you have 2 cpus because
0279      * OF doesn't know anything about the 2nd processor.
0280      * Instead we look for magic bits in magic registers,
0281      * in the hammerhead memory controller in the case of the
0282      * dual-cpu powersurge board.  -- paulus.
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         /* All released cards using this HW design have 4 CPUs */
0297         ncpus = 4;
0298         /* No sure how timebase sync works on those, let's use SW */
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             /* not a dual-cpu card */
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     /* This is necessary because OF doesn't know about the
0319      * secondary cpu(s), and thus there aren't nodes in the
0320      * device tree for them, and smp_setup_cpu_maps hasn't
0321      * set their bits in cpu_present_mask.
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     /* Defining this here is evil ... but I prefer hiding that
0338      * crap to avoid giving people ideas that they can do the
0339      * same.
0340      */
0341     extern volatile unsigned int cpu_callin_map[NR_CPUS];
0342 
0343     /* may need to flush here if secondary bats aren't setup */
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     /* This is going to freeze the timeebase, we disable interrupts */
0351     local_irq_save(flags);
0352 
0353     out_be32(psurge_start, start);
0354     mb();
0355 
0356     psurge_set_ipi(nr);
0357 
0358     /*
0359      * We can't use udelay here because the timebase is now frozen.
0360      */
0361     for (i = 0; i < 2000; ++i)
0362         asm volatile("nop" : : : "memory");
0363     psurge_clr_ipi(nr);
0364 
0365     /*
0366      * Also, because the timebase is frozen, we must not return to the
0367      * caller which will try to do udelay's etc... Instead, we wait -here-
0368      * for the CPU to callin.
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     /* And we do the TB sync here too for standard dual CPU cards */
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     /* now interrupt the secondary, restarting both TBs */
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     /* reset the entry point so if we get another intr we won't
0409      * try to startup again */
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     /* Nothing to do here */
0435 }
0436 
0437 /* PowerSurge-style Macs */
0438 struct smp_ops_t psurge_smp_ops = {
0439     .message_pass   = NULL, /* Use smp_muxed_ipi_message_pass */
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 /* CONFIG_PPC_PMAC32_PSURGE */
0449 
0450 /*
0451  * Core 99 and later support
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  * G5s enable/disable the timebase via an i2c-connected clock chip.
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     /* Strangely, the device-tree says address is 0xd2, but darwin
0509      * accesses 0xd0 ...
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     /* Look for the clock chip */
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         /* Open i2c bus for synchronous access */
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  * Newer G5s uses a platform function
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 /* CONFIG_PPC64 */
0640 
0641 /*
0642  * SMP G4 use a GPIO to enable/disable the timebase.
0643  */
0644 
0645 static unsigned int core99_tb_gpio; /* Timebase freeze 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 /* !CONFIG_PPC64 */
0658 
0659 static void core99_init_caches(int cpu)
0660 {
0661 #ifndef CONFIG_PPC64
0662     /* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
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 /* !CONFIG_PPC64 */
0692 }
0693 
0694 static void __init smp_core99_setup(int ncpus)
0695 {
0696 #ifdef CONFIG_PPC64
0697 
0698     /* i2c based HW sync on some G5s */
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     /* pfunc based HW sync on recent G5s */
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 /* CONFIG_PPC64 */
0717 
0718     /* GPIO based HW sync on ppc32 Core99 */
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; /* default value */
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 /* CONFIG_PPC64 */
0737 
0738     /* No timebase sync, fallback to software */
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         /* XXX should get this from reg properties */
0750         for (i = 1; i < ncpus; ++i)
0751             set_hard_smp_processor_id(i, i);
0752     }
0753 #endif
0754 
0755     /* 32 bits SMP can't NAP */
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     /* Count CPUs in the device-tree */
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     /* Nothing more to do if less than 2 of them */
0774     if (ncpus <= 1)
0775         return;
0776 
0777     /* We need to perform some early initialisations before we can start
0778      * setting up SMP as we are running before initcalls
0779      */
0780     pmac_pfunc_base_install();
0781     pmac_i2c_init();
0782 
0783     /* Setup various bits like timebase sync method, ability to nap, ... */
0784     smp_core99_setup(ncpus);
0785 
0786     /* Install IPIs */
0787     mpic_request_ipis();
0788 
0789     /* Collect l2cr and l3cr values from CPU 0 */
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     /* Save reset vector */
0808     save_vector = *vector;
0809 
0810     /* Setup fake reset vector that does
0811      *   b __secondary_start_pmac_0 + nr*8
0812      */
0813     target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
0814     patch_branch(vector, target, BRANCH_SET_LINK);
0815 
0816     /* Put some life in our friend */
0817     pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
0818 
0819     /* FIXME: We wait a bit for the CPU to take the exception, I should
0820      * instead wait for the entry code to set something for me. Well,
0821      * ideally, all that crap will be done in prom.c and the CPU left
0822      * in a RAM-based wait loop like CHRP.
0823      */
0824     mdelay(1);
0825 
0826     /* Restore our exception vector */
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     /* Setup L2/L3 */
0838     if (cpu_nr != 0)
0839         core99_init_caches(cpu_nr);
0840 
0841     /* Setup openpic */
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     /* Open i2c bus if it was used for tb sync */
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     /* Close i2c bus if it was used for tb sync */
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 /* CONFIG_HOTPLUG_CPU */
0875 
0876 static void __init smp_core99_bringup_done(void)
0877 {
0878     /* Close i2c bus if it was used for tb sync */
0879     if (pmac_tb_clock_chip_host)
0880         pmac_i2c_close(pmac_tb_clock_chip_host);
0881 
0882     /* If we didn't start the second CPU, we must take
0883      * it off the bus.
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 /* CONFIG_PPC64 */
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 /* CONFIG_PPC32 */
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      * turn off as much as possible, we'll be
0944      * kicked out as this will only be invoked
0945      * on core99 platforms for now ...
0946      */
0947 
0948     printk(KERN_INFO "CPU#%d offline\n", cpu);
0949     generic_set_cpu_dead(cpu);
0950     smp_wmb();
0951 
0952     /*
0953      * Re-enable interrupts. The NAP code needs to enable them
0954      * anyways, do it now so we deal with the case where one already
0955      * happened while soft-disabled.
0956      * We shouldn't get any external interrupts, only decrementer, and the
0957      * decrementer handler is safe for use on offline CPUs
0958      */
0959     local_irq_enable();
0960 
0961     while (1) {
0962         /* let's not take timer interrupts too often ... */
0963         set_dec(0x7fffffff);
0964 
0965         /* Enter NAP mode */
0966         power4_idle();
0967     }
0968 }
0969 
0970 #endif /* else CONFIG_PPC32 */
0971 #endif /* CONFIG_HOTPLUG_CPU */
0972 
0973 /* Core99 Macs (dual G4s and G5s) */
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     /* Check for Core99 */
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         /* We have to set bits in cpu_possible_mask here since the
1007          * secondary CPU(s) aren't in the device tree. Various
1008          * things won't be initialized for CPUs not in the possible
1009          * map, so we really need to fix it up here.
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 /* CONFIG_PPC_PMAC32_PSURGE */
1018 
1019 #ifdef CONFIG_HOTPLUG_CPU
1020     smp_ops->cpu_offline_self = pmac_cpu_offline_self;
1021 #endif
1022 }
1023 
1024