Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2006-2007 PA Semi, Inc
0004  *
0005  * Authors: Kip Walker, PA Semi
0006  *      Olof Johansson, PA Semi
0007  *
0008  * Maintained by: Olof Johansson <olof@lixom.net>
0009  *
0010  * Based on arch/powerpc/platforms/maple/setup.c
0011  */
0012 
0013 #include <linux/errno.h>
0014 #include <linux/kernel.h>
0015 #include <linux/delay.h>
0016 #include <linux/console.h>
0017 #include <linux/export.h>
0018 #include <linux/pci.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/gfp.h>
0021 #include <linux/irqdomain.h>
0022 
0023 #include <asm/iommu.h>
0024 #include <asm/machdep.h>
0025 #include <asm/i8259.h>
0026 #include <asm/mpic.h>
0027 #include <asm/smp.h>
0028 #include <asm/time.h>
0029 #include <asm/mmu.h>
0030 #include <asm/debug.h>
0031 
0032 #include <pcmcia/ss.h>
0033 #include <pcmcia/cistpl.h>
0034 #include <pcmcia/ds.h>
0035 
0036 #include "pasemi.h"
0037 
0038 /* SDC reset register, must be pre-mapped at reset time */
0039 static void __iomem *reset_reg;
0040 
0041 /* Various error status registers, must be pre-mapped at MCE time */
0042 
0043 #define MAX_MCE_REGS    32
0044 struct mce_regs {
0045     char *name;
0046     void __iomem *addr;
0047 };
0048 
0049 static struct mce_regs mce_regs[MAX_MCE_REGS];
0050 static int num_mce_regs;
0051 static int nmi_virq = 0;
0052 
0053 
0054 static void __noreturn pas_restart(char *cmd)
0055 {
0056     /* Need to put others cpu in hold loop so they're not sleeping */
0057     smp_send_stop();
0058     udelay(10000);
0059     printk("Restarting...\n");
0060     while (1)
0061         out_le32(reset_reg, 0x6000000);
0062 }
0063 
0064 #ifdef CONFIG_PPC_PASEMI_NEMO
0065 void pas_shutdown(void)
0066 {
0067     /* Set the PLD bit that makes the SB600 think the power button is being pressed */
0068     void __iomem *pld_map = ioremap(0xf5000000,4096);
0069     while (1)
0070         out_8(pld_map+7,0x01);
0071 }
0072 
0073 /* RTC platform device structure as is not in device tree */
0074 static struct resource rtc_resource[] = {{
0075     .name = "rtc",
0076     .start = 0x70,
0077     .end = 0x71,
0078     .flags = IORESOURCE_IO,
0079 }, {
0080     .name = "rtc",
0081     .start = 8,
0082     .end = 8,
0083     .flags = IORESOURCE_IRQ,
0084 }};
0085 
0086 static inline void nemo_init_rtc(void)
0087 {
0088     platform_device_register_simple("rtc_cmos", -1, rtc_resource, 2);
0089 }
0090 
0091 #else
0092 
0093 static inline void nemo_init_rtc(void)
0094 {
0095 }
0096 #endif
0097 
0098 #ifdef CONFIG_SMP
0099 static arch_spinlock_t timebase_lock;
0100 static unsigned long timebase;
0101 
0102 static void pas_give_timebase(void)
0103 {
0104     unsigned long flags;
0105 
0106     local_irq_save(flags);
0107     hard_irq_disable();
0108     arch_spin_lock(&timebase_lock);
0109     mtspr(SPRN_TBCTL, TBCTL_FREEZE);
0110     isync();
0111     timebase = get_tb();
0112     arch_spin_unlock(&timebase_lock);
0113 
0114     while (timebase)
0115         barrier();
0116     mtspr(SPRN_TBCTL, TBCTL_RESTART);
0117     local_irq_restore(flags);
0118 }
0119 
0120 static void pas_take_timebase(void)
0121 {
0122     while (!timebase)
0123         smp_rmb();
0124 
0125     arch_spin_lock(&timebase_lock);
0126     set_tb(timebase >> 32, timebase & 0xffffffff);
0127     timebase = 0;
0128     arch_spin_unlock(&timebase_lock);
0129 }
0130 
0131 static struct smp_ops_t pas_smp_ops = {
0132     .probe      = smp_mpic_probe,
0133     .message_pass   = smp_mpic_message_pass,
0134     .kick_cpu   = smp_generic_kick_cpu,
0135     .setup_cpu  = smp_mpic_setup_cpu,
0136     .give_timebase  = pas_give_timebase,
0137     .take_timebase  = pas_take_timebase,
0138 };
0139 #endif /* CONFIG_SMP */
0140 
0141 static void __init pas_setup_arch(void)
0142 {
0143 #ifdef CONFIG_SMP
0144     /* Setup SMP callback */
0145     smp_ops = &pas_smp_ops;
0146 #endif
0147 
0148     /* Remap SDC register for doing reset */
0149     /* XXXOJN This should maybe come out of the device tree */
0150     reset_reg = ioremap(0xfc101100, 4);
0151 }
0152 
0153 static int __init pas_setup_mce_regs(void)
0154 {
0155     struct pci_dev *dev;
0156     int reg;
0157 
0158     /* Remap various SoC status registers for use by the MCE handler */
0159 
0160     reg = 0;
0161 
0162     dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, NULL);
0163     while (dev && reg < MAX_MCE_REGS) {
0164         mce_regs[reg].name = kasprintf(GFP_KERNEL,
0165                         "mc%d_mcdebug_errsta", reg);
0166         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730);
0167         dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev);
0168         reg++;
0169     }
0170 
0171     dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
0172     if (dev && reg+4 < MAX_MCE_REGS) {
0173         mce_regs[reg].name = "iobdbg_IntStatus1";
0174         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x438);
0175         reg++;
0176         mce_regs[reg].name = "iobdbg_IOCTbusIntDbgReg";
0177         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x454);
0178         reg++;
0179         mce_regs[reg].name = "iobiom_IntStatus";
0180         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0xc10);
0181         reg++;
0182         mce_regs[reg].name = "iobiom_IntDbgReg";
0183         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0xc1c);
0184         reg++;
0185     }
0186 
0187     dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa009, NULL);
0188     if (dev && reg+2 < MAX_MCE_REGS) {
0189         mce_regs[reg].name = "l2csts_IntStatus";
0190         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x200);
0191         reg++;
0192         mce_regs[reg].name = "l2csts_Cnt";
0193         mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x214);
0194         reg++;
0195     }
0196 
0197     num_mce_regs = reg;
0198 
0199     return 0;
0200 }
0201 machine_device_initcall(pasemi, pas_setup_mce_regs);
0202 
0203 #ifdef CONFIG_PPC_PASEMI_NEMO
0204 static void sb600_8259_cascade(struct irq_desc *desc)
0205 {
0206     struct irq_chip *chip = irq_desc_get_chip(desc);
0207     unsigned int cascade_irq = i8259_irq();
0208 
0209     if (cascade_irq)
0210         generic_handle_irq(cascade_irq);
0211 
0212     chip->irq_eoi(&desc->irq_data);
0213 }
0214 
0215 static void __init nemo_init_IRQ(struct mpic *mpic)
0216 {
0217     struct device_node *np;
0218     int gpio_virq;
0219     /* Connect the SB600's legacy i8259 controller */
0220     np = of_find_node_by_path("/pxp@0,e0000000");
0221     i8259_init(np, 0);
0222     of_node_put(np);
0223 
0224     gpio_virq = irq_create_mapping(NULL, 3);
0225     irq_set_irq_type(gpio_virq, IRQ_TYPE_LEVEL_HIGH);
0226     irq_set_chained_handler(gpio_virq, sb600_8259_cascade);
0227     mpic_unmask_irq(irq_get_irq_data(gpio_virq));
0228 
0229     irq_set_default_host(mpic->irqhost);
0230 }
0231 
0232 #else
0233 
0234 static inline void nemo_init_IRQ(struct mpic *mpic)
0235 {
0236 }
0237 #endif
0238 
0239 static __init void pas_init_IRQ(void)
0240 {
0241     struct device_node *np;
0242     struct device_node *root, *mpic_node;
0243     unsigned long openpic_addr;
0244     const unsigned int *opprop;
0245     int naddr, opplen;
0246     int mpic_flags;
0247     const unsigned int *nmiprop;
0248     struct mpic *mpic;
0249 
0250     mpic_node = NULL;
0251 
0252     for_each_node_by_type(np, "interrupt-controller")
0253         if (of_device_is_compatible(np, "open-pic")) {
0254             mpic_node = np;
0255             break;
0256         }
0257     if (!mpic_node)
0258         for_each_node_by_type(np, "open-pic") {
0259             mpic_node = np;
0260             break;
0261         }
0262     if (!mpic_node) {
0263         pr_err("Failed to locate the MPIC interrupt controller\n");
0264         return;
0265     }
0266 
0267     /* Find address list in /platform-open-pic */
0268     root = of_find_node_by_path("/");
0269     naddr = of_n_addr_cells(root);
0270     opprop = of_get_property(root, "platform-open-pic", &opplen);
0271     if (!opprop) {
0272         pr_err("No platform-open-pic property.\n");
0273         of_node_put(root);
0274         return;
0275     }
0276     openpic_addr = of_read_number(opprop, naddr);
0277     pr_debug("OpenPIC addr: %lx\n", openpic_addr);
0278 
0279     mpic_flags = MPIC_LARGE_VECTORS | MPIC_NO_BIAS | MPIC_NO_RESET;
0280 
0281     nmiprop = of_get_property(mpic_node, "nmi-source", NULL);
0282     if (nmiprop)
0283         mpic_flags |= MPIC_ENABLE_MCK;
0284 
0285     mpic = mpic_alloc(mpic_node, openpic_addr,
0286               mpic_flags, 0, 0, "PASEMI-OPIC");
0287     BUG_ON(!mpic);
0288 
0289     mpic_assign_isu(mpic, 0, mpic->paddr + 0x10000);
0290     mpic_init(mpic);
0291     /* The NMI/MCK source needs to be prio 15 */
0292     if (nmiprop) {
0293         nmi_virq = irq_create_mapping(NULL, *nmiprop);
0294         mpic_irq_set_priority(nmi_virq, 15);
0295         irq_set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
0296         mpic_unmask_irq(irq_get_irq_data(nmi_virq));
0297     }
0298 
0299     nemo_init_IRQ(mpic);
0300 
0301     of_node_put(mpic_node);
0302     of_node_put(root);
0303 }
0304 
0305 static void __init pas_progress(char *s, unsigned short hex)
0306 {
0307     printk("[%04x] : %s\n", hex, s ? s : "");
0308 }
0309 
0310 
0311 static int pas_machine_check_handler(struct pt_regs *regs)
0312 {
0313     int cpu = smp_processor_id();
0314     unsigned long srr0, srr1, dsisr;
0315     int dump_slb = 0;
0316     int i;
0317 
0318     srr0 = regs->nip;
0319     srr1 = regs->msr;
0320 
0321     if (nmi_virq && mpic_get_mcirq() == nmi_virq) {
0322         pr_err("NMI delivered\n");
0323         debugger(regs);
0324         mpic_end_irq(irq_get_irq_data(nmi_virq));
0325         goto out;
0326     }
0327 
0328     dsisr = mfspr(SPRN_DSISR);
0329     pr_err("Machine Check on CPU %d\n", cpu);
0330     pr_err("SRR0  0x%016lx SRR1 0x%016lx\n", srr0, srr1);
0331     pr_err("DSISR 0x%016lx DAR  0x%016lx\n", dsisr, regs->dar);
0332     pr_err("BER   0x%016lx MER  0x%016lx\n", mfspr(SPRN_PA6T_BER),
0333         mfspr(SPRN_PA6T_MER));
0334     pr_err("IER   0x%016lx DER  0x%016lx\n", mfspr(SPRN_PA6T_IER),
0335         mfspr(SPRN_PA6T_DER));
0336     pr_err("Cause:\n");
0337 
0338     if (srr1 & 0x200000)
0339         pr_err("Signalled by SDC\n");
0340 
0341     if (srr1 & 0x100000) {
0342         pr_err("Load/Store detected error:\n");
0343         if (dsisr & 0x8000)
0344             pr_err("D-cache ECC double-bit error or bus error\n");
0345         if (dsisr & 0x4000)
0346             pr_err("LSU snoop response error\n");
0347         if (dsisr & 0x2000) {
0348             pr_err("MMU SLB multi-hit or invalid B field\n");
0349             dump_slb = 1;
0350         }
0351         if (dsisr & 0x1000)
0352             pr_err("Recoverable Duptags\n");
0353         if (dsisr & 0x800)
0354             pr_err("Recoverable D-cache parity error count overflow\n");
0355         if (dsisr & 0x400)
0356             pr_err("TLB parity error count overflow\n");
0357     }
0358 
0359     if (srr1 & 0x80000)
0360         pr_err("Bus Error\n");
0361 
0362     if (srr1 & 0x40000) {
0363         pr_err("I-side SLB multiple hit\n");
0364         dump_slb = 1;
0365     }
0366 
0367     if (srr1 & 0x20000)
0368         pr_err("I-cache parity error hit\n");
0369 
0370     if (num_mce_regs == 0)
0371         pr_err("No MCE registers mapped yet, can't dump\n");
0372     else
0373         pr_err("SoC debug registers:\n");
0374 
0375     for (i = 0; i < num_mce_regs; i++)
0376         pr_err("%s: 0x%08x\n", mce_regs[i].name,
0377             in_le32(mce_regs[i].addr));
0378 
0379     if (dump_slb) {
0380         unsigned long e, v;
0381         int i;
0382 
0383         pr_err("slb contents:\n");
0384         for (i = 0; i < mmu_slb_size; i++) {
0385             asm volatile("slbmfee  %0,%1" : "=r" (e) : "r" (i));
0386             asm volatile("slbmfev  %0,%1" : "=r" (v) : "r" (i));
0387             pr_err("%02d %016lx %016lx\n", i, e, v);
0388         }
0389     }
0390 
0391 out:
0392     /* SRR1[62] is from MSR[62] if recoverable, so pass that back */
0393     return !!(srr1 & 0x2);
0394 }
0395 
0396 static const struct of_device_id pasemi_bus_ids[] = {
0397     /* Unfortunately needed for legacy firmwares */
0398     { .type = "localbus", },
0399     { .type = "sdc", },
0400     /* These are the proper entries, which newer firmware uses */
0401     { .compatible = "pasemi,localbus", },
0402     { .compatible = "pasemi,sdc", },
0403     {},
0404 };
0405 
0406 static int __init pasemi_publish_devices(void)
0407 {
0408     /* Publish OF platform devices for SDC and other non-PCI devices */
0409     of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
0410 
0411     nemo_init_rtc();
0412 
0413     return 0;
0414 }
0415 machine_device_initcall(pasemi, pasemi_publish_devices);
0416 
0417 
0418 /*
0419  * Called very early, MMU is off, device-tree isn't unflattened
0420  */
0421 static int __init pas_probe(void)
0422 {
0423     if (!of_machine_is_compatible("PA6T-1682M") &&
0424         !of_machine_is_compatible("pasemi,pwrficient"))
0425         return 0;
0426 
0427 #ifdef CONFIG_PPC_PASEMI_NEMO
0428     /*
0429      * Check for the Nemo motherboard here, if we are running on one
0430      * change the machine definition to fit
0431      */
0432     if (of_machine_is_compatible("pasemi,nemo")) {
0433         pm_power_off        = pas_shutdown;
0434         ppc_md.name     = "A-EON Amigaone X1000";
0435     }
0436 #endif
0437 
0438     iommu_init_early_pasemi();
0439 
0440     return 1;
0441 }
0442 
0443 define_machine(pasemi) {
0444     .name           = "PA Semi PWRficient",
0445     .probe          = pas_probe,
0446     .setup_arch     = pas_setup_arch,
0447     .discover_phbs      = pas_pci_init,
0448     .init_IRQ       = pas_init_IRQ,
0449     .get_irq        = mpic_get_irq,
0450     .restart        = pas_restart,
0451     .get_boot_time      = pas_get_boot_time,
0452     .calibrate_decr     = generic_calibrate_decr,
0453     .progress       = pas_progress,
0454     .machine_check_exception = pas_machine_check_handler,
0455 };