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
  24#include <asm/time.h>
  25#include <asm/machdep.h>
  26#include <asm/pci-bridge.h>
  27#include <mm/mmu_decl.h>
  28#include <asm/prom.h>
  29#include <asm/udbg.h>
  30#include <asm/mpic.h>
  31#include <asm/i8259.h>
  32#include <asm/swiotlb.h>
  33
  34#include <sysdev/fsl_soc.h>
  35#include <sysdev/fsl_pci.h>
  36#include "smp.h"
  37
  38#include "mpc85xx.h"
  39
  40#undef DEBUG
  41
  42#ifdef DEBUG
  43#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
  44#else
  45#define DBG(fmt, args...)
  46#endif
  47
  48#ifdef CONFIG_PPC_I8259
  49static void mpc85xx_8259_cascade(struct irq_desc *desc)
  50{
  51        struct irq_chip *chip = irq_desc_get_chip(desc);
  52        unsigned int cascade_irq = i8259_irq();
  53
  54        if (cascade_irq) {
  55                generic_handle_irq(cascade_irq);
  56        }
  57        chip->irq_eoi(&desc->irq_data);
  58}
  59#endif  /* CONFIG_PPC_I8259 */
  60
  61void __init mpc85xx_ds_pic_init(void)
  62{
  63        struct mpic *mpic;
  64#ifdef CONFIG_PPC_I8259
  65        struct device_node *np;
  66        struct device_node *cascade_node = NULL;
  67        int cascade_irq;
  68#endif
  69        if (of_machine_is_compatible("fsl,MPC8572DS-CAMP")) {
  70                mpic = mpic_alloc(NULL, 0,
  71                        MPIC_NO_RESET |
  72                        MPIC_BIG_ENDIAN |
  73                        MPIC_SINGLE_DEST_CPU,
  74                        0, 256, " OpenPIC  ");
  75        } else {
  76                mpic = mpic_alloc(NULL, 0,
  77                          MPIC_BIG_ENDIAN |
  78                          MPIC_SINGLE_DEST_CPU,
  79                        0, 256, " OpenPIC  ");
  80        }
  81
  82        BUG_ON(mpic == NULL);
  83        mpic_init(mpic);
  84
  85#ifdef CONFIG_PPC_I8259
  86        /* Initialize the i8259 controller */
  87        for_each_node_by_type(np, "interrupt-controller")
  88            if (of_device_is_compatible(np, "chrp,iic")) {
  89                cascade_node = np;
  90                break;
  91        }
  92
  93        if (cascade_node == NULL) {
  94                printk(KERN_DEBUG "Could not find i8259 PIC\n");
  95                return;
  96        }
  97
  98        cascade_irq = irq_of_parse_and_map(cascade_node, 0);
  99        if (!cascade_irq) {
 100                printk(KERN_ERR "Failed to map cascade interrupt\n");
 101                return;
 102        }
 103
 104        DBG("mpc85xxds: cascade mapped to irq %d\n", cascade_irq);
 105
 106        i8259_init(cascade_node, 0);
 107        of_node_put(cascade_node);
 108
 109        irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade);
 110#endif  /* CONFIG_PPC_I8259 */
 111}
 112
 113#ifdef CONFIG_PCI
 114extern int uli_exclude_device(struct pci_controller *hose,
 115                                u_char bus, u_char devfn);
 116
 117static struct device_node *pci_with_uli;
 118
 119static int mpc85xx_exclude_device(struct pci_controller *hose,
 120                                   u_char bus, u_char devfn)
 121{
 122        if (hose->dn == pci_with_uli)
 123                return uli_exclude_device(hose, bus, devfn);
 124
 125        return PCIBIOS_SUCCESSFUL;
 126}
 127#endif  /* CONFIG_PCI */
 128
 129static void __init mpc85xx_ds_uli_init(void)
 130{
 131#ifdef CONFIG_PCI
 132        struct device_node *node;
 133
 134        /* See if we have a ULI under the primary */
 135
 136        node = of_find_node_by_name(NULL, "uli1575");
 137        while ((pci_with_uli = of_get_parent(node))) {
 138                of_node_put(node);
 139                node = pci_with_uli;
 140
 141                if (pci_with_uli == fsl_pci_primary) {
 142                        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 143                        break;
 144                }
 145        }
 146#endif
 147}
 148
 149/*
 150 * Setup the architecture
 151 */
 152static void __init mpc85xx_ds_setup_arch(void)
 153{
 154        if (ppc_md.progress)
 155                ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
 156
 157        swiotlb_detect_4g();
 158        fsl_pci_assign_primary();
 159        mpc85xx_ds_uli_init();
 160        mpc85xx_smp_init();
 161
 162        printk("MPC85xx DS board from Freescale Semiconductor\n");
 163}
 164
 165/*
 166 * Called very early, device-tree isn't unflattened
 167 */
 168static int __init mpc8544_ds_probe(void)
 169{
 170        return !!of_machine_is_compatible("MPC8544DS");
 171}
 172
 173machine_arch_initcall(mpc8544_ds, mpc85xx_common_publish_devices);
 174machine_arch_initcall(mpc8572_ds, mpc85xx_common_publish_devices);
 175machine_arch_initcall(p2020_ds, mpc85xx_common_publish_devices);
 176
 177machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
 178machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
 179machine_arch_initcall(p2020_ds, swiotlb_setup_bus_notifier);
 180
 181/*
 182 * Called very early, device-tree isn't unflattened
 183 */
 184static int __init mpc8572_ds_probe(void)
 185{
 186        return !!of_machine_is_compatible("fsl,MPC8572DS");
 187}
 188
 189/*
 190 * Called very early, device-tree isn't unflattened
 191 */
 192static int __init p2020_ds_probe(void)
 193{
 194        return !!of_machine_is_compatible("fsl,P2020DS");
 195}
 196
 197define_machine(mpc8544_ds) {
 198        .name                   = "MPC8544 DS",
 199        .probe                  = mpc8544_ds_probe,
 200        .setup_arch             = mpc85xx_ds_setup_arch,
 201        .init_IRQ               = mpc85xx_ds_pic_init,
 202#ifdef CONFIG_PCI
 203        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 204        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 205#endif
 206        .get_irq                = mpic_get_irq,
 207        .calibrate_decr         = generic_calibrate_decr,
 208        .progress               = udbg_progress,
 209};
 210
 211define_machine(mpc8572_ds) {
 212        .name                   = "MPC8572 DS",
 213        .probe                  = mpc8572_ds_probe,
 214        .setup_arch             = mpc85xx_ds_setup_arch,
 215        .init_IRQ               = mpc85xx_ds_pic_init,
 216#ifdef CONFIG_PCI
 217        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 218        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 219#endif
 220        .get_irq                = mpic_get_irq,
 221        .calibrate_decr         = generic_calibrate_decr,
 222        .progress               = udbg_progress,
 223};
 224
 225define_machine(p2020_ds) {
 226        .name                   = "P2020 DS",
 227        .probe                  = p2020_ds_probe,
 228        .setup_arch             = mpc85xx_ds_setup_arch,
 229        .init_IRQ               = mpc85xx_ds_pic_init,
 230#ifdef CONFIG_PCI
 231        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 232        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 233#endif
 234        .get_irq                = mpic_get_irq,
 235        .calibrate_decr         = generic_calibrate_decr,
 236        .progress               = udbg_progress,
 237};
 238