Path: blob/master/arch/powerpc/platforms/85xx/mpc85xx_ds.c
10820 views
/*1* MPC85xx DS Board Setup2*3* Author Xianghua Xiao ([email protected])4* Roy Zang <[email protected]>5* - Add PCI/PCI Exprees support6* Copyright 2007 Freescale Semiconductor Inc.7*8* This program is free software; you can redistribute it and/or modify it9* under the terms of the GNU General Public License as published by the10* Free Software Foundation; either version 2 of the License, or (at your11* option) any later version.12*/1314#include <linux/stddef.h>15#include <linux/kernel.h>16#include <linux/pci.h>17#include <linux/kdev_t.h>18#include <linux/delay.h>19#include <linux/seq_file.h>20#include <linux/interrupt.h>21#include <linux/of_platform.h>22#include <linux/memblock.h>2324#include <asm/system.h>25#include <asm/time.h>26#include <asm/machdep.h>27#include <asm/pci-bridge.h>28#include <mm/mmu_decl.h>29#include <asm/prom.h>30#include <asm/udbg.h>31#include <asm/mpic.h>32#include <asm/i8259.h>33#include <asm/swiotlb.h>3435#include <sysdev/fsl_soc.h>36#include <sysdev/fsl_pci.h>3738#undef DEBUG3940#ifdef DEBUG41#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)42#else43#define DBG(fmt, args...)44#endif4546#ifdef CONFIG_PPC_I825947static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)48{49struct irq_chip *chip = irq_desc_get_chip(desc);50unsigned int cascade_irq = i8259_irq();5152if (cascade_irq != NO_IRQ) {53generic_handle_irq(cascade_irq);54}55chip->irq_eoi(&desc->irq_data);56}57#endif /* CONFIG_PPC_I8259 */5859void __init mpc85xx_ds_pic_init(void)60{61struct mpic *mpic;62struct resource r;63struct device_node *np;64#ifdef CONFIG_PPC_I825965struct device_node *cascade_node = NULL;66int cascade_irq;67#endif68unsigned long root = of_get_flat_dt_root();6970np = of_find_node_by_type(NULL, "open-pic");71if (np == NULL) {72printk(KERN_ERR "Could not find open-pic node\n");73return;74}7576if (of_address_to_resource(np, 0, &r)) {77printk(KERN_ERR "Failed to map mpic register space\n");78of_node_put(np);79return;80}8182if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {83mpic = mpic_alloc(np, r.start,84MPIC_PRIMARY |85MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,860, 256, " OpenPIC ");87} else {88mpic = mpic_alloc(np, r.start,89MPIC_PRIMARY | MPIC_WANTS_RESET |90MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |91MPIC_SINGLE_DEST_CPU,920, 256, " OpenPIC ");93}9495BUG_ON(mpic == NULL);96of_node_put(np);9798mpic_init(mpic);99100#ifdef CONFIG_PPC_I8259101/* Initialize the i8259 controller */102for_each_node_by_type(np, "interrupt-controller")103if (of_device_is_compatible(np, "chrp,iic")) {104cascade_node = np;105break;106}107108if (cascade_node == NULL) {109printk(KERN_DEBUG "Could not find i8259 PIC\n");110return;111}112113cascade_irq = irq_of_parse_and_map(cascade_node, 0);114if (cascade_irq == NO_IRQ) {115printk(KERN_ERR "Failed to map cascade interrupt\n");116return;117}118119DBG("mpc85xxds: cascade mapped to irq %d\n", cascade_irq);120121i8259_init(cascade_node, 0);122of_node_put(cascade_node);123124irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade);125#endif /* CONFIG_PPC_I8259 */126}127128#ifdef CONFIG_PCI129static int primary_phb_addr;130extern int uli_exclude_device(struct pci_controller *hose,131u_char bus, u_char devfn);132133static int mpc85xx_exclude_device(struct pci_controller *hose,134u_char bus, u_char devfn)135{136struct device_node* node;137struct resource rsrc;138139node = hose->dn;140of_address_to_resource(node, 0, &rsrc);141142if ((rsrc.start & 0xfffff) == primary_phb_addr) {143return uli_exclude_device(hose, bus, devfn);144}145146return PCIBIOS_SUCCESSFUL;147}148#endif /* CONFIG_PCI */149150/*151* Setup the architecture152*/153#ifdef CONFIG_SMP154extern void __init mpc85xx_smp_init(void);155#endif156static void __init mpc85xx_ds_setup_arch(void)157{158#ifdef CONFIG_PCI159struct device_node *np;160struct pci_controller *hose;161#endif162dma_addr_t max = 0xffffffff;163164if (ppc_md.progress)165ppc_md.progress("mpc85xx_ds_setup_arch()", 0);166167#ifdef CONFIG_PCI168for_each_node_by_type(np, "pci") {169if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||170of_device_is_compatible(np, "fsl,mpc8548-pcie") ||171of_device_is_compatible(np, "fsl,p2020-pcie")) {172struct resource rsrc;173of_address_to_resource(np, 0, &rsrc);174if ((rsrc.start & 0xfffff) == primary_phb_addr)175fsl_add_bridge(np, 1);176else177fsl_add_bridge(np, 0);178179hose = pci_find_hose_for_OF_device(np);180max = min(max, hose->dma_window_base_cur +181hose->dma_window_size);182}183}184185ppc_md.pci_exclude_device = mpc85xx_exclude_device;186#endif187188#ifdef CONFIG_SMP189mpc85xx_smp_init();190#endif191192#ifdef CONFIG_SWIOTLB193if (memblock_end_of_DRAM() > max) {194ppc_swiotlb_enable = 1;195set_pci_dma_ops(&swiotlb_dma_ops);196ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;197}198#endif199200printk("MPC85xx DS board from Freescale Semiconductor\n");201}202203/*204* Called very early, device-tree isn't unflattened205*/206static int __init mpc8544_ds_probe(void)207{208unsigned long root = of_get_flat_dt_root();209210if (of_flat_dt_is_compatible(root, "MPC8544DS")) {211#ifdef CONFIG_PCI212primary_phb_addr = 0xb000;213#endif214return 1;215}216217return 0;218}219220static struct of_device_id __initdata mpc85xxds_ids[] = {221{ .type = "soc", },222{ .compatible = "soc", },223{ .compatible = "simple-bus", },224{ .compatible = "gianfar", },225{},226};227228static int __init mpc85xxds_publish_devices(void)229{230return 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);235236machine_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);239240/*241* Called very early, device-tree isn't unflattened242*/243static int __init mpc8572_ds_probe(void)244{245unsigned long root = of_get_flat_dt_root();246247if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS")) {248#ifdef CONFIG_PCI249primary_phb_addr = 0x8000;250#endif251return 1;252}253254return 0;255}256257/*258* Called very early, device-tree isn't unflattened259*/260static int __init p2020_ds_probe(void)261{262unsigned long root = of_get_flat_dt_root();263264if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) {265#ifdef CONFIG_PCI266primary_phb_addr = 0x9000;267#endif268return 1;269}270271return 0;272}273274define_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_PCI280.pcibios_fixup_bus = fsl_pcibios_fixup_bus,281#endif282.get_irq = mpic_get_irq,283.restart = fsl_rstcr_restart,284.calibrate_decr = generic_calibrate_decr,285.progress = udbg_progress,286};287288define_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_PCI294.pcibios_fixup_bus = fsl_pcibios_fixup_bus,295#endif296.get_irq = mpic_get_irq,297.restart = fsl_rstcr_restart,298.calibrate_decr = generic_calibrate_decr,299.progress = udbg_progress,300};301302define_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_PCI308.pcibios_fixup_bus = fsl_pcibios_fixup_bus,309#endif310.get_irq = mpic_get_irq,311.restart = fsl_rstcr_restart,312.calibrate_decr = generic_calibrate_decr,313.progress = udbg_progress,314};315316317