linux/arch/powerpc/platforms/85xx/mpc85xx_cds.c
<<
>>
Prefs
   1/*
   2 * MPC85xx setup and early boot code plus other random bits.
   3 *
   4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
   5 *
   6 * Copyright 2005 Freescale Semiconductor Inc.
   7 *
   8 * This program is free software; you can redistribute  it and/or modify it
   9 * under  the terms of  the GNU General  Public License as published by the
  10 * Free Software Foundation;  either version 2 of the  License, or (at your
  11 * option) any later version.
  12 */
  13
  14#include <linux/stddef.h>
  15#include <linux/kernel.h>
  16#include <linux/init.h>
  17#include <linux/errno.h>
  18#include <linux/reboot.h>
  19#include <linux/pci.h>
  20#include <linux/kdev_t.h>
  21#include <linux/major.h>
  22#include <linux/console.h>
  23#include <linux/delay.h>
  24#include <linux/seq_file.h>
  25#include <linux/initrd.h>
  26#include <linux/module.h>
  27#include <linux/interrupt.h>
  28#include <linux/fsl_devices.h>
  29#include <linux/of_platform.h>
  30
  31#include <asm/system.h>
  32#include <asm/pgtable.h>
  33#include <asm/page.h>
  34#include <asm/atomic.h>
  35#include <asm/time.h>
  36#include <asm/io.h>
  37#include <asm/machdep.h>
  38#include <asm/ipic.h>
  39#include <asm/pci-bridge.h>
  40#include <asm/irq.h>
  41#include <mm/mmu_decl.h>
  42#include <asm/prom.h>
  43#include <asm/udbg.h>
  44#include <asm/mpic.h>
  45#include <asm/i8259.h>
  46
  47#include <sysdev/fsl_soc.h>
  48#include <sysdev/fsl_pci.h>
  49
  50/* CADMUS info */
  51/* xxx - galak, move into device tree */
  52#define CADMUS_BASE (0xf8004000)
  53#define CADMUS_SIZE (256)
  54#define CM_VER  (0)
  55#define CM_CSR  (1)
  56#define CM_RST  (2)
  57
  58
  59static int cds_pci_slot = 2;
  60static volatile u8 *cadmus;
  61
  62#ifdef CONFIG_PCI
  63
  64#define ARCADIA_HOST_BRIDGE_IDSEL       17
  65#define ARCADIA_2ND_BRIDGE_IDSEL        3
  66
  67static int mpc85xx_exclude_device(struct pci_controller *hose,
  68                                  u_char bus, u_char devfn)
  69{
  70        /* We explicitly do not go past the Tundra 320 Bridge */
  71        if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
  72                return PCIBIOS_DEVICE_NOT_FOUND;
  73        if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
  74                return PCIBIOS_DEVICE_NOT_FOUND;
  75        else
  76                return PCIBIOS_SUCCESSFUL;
  77}
  78
  79static void mpc85xx_cds_restart(char *cmd)
  80{
  81        struct pci_dev *dev;
  82        u_char tmp;
  83
  84        if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
  85                                        NULL))) {
  86
  87                /* Use the VIA Super Southbridge to force a PCI reset */
  88                pci_read_config_byte(dev, 0x47, &tmp);
  89                pci_write_config_byte(dev, 0x47, tmp | 1);
  90
  91                /* Flush the outbound PCI write queues */
  92                pci_read_config_byte(dev, 0x47, &tmp);
  93
  94                /*
  95                 *  At this point, the harware reset should have triggered.
  96                 *  However, if it doesn't work for some mysterious reason,
  97                 *  just fall through to the default reset below.
  98                 */
  99
 100                pci_dev_put(dev);
 101        }
 102
 103        /*
 104         *  If we can't find the VIA chip (maybe the P2P bridge is disabled)
 105         *  or the VIA chip reset didn't work, just use the default reset.
 106         */
 107        fsl_rstcr_restart(NULL);
 108}
 109
 110static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
 111{
 112        u_char c;
 113        if (dev->vendor == PCI_VENDOR_ID_VIA) {
 114                switch (dev->device) {
 115                case PCI_DEVICE_ID_VIA_82C586_1:
 116                        /*
 117                         * U-Boot does not set the enable bits
 118                         * for the IDE device. Force them on here.
 119                         */
 120                        pci_read_config_byte(dev, 0x40, &c);
 121                        c |= 0x03; /* IDE: Chip Enable Bits */
 122                        pci_write_config_byte(dev, 0x40, c);
 123
 124                        /*
 125                         * Since only primary interface works, force the
 126                         * IDE function to standard primary IDE interrupt
 127                         * w/ 8259 offset
 128                         */
 129                        dev->irq = 14;
 130                        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 131                        break;
 132                /*
 133                 * Force legacy USB interrupt routing
 134                 */
 135                case PCI_DEVICE_ID_VIA_82C586_2:
 136                /* There are two USB controllers.
 137                 * Identify them by functon number
 138                 */
 139                        if (PCI_FUNC(dev->devfn) == 3)
 140                                dev->irq = 11;
 141                        else
 142                                dev->irq = 10;
 143                        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 144                default:
 145                        break;
 146                }
 147        }
 148}
 149
 150static void __devinit skip_fake_bridge(struct pci_dev *dev)
 151{
 152        /* Make it an error to skip the fake bridge
 153         * in pci_setup_device() in probe.c */
 154        dev->hdr_type = 0x7f;
 155}
 156DECLARE_PCI_FIXUP_EARLY(0x1957, 0x3fff, skip_fake_bridge);
 157DECLARE_PCI_FIXUP_EARLY(0x3fff, 0x1957, skip_fake_bridge);
 158DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge);
 159
 160#ifdef CONFIG_PPC_I8259
 161static void mpc85xx_8259_cascade_handler(unsigned int irq,
 162                                         struct irq_desc *desc)
 163{
 164        unsigned int cascade_irq = i8259_irq();
 165
 166        if (cascade_irq != NO_IRQ)
 167                /* handle an interrupt from the 8259 */
 168                generic_handle_irq(cascade_irq);
 169
 170        /* check for any interrupts from the shared IRQ line */
 171        handle_fasteoi_irq(irq, desc);
 172}
 173
 174static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id)
 175{
 176        return IRQ_HANDLED;
 177}
 178
 179static struct irqaction mpc85xxcds_8259_irqaction = {
 180        .handler = mpc85xx_8259_cascade_action,
 181        .flags = IRQF_SHARED,
 182        .name = "8259 cascade",
 183};
 184#endif /* PPC_I8259 */
 185#endif /* CONFIG_PCI */
 186
 187static void __init mpc85xx_cds_pic_init(void)
 188{
 189        struct mpic *mpic;
 190        struct resource r;
 191        struct device_node *np = NULL;
 192
 193        np = of_find_node_by_type(np, "open-pic");
 194
 195        if (np == NULL) {
 196                printk(KERN_ERR "Could not find open-pic node\n");
 197                return;
 198        }
 199
 200        if (of_address_to_resource(np, 0, &r)) {
 201                printk(KERN_ERR "Failed to map mpic register space\n");
 202                of_node_put(np);
 203                return;
 204        }
 205
 206        mpic = mpic_alloc(np, r.start,
 207                        MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
 208                        0, 256, " OpenPIC  ");
 209        BUG_ON(mpic == NULL);
 210
 211        /* Return the mpic node */
 212        of_node_put(np);
 213
 214        mpic_init(mpic);
 215}
 216
 217#if defined(CONFIG_PPC_I8259) && defined(CONFIG_PCI)
 218static int mpc85xx_cds_8259_attach(void)
 219{
 220        int ret;
 221        struct device_node *np = NULL;
 222        struct device_node *cascade_node = NULL;
 223        int cascade_irq;
 224
 225        /* Initialize the i8259 controller */
 226        for_each_node_by_type(np, "interrupt-controller")
 227                if (of_device_is_compatible(np, "chrp,iic")) {
 228                        cascade_node = np;
 229                        break;
 230                }
 231
 232        if (cascade_node == NULL) {
 233                printk(KERN_DEBUG "Could not find i8259 PIC\n");
 234                return -ENODEV;
 235        }
 236
 237        cascade_irq = irq_of_parse_and_map(cascade_node, 0);
 238        if (cascade_irq == NO_IRQ) {
 239                printk(KERN_ERR "Failed to map cascade interrupt\n");
 240                return -ENXIO;
 241        }
 242
 243        i8259_init(cascade_node, 0);
 244        of_node_put(cascade_node);
 245
 246        /*
 247         *  Hook the interrupt to make sure desc->action is never NULL.
 248         *  This is required to ensure that the interrupt does not get
 249         *  disabled when the last user of the shared IRQ line frees their
 250         *  interrupt.
 251         */
 252        if ((ret = setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction))) {
 253                printk(KERN_ERR "Failed to setup cascade interrupt\n");
 254                return ret;
 255        }
 256
 257        /* Success. Connect our low-level cascade handler. */
 258        set_irq_handler(cascade_irq, mpc85xx_8259_cascade_handler);
 259
 260        return 0;
 261}
 262machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach);
 263
 264#endif /* CONFIG_PPC_I8259 */
 265
 266/*
 267 * Setup the architecture
 268 */
 269static void __init mpc85xx_cds_setup_arch(void)
 270{
 271#ifdef CONFIG_PCI
 272        struct device_node *np;
 273#endif
 274
 275        if (ppc_md.progress)
 276                ppc_md.progress("mpc85xx_cds_setup_arch()", 0);
 277
 278        cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE);
 279        cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1;
 280
 281        if (ppc_md.progress) {
 282                char buf[40];
 283                snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n",
 284                                cadmus[CM_VER], cds_pci_slot);
 285                ppc_md.progress(buf, 0);
 286        }
 287
 288#ifdef CONFIG_PCI
 289        for_each_node_by_type(np, "pci") {
 290                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
 291                    of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
 292                        struct resource rsrc;
 293                        of_address_to_resource(np, 0, &rsrc);
 294                        if ((rsrc.start & 0xfffff) == 0x8000)
 295                                fsl_add_bridge(np, 1);
 296                        else
 297                                fsl_add_bridge(np, 0);
 298                }
 299        }
 300
 301        ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup;
 302        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 303#endif
 304}
 305
 306static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
 307{
 308        uint pvid, svid, phid1;
 309
 310        pvid = mfspr(SPRN_PVR);
 311        svid = mfspr(SPRN_SVR);
 312
 313        seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
 314        seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]);
 315        seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
 316        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 317
 318        /* Display cpu Pll setting */
 319        phid1 = mfspr(SPRN_HID1);
 320        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
 321}
 322
 323
 324/*
 325 * Called very early, device-tree isn't unflattened
 326 */
 327static int __init mpc85xx_cds_probe(void)
 328{
 329        unsigned long root = of_get_flat_dt_root();
 330
 331        return of_flat_dt_is_compatible(root, "MPC85xxCDS");
 332}
 333
 334static struct of_device_id __initdata of_bus_ids[] = {
 335        { .type = "soc", },
 336        { .compatible = "soc", },
 337        { .compatible = "simple-bus", },
 338        { .compatible = "gianfar", },
 339        {},
 340};
 341
 342static int __init declare_of_platform_devices(void)
 343{
 344        return of_platform_bus_probe(NULL, of_bus_ids, NULL);
 345}
 346machine_device_initcall(mpc85xx_cds, declare_of_platform_devices);
 347
 348define_machine(mpc85xx_cds) {
 349        .name           = "MPC85xx CDS",
 350        .probe          = mpc85xx_cds_probe,
 351        .setup_arch     = mpc85xx_cds_setup_arch,
 352        .init_IRQ       = mpc85xx_cds_pic_init,
 353        .show_cpuinfo   = mpc85xx_cds_show_cpuinfo,
 354        .get_irq        = mpic_get_irq,
 355#ifdef CONFIG_PCI
 356        .restart        = mpc85xx_cds_restart,
 357        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 358#else
 359        .restart        = fsl_rstcr_restart,
 360#endif
 361        .calibrate_decr = generic_calibrate_decr,
 362        .progress       = udbg_progress,
 363};
 364