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 != NO_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        unsigned long root = of_get_flat_dt_root();
  70
  71        if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
  72                mpic = mpic_alloc(NULL, 0,
  73                        MPIC_NO_RESET |
  74                        MPIC_BIG_ENDIAN |
  75                        MPIC_SINGLE_DEST_CPU,
  76                        0, 256, " OpenPIC  ");
  77        } else {
  78                mpic = mpic_alloc(NULL, 0,
  79                          MPIC_BIG_ENDIAN |
  80                          MPIC_SINGLE_DEST_CPU,
  81                        0, 256, " OpenPIC  ");
  82        }
  83
  84        BUG_ON(mpic == NULL);
  85        mpic_init(mpic);
  86
  87#ifdef CONFIG_PPC_I8259
  88        /* Initialize the i8259 controller */
  89        for_each_node_by_type(np, "interrupt-controller")
  90            if (of_device_is_compatible(np, "chrp,iic")) {
  91                cascade_node = np;
  92                break;
  93        }
  94
  95        if (cascade_node == NULL) {
  96                printk(KERN_DEBUG "Could not find i8259 PIC\n");
  97                return;
  98        }
  99
 100        cascade_irq = irq_of_parse_and_map(cascade_node, 0);
 101        if (cascade_irq == NO_IRQ) {
 102                printk(KERN_ERR "Failed to map cascade interrupt\n");
 103                return;
 104        }
 105
 106        DBG("mpc85xxds: cascade mapped to irq %d\n", cascade_irq);
 107
 108        i8259_init(cascade_node, 0);
 109        of_node_put(cascade_node);
 110
 111        irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade);
 112#endif  /* CONFIG_PPC_I8259 */
 113}
 114
 115#ifdef CONFIG_PCI
 116extern int uli_exclude_device(struct pci_controller *hose,
 117                                u_char bus, u_char devfn);
 118
 119static struct device_node *pci_with_uli;
 120
 121static int mpc85xx_exclude_device(struct pci_controller *hose,
 122                                   u_char bus, u_char devfn)
 123{
 124        if (hose->dn == pci_with_uli)
 125                return uli_exclude_device(hose, bus, devfn);
 126
 127        return PCIBIOS_SUCCESSFUL;
 128}
 129#endif  /* CONFIG_PCI */
 130
 131static void __init mpc85xx_ds_uli_init(void)
 132{
 133#ifdef CONFIG_PCI
 134        struct device_node *node;
 135
 136        /* See if we have a ULI under the primary */
 137
 138        node = of_find_node_by_name(NULL, "uli1575");
 139        while ((pci_with_uli = of_get_parent(node))) {
 140                of_node_put(node);
 141                node = pci_with_uli;
 142
 143                if (pci_with_uli == fsl_pci_primary) {
 144                        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 145                        break;
 146                }
 147        }
 148#endif
 149}
 150
 151/*
 152 * Setup the architecture
 153 */
 154static void __init mpc85xx_ds_setup_arch(void)
 155{
 156        if (ppc_md.progress)
 157                ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
 158
 159        swiotlb_detect_4g();
 160        fsl_pci_assign_primary();
 161        mpc85xx_ds_uli_init();
 162        mpc85xx_smp_init();
 163
 164        printk("MPC85xx DS board from Freescale Semiconductor\n");
 165}
 166
 167/*
 168 * Called very early, device-tree isn't unflattened
 169 */
 170static int __init mpc8544_ds_probe(void)
 171{
 172        unsigned long root = of_get_flat_dt_root();
 173
 174        return !!of_flat_dt_is_compatible(root, "MPC8544DS");
 175}
 176
 177machine_arch_initcall(mpc8544_ds, mpc85xx_common_publish_devices);
 178machine_arch_initcall(mpc8572_ds, mpc85xx_common_publish_devices);
 179machine_arch_initcall(p2020_ds, mpc85xx_common_publish_devices);
 180
 181machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
 182machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
 183machine_arch_initcall(p2020_ds, swiotlb_setup_bus_notifier);
 184
 185/*
 186 * Called very early, device-tree isn't unflattened
 187 */
 188static int __init mpc8572_ds_probe(void)
 189{
 190        unsigned long root = of_get_flat_dt_root();
 191
 192        return !!of_flat_dt_is_compatible(root, "fsl,MPC8572DS");
 193}
 194
 195/*
 196 * Called very early, device-tree isn't unflattened
 197 */
 198static int __init p2020_ds_probe(void)
 199{
 200        unsigned long root = of_get_flat_dt_root();
 201
 202        return !!of_flat_dt_is_compatible(root, "fsl,P2020DS");
 203}
 204
 205define_machine(mpc8544_ds) {
 206        .name                   = "MPC8544 DS",
 207        .probe                  = mpc8544_ds_probe,
 208        .setup_arch             = mpc85xx_ds_setup_arch,
 209        .init_IRQ               = mpc85xx_ds_pic_init,
 210#ifdef CONFIG_PCI
 211        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 212        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 213#endif
 214        .get_irq                = mpic_get_irq,
 215        .restart                = fsl_rstcr_restart,
 216        .calibrate_decr         = generic_calibrate_decr,
 217        .progress               = udbg_progress,
 218};
 219
 220define_machine(mpc8572_ds) {
 221        .name                   = "MPC8572 DS",
 222        .probe                  = mpc8572_ds_probe,
 223        .setup_arch             = mpc85xx_ds_setup_arch,
 224        .init_IRQ               = mpc85xx_ds_pic_init,
 225#ifdef CONFIG_PCI
 226        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 227        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 228#endif
 229        .get_irq                = mpic_get_irq,
 230        .restart                = fsl_rstcr_restart,
 231        .calibrate_decr         = generic_calibrate_decr,
 232        .progress               = udbg_progress,
 233};
 234
 235define_machine(p2020_ds) {
 236        .name                   = "P2020 DS",
 237        .probe                  = p2020_ds_probe,
 238        .setup_arch             = mpc85xx_ds_setup_arch,
 239        .init_IRQ               = mpc85xx_ds_pic_init,
 240#ifdef CONFIG_PCI
 241        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 242        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 243#endif
 244        .get_irq                = mpic_get_irq,
 245        .restart                = fsl_rstcr_restart,
 246        .calibrate_decr         = generic_calibrate_decr,
 247        .progress               = udbg_progress,
 248};
 249