linux/arch/powerpc/platforms/85xx/mpc85xx_ds.c
<<
>>
Prefs
   1/*
   2 * MPC85xx DS Board Setup
   3 *
   4 * Author Xianghua Xiao (x.xiao@freescale.com)
   5 * Roy Zang <tie-fei.zang@freescale.com>
   6 *      - Add PCI/PCI Exprees support
   7 * Copyright 2007 Freescale Semiconductor Inc.
   8 *
   9 * This program is free software; you can redistribute  it and/or modify it
  10 * under  the terms of  the GNU General  Public License as published by the
  11 * Free Software Foundation;  either version 2 of the  License, or (at your
  12 * option) any later version.
  13 */
  14
  15#include <linux/stddef.h>
  16#include <linux/kernel.h>
  17#include <linux/pci.h>
  18#include <linux/kdev_t.h>
  19#include <linux/delay.h>
  20#include <linux/seq_file.h>
  21#include <linux/interrupt.h>
  22#include <linux/of_platform.h>
  23#include <linux/lmb.h>
  24
  25#include <asm/system.h>
  26#include <asm/time.h>
  27#include <asm/machdep.h>
  28#include <asm/pci-bridge.h>
  29#include <mm/mmu_decl.h>
  30#include <asm/prom.h>
  31#include <asm/udbg.h>
  32#include <asm/mpic.h>
  33#include <asm/i8259.h>
  34#include <asm/swiotlb.h>
  35
  36#include <sysdev/fsl_soc.h>
  37#include <sysdev/fsl_pci.h>
  38
  39#undef DEBUG
  40
  41#ifdef DEBUG
  42#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
  43#else
  44#define DBG(fmt, args...)
  45#endif
  46
  47#ifdef CONFIG_PPC_I8259
  48static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
  49{
  50        unsigned int cascade_irq = i8259_irq();
  51
  52        if (cascade_irq != NO_IRQ) {
  53                generic_handle_irq(cascade_irq);
  54        }
  55        desc->chip->eoi(irq);
  56}
  57#endif  /* CONFIG_PPC_I8259 */
  58
  59void __init mpc85xx_ds_pic_init(void)
  60{
  61        struct mpic *mpic;
  62        struct resource r;
  63        struct device_node *np;
  64#ifdef CONFIG_PPC_I8259
  65        struct device_node *cascade_node = NULL;
  66        int cascade_irq;
  67#endif
  68        unsigned long root = of_get_flat_dt_root();
  69
  70        np = of_find_node_by_type(NULL, "open-pic");
  71        if (np == NULL) {
  72                printk(KERN_ERR "Could not find open-pic node\n");
  73                return;
  74        }
  75
  76        if (of_address_to_resource(np, 0, &r)) {
  77                printk(KERN_ERR "Failed to map mpic register space\n");
  78                of_node_put(np);
  79                return;
  80        }
  81
  82        if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
  83                mpic = mpic_alloc(np, r.start,
  84                        MPIC_PRIMARY |
  85                        MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
  86                        0, 256, " OpenPIC  ");
  87        } else {
  88                mpic = mpic_alloc(np, r.start,
  89                          MPIC_PRIMARY | MPIC_WANTS_RESET |
  90                          MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
  91                          MPIC_SINGLE_DEST_CPU,
  92                        0, 256, " OpenPIC  ");
  93        }
  94
  95        BUG_ON(mpic == NULL);
  96        of_node_put(np);
  97
  98        mpic_init(mpic);
  99
 100#ifdef CONFIG_PPC_I8259
 101        /* Initialize the i8259 controller */
 102        for_each_node_by_type(np, "interrupt-controller")
 103            if (of_device_is_compatible(np, "chrp,iic")) {
 104                cascade_node = np;
 105                break;
 106        }
 107
 108        if (cascade_node == NULL) {
 109                printk(KERN_DEBUG "Could not find i8259 PIC\n");
 110                return;
 111        }
 112
 113        cascade_irq = irq_of_parse_and_map(cascade_node, 0);
 114        if (cascade_irq == NO_IRQ) {
 115                printk(KERN_ERR "Failed to map cascade interrupt\n");
 116                return;
 117        }
 118
 119        DBG("mpc85xxds: cascade mapped to irq %d\n", cascade_irq);
 120
 121        i8259_init(cascade_node, 0);
 122        of_node_put(cascade_node);
 123
 124        set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade);
 125#endif  /* CONFIG_PPC_I8259 */
 126}
 127
 128#ifdef CONFIG_PCI
 129static int primary_phb_addr;
 130extern int uli_exclude_device(struct pci_controller *hose,
 131                                u_char bus, u_char devfn);
 132
 133static int mpc85xx_exclude_device(struct pci_controller *hose,
 134                                   u_char bus, u_char devfn)
 135{
 136        struct device_node* node;
 137        struct resource rsrc;
 138
 139        node = hose->dn;
 140        of_address_to_resource(node, 0, &rsrc);
 141
 142        if ((rsrc.start & 0xfffff) == primary_phb_addr) {
 143                return uli_exclude_device(hose, bus, devfn);
 144        }
 145
 146        return PCIBIOS_SUCCESSFUL;
 147}
 148#endif  /* CONFIG_PCI */
 149
 150/*
 151 * Setup the architecture
 152 */
 153#ifdef CONFIG_SMP
 154extern void __init mpc85xx_smp_init(void);
 155#endif
 156static void __init mpc85xx_ds_setup_arch(void)
 157{
 158#ifdef CONFIG_PCI
 159        struct device_node *np;
 160        struct pci_controller *hose;
 161#endif
 162        dma_addr_t max = 0xffffffff;
 163
 164        if (ppc_md.progress)
 165                ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
 166
 167#ifdef CONFIG_PCI
 168        for_each_node_by_type(np, "pci") {
 169                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
 170                    of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
 171                    of_device_is_compatible(np, "fsl,p2020-pcie")) {
 172                        struct resource rsrc;
 173                        of_address_to_resource(np, 0, &rsrc);
 174                        if ((rsrc.start & 0xfffff) == primary_phb_addr)
 175                                fsl_add_bridge(np, 1);
 176                        else
 177                                fsl_add_bridge(np, 0);
 178
 179                        hose = pci_find_hose_for_OF_device(np);
 180                        max = min(max, hose->dma_window_base_cur +
 181                                        hose->dma_window_size);
 182                }
 183        }
 184
 185        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 186#endif
 187
 188#ifdef CONFIG_SMP
 189        mpc85xx_smp_init();
 190#endif
 191
 192#ifdef CONFIG_SWIOTLB
 193        if (lmb_end_of_DRAM() > max) {
 194                ppc_swiotlb_enable = 1;
 195                set_pci_dma_ops(&swiotlb_dma_ops);
 196                ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
 197        }
 198#endif
 199
 200        printk("MPC85xx DS board from Freescale Semiconductor\n");
 201}
 202
 203/*
 204 * Called very early, device-tree isn't unflattened
 205 */
 206static int __init mpc8544_ds_probe(void)
 207{
 208        unsigned long root = of_get_flat_dt_root();
 209
 210        if (of_flat_dt_is_compatible(root, "MPC8544DS")) {
 211#ifdef CONFIG_PCI
 212                primary_phb_addr = 0xb000;
 213#endif
 214                return 1;
 215        }
 216
 217        return 0;
 218}
 219
 220static struct of_device_id __initdata mpc85xxds_ids[] = {
 221        { .type = "soc", },
 222        { .compatible = "soc", },
 223        { .compatible = "simple-bus", },
 224        { .compatible = "gianfar", },
 225        {},
 226};
 227
 228static int __init mpc85xxds_publish_devices(void)
 229{
 230        return of_platform_bus_probe(NULL, mpc85xxds_ids, NULL);
 231}
 232machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices);
 233machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices);
 234machine_device_initcall(p2020_ds, mpc85xxds_publish_devices);
 235
 236machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
 237machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
 238machine_arch_initcall(p2020_ds, swiotlb_setup_bus_notifier);
 239
 240/*
 241 * Called very early, device-tree isn't unflattened
 242 */
 243static int __init mpc8572_ds_probe(void)
 244{
 245        unsigned long root = of_get_flat_dt_root();
 246
 247        if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS")) {
 248#ifdef CONFIG_PCI
 249                primary_phb_addr = 0x8000;
 250#endif
 251                return 1;
 252        }
 253
 254        return 0;
 255}
 256
 257/*
 258 * Called very early, device-tree isn't unflattened
 259 */
 260static int __init p2020_ds_probe(void)
 261{
 262        unsigned long root = of_get_flat_dt_root();
 263
 264        if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) {
 265#ifdef CONFIG_PCI
 266                primary_phb_addr = 0x9000;
 267#endif
 268                return 1;
 269        }
 270
 271        return 0;
 272}
 273
 274define_machine(mpc8544_ds) {
 275        .name                   = "MPC8544 DS",
 276        .probe                  = mpc8544_ds_probe,
 277        .setup_arch             = mpc85xx_ds_setup_arch,
 278        .init_IRQ               = mpc85xx_ds_pic_init,
 279#ifdef CONFIG_PCI
 280        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 281#endif
 282        .get_irq                = mpic_get_irq,
 283        .restart                = fsl_rstcr_restart,
 284        .calibrate_decr         = generic_calibrate_decr,
 285        .progress               = udbg_progress,
 286};
 287
 288define_machine(mpc8572_ds) {
 289        .name                   = "MPC8572 DS",
 290        .probe                  = mpc8572_ds_probe,
 291        .setup_arch             = mpc85xx_ds_setup_arch,
 292        .init_IRQ               = mpc85xx_ds_pic_init,
 293#ifdef CONFIG_PCI
 294        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 295#endif
 296        .get_irq                = mpic_get_irq,
 297        .restart                = fsl_rstcr_restart,
 298        .calibrate_decr         = generic_calibrate_decr,
 299        .progress               = udbg_progress,
 300};
 301
 302define_machine(p2020_ds) {
 303        .name                   = "P2020 DS",
 304        .probe                  = p2020_ds_probe,
 305        .setup_arch             = mpc85xx_ds_setup_arch,
 306        .init_IRQ               = mpc85xx_ds_pic_init,
 307#ifdef CONFIG_PCI
 308        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 309#endif
 310        .get_irq                = mpic_get_irq,
 311        .restart                = fsl_rstcr_restart,
 312        .calibrate_decr         = generic_calibrate_decr,
 313        .progress               = udbg_progress,
 314};
 315