17568cb4eSPaul Mackerras /* 27568cb4eSPaul Mackerras * Port for PPC64 David Engebretsen, IBM Corp. 37568cb4eSPaul Mackerras * Contains common pci routines for ppc64 platform, pSeries and iSeries brands. 47568cb4eSPaul Mackerras * 57568cb4eSPaul Mackerras * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 67568cb4eSPaul Mackerras * Rework, based on alpha PCI code. 77568cb4eSPaul Mackerras * 87568cb4eSPaul Mackerras * This program is free software; you can redistribute it and/or 97568cb4eSPaul Mackerras * modify it under the terms of the GNU General Public License 107568cb4eSPaul Mackerras * as published by the Free Software Foundation; either version 117568cb4eSPaul Mackerras * 2 of the License, or (at your option) any later version. 127568cb4eSPaul Mackerras */ 137568cb4eSPaul Mackerras 147568cb4eSPaul Mackerras #undef DEBUG 157568cb4eSPaul Mackerras 167568cb4eSPaul Mackerras #include <linux/kernel.h> 177568cb4eSPaul Mackerras #include <linux/pci.h> 187568cb4eSPaul Mackerras #include <linux/string.h> 197568cb4eSPaul Mackerras #include <linux/init.h> 207568cb4eSPaul Mackerras #include <linux/bootmem.h> 217568cb4eSPaul Mackerras #include <linux/mm.h> 227568cb4eSPaul Mackerras #include <linux/list.h> 237568cb4eSPaul Mackerras #include <linux/syscalls.h> 246e99e458SBenjamin Herrenschmidt #include <linux/irq.h> 253d5134eeSBenjamin Herrenschmidt #include <linux/vmalloc.h> 267568cb4eSPaul Mackerras 277568cb4eSPaul Mackerras #include <asm/processor.h> 287568cb4eSPaul Mackerras #include <asm/io.h> 297568cb4eSPaul Mackerras #include <asm/prom.h> 307568cb4eSPaul Mackerras #include <asm/pci-bridge.h> 317568cb4eSPaul Mackerras #include <asm/byteorder.h> 327568cb4eSPaul Mackerras #include <asm/machdep.h> 337568cb4eSPaul Mackerras #include <asm/ppc-pci.h> 347568cb4eSPaul Mackerras 357568cb4eSPaul Mackerras #ifdef DEBUG 36f9e4ec57SMichael Ellerman #include <asm/udbg.h> 371beb6a7dSBenjamin Herrenschmidt #define DBG(fmt...) printk(fmt) 387568cb4eSPaul Mackerras #else 397568cb4eSPaul Mackerras #define DBG(fmt...) 407568cb4eSPaul Mackerras #endif 417568cb4eSPaul Mackerras 427568cb4eSPaul Mackerras unsigned long pci_probe_only = 1; 43f8ef2705SPaul Mackerras int pci_assign_all_buses = 0; 447568cb4eSPaul Mackerras 457568cb4eSPaul Mackerras static void fixup_resource(struct resource *res, struct pci_dev *dev); 467568cb4eSPaul Mackerras static void do_bus_setup(struct pci_bus *bus); 477568cb4eSPaul Mackerras 487568cb4eSPaul Mackerras /* pci_io_base -- the base address from which io bars are offsets. 497568cb4eSPaul Mackerras * This is the lowest I/O base address (so bar values are always positive), 507568cb4eSPaul Mackerras * and it *must* be the start of ISA space if an ISA bus exists because 513d5134eeSBenjamin Herrenschmidt * ISA drivers use hard coded offsets. If no ISA bus exists nothing 523d5134eeSBenjamin Herrenschmidt * is mapped on the first 64K of IO space 537568cb4eSPaul Mackerras */ 543d5134eeSBenjamin Herrenschmidt unsigned long pci_io_base = ISA_IO_BASE; 557568cb4eSPaul Mackerras EXPORT_SYMBOL(pci_io_base); 567568cb4eSPaul Mackerras 577568cb4eSPaul Mackerras LIST_HEAD(hose_list); 587568cb4eSPaul Mackerras 5957190708SStephen Rothwell static struct dma_mapping_ops *pci_dma_ops; 607568cb4eSPaul Mackerras 6198747770SStephen Rothwell void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) 6298747770SStephen Rothwell { 6398747770SStephen Rothwell pci_dma_ops = dma_ops; 6498747770SStephen Rothwell } 6598747770SStephen Rothwell 6657190708SStephen Rothwell struct dma_mapping_ops *get_pci_dma_ops(void) 6757190708SStephen Rothwell { 6857190708SStephen Rothwell return pci_dma_ops; 6957190708SStephen Rothwell } 7057190708SStephen Rothwell EXPORT_SYMBOL(get_pci_dma_ops); 7157190708SStephen Rothwell 727568cb4eSPaul Mackerras static void fixup_broken_pcnet32(struct pci_dev* dev) 737568cb4eSPaul Mackerras { 747568cb4eSPaul Mackerras if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 757568cb4eSPaul Mackerras dev->vendor = PCI_VENDOR_ID_AMD; 767568cb4eSPaul Mackerras pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); 777568cb4eSPaul Mackerras } 787568cb4eSPaul Mackerras } 797568cb4eSPaul Mackerras DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); 807568cb4eSPaul Mackerras 817568cb4eSPaul Mackerras void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 827568cb4eSPaul Mackerras struct resource *res) 837568cb4eSPaul Mackerras { 847568cb4eSPaul Mackerras unsigned long offset = 0; 857568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 867568cb4eSPaul Mackerras 877568cb4eSPaul Mackerras if (!hose) 887568cb4eSPaul Mackerras return; 897568cb4eSPaul Mackerras 907568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 913d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 927568cb4eSPaul Mackerras 937568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 947568cb4eSPaul Mackerras offset = hose->pci_mem_offset; 957568cb4eSPaul Mackerras 967568cb4eSPaul Mackerras region->start = res->start - offset; 977568cb4eSPaul Mackerras region->end = res->end - offset; 987568cb4eSPaul Mackerras } 997568cb4eSPaul Mackerras 1007568cb4eSPaul Mackerras void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 1017568cb4eSPaul Mackerras struct pci_bus_region *region) 1027568cb4eSPaul Mackerras { 1037568cb4eSPaul Mackerras unsigned long offset = 0; 1047568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 1057568cb4eSPaul Mackerras 1067568cb4eSPaul Mackerras if (!hose) 1077568cb4eSPaul Mackerras return; 1087568cb4eSPaul Mackerras 1097568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 1103d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 1117568cb4eSPaul Mackerras 1127568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 1137568cb4eSPaul Mackerras offset = hose->pci_mem_offset; 1147568cb4eSPaul Mackerras 1157568cb4eSPaul Mackerras res->start = region->start + offset; 1167568cb4eSPaul Mackerras res->end = region->end + offset; 1177568cb4eSPaul Mackerras } 1187568cb4eSPaul Mackerras 1197568cb4eSPaul Mackerras #ifdef CONFIG_HOTPLUG 1207568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_resource_to_bus); 1217568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_bus_to_resource); 1227568cb4eSPaul Mackerras #endif 1237568cb4eSPaul Mackerras 1247568cb4eSPaul Mackerras /* 1257568cb4eSPaul Mackerras * We need to avoid collisions with `mirrored' VGA ports 1267568cb4eSPaul Mackerras * and other strange ISA hardware, so we always want the 1277568cb4eSPaul Mackerras * addresses to be allocated in the 0x000-0x0ff region 1287568cb4eSPaul Mackerras * modulo 0x400. 1297568cb4eSPaul Mackerras * 1307568cb4eSPaul Mackerras * Why? Because some silly external IO cards only decode 1317568cb4eSPaul Mackerras * the low 10 bits of the IO address. The 0x00-0xff region 1327568cb4eSPaul Mackerras * is reserved for motherboard devices that decode all 16 1337568cb4eSPaul Mackerras * bits, so it's ok to allocate at, say, 0x2800-0x28ff, 1347568cb4eSPaul Mackerras * but we want to try to avoid allocating at 0x2900-0x2bff 1357568cb4eSPaul Mackerras * which might have be mirrored at 0x0100-0x03ff.. 1367568cb4eSPaul Mackerras */ 1377568cb4eSPaul Mackerras void pcibios_align_resource(void *data, struct resource *res, 138e31dd6e4SGreg Kroah-Hartman resource_size_t size, resource_size_t align) 1397568cb4eSPaul Mackerras { 1407568cb4eSPaul Mackerras struct pci_dev *dev = data; 1417568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 142e31dd6e4SGreg Kroah-Hartman resource_size_t start = res->start; 1437568cb4eSPaul Mackerras unsigned long alignto; 1447568cb4eSPaul Mackerras 1457568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) { 1467568cb4eSPaul Mackerras unsigned long offset = (unsigned long)hose->io_base_virt - 1473d5134eeSBenjamin Herrenschmidt _IO_BASE; 1487568cb4eSPaul Mackerras /* Make sure we start at our min on all hoses */ 1497568cb4eSPaul Mackerras if (start - offset < PCIBIOS_MIN_IO) 1507568cb4eSPaul Mackerras start = PCIBIOS_MIN_IO + offset; 1517568cb4eSPaul Mackerras 1527568cb4eSPaul Mackerras /* 1537568cb4eSPaul Mackerras * Put everything into 0x00-0xff region modulo 0x400 1547568cb4eSPaul Mackerras */ 1557568cb4eSPaul Mackerras if (start & 0x300) 1567568cb4eSPaul Mackerras start = (start + 0x3ff) & ~0x3ff; 1577568cb4eSPaul Mackerras 1587568cb4eSPaul Mackerras } else if (res->flags & IORESOURCE_MEM) { 1597568cb4eSPaul Mackerras /* Make sure we start at our min on all hoses */ 1607568cb4eSPaul Mackerras if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM) 1617568cb4eSPaul Mackerras start = PCIBIOS_MIN_MEM + hose->pci_mem_offset; 1627568cb4eSPaul Mackerras 1637568cb4eSPaul Mackerras /* Align to multiple of size of minimum base. */ 1647568cb4eSPaul Mackerras alignto = max(0x1000UL, align); 1657568cb4eSPaul Mackerras start = ALIGN(start, alignto); 1667568cb4eSPaul Mackerras } 1677568cb4eSPaul Mackerras 1687568cb4eSPaul Mackerras res->start = start; 1697568cb4eSPaul Mackerras } 1707568cb4eSPaul Mackerras 171facf0787SLinas Vepstas void __devinit pcibios_claim_one_bus(struct pci_bus *b) 1727568cb4eSPaul Mackerras { 1737568cb4eSPaul Mackerras struct pci_dev *dev; 1747568cb4eSPaul Mackerras struct pci_bus *child_bus; 1757568cb4eSPaul Mackerras 1767568cb4eSPaul Mackerras list_for_each_entry(dev, &b->devices, bus_list) { 1777568cb4eSPaul Mackerras int i; 1787568cb4eSPaul Mackerras 1797568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES; i++) { 1807568cb4eSPaul Mackerras struct resource *r = &dev->resource[i]; 1817568cb4eSPaul Mackerras 1827568cb4eSPaul Mackerras if (r->parent || !r->start || !r->flags) 1837568cb4eSPaul Mackerras continue; 1847568cb4eSPaul Mackerras pci_claim_resource(dev, i); 1857568cb4eSPaul Mackerras } 1867568cb4eSPaul Mackerras } 1877568cb4eSPaul Mackerras 1887568cb4eSPaul Mackerras list_for_each_entry(child_bus, &b->children, node) 1897568cb4eSPaul Mackerras pcibios_claim_one_bus(child_bus); 1907568cb4eSPaul Mackerras } 191af9deabeSlinas #ifdef CONFIG_HOTPLUG 192af9deabeSlinas EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); 193af9deabeSlinas #endif 1947568cb4eSPaul Mackerras 1957568cb4eSPaul Mackerras static void __init pcibios_claim_of_setup(void) 1967568cb4eSPaul Mackerras { 1977568cb4eSPaul Mackerras struct pci_bus *b; 1987568cb4eSPaul Mackerras 1997568cb4eSPaul Mackerras list_for_each_entry(b, &pci_root_buses, node) 2007568cb4eSPaul Mackerras pcibios_claim_one_bus(b); 2017568cb4eSPaul Mackerras } 2027568cb4eSPaul Mackerras 2037568cb4eSPaul Mackerras static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 2047568cb4eSPaul Mackerras { 205a7f67bdfSJeremy Kerr const u32 *prop; 2067568cb4eSPaul Mackerras int len; 2077568cb4eSPaul Mackerras 208e2eb6392SStephen Rothwell prop = of_get_property(np, name, &len); 2097568cb4eSPaul Mackerras if (prop && len >= 4) 2107568cb4eSPaul Mackerras return *prop; 2117568cb4eSPaul Mackerras return def; 2127568cb4eSPaul Mackerras } 2137568cb4eSPaul Mackerras 2147568cb4eSPaul Mackerras static unsigned int pci_parse_of_flags(u32 addr0) 2157568cb4eSPaul Mackerras { 2167568cb4eSPaul Mackerras unsigned int flags = 0; 2177568cb4eSPaul Mackerras 2187568cb4eSPaul Mackerras if (addr0 & 0x02000000) { 2197568cb4eSPaul Mackerras flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; 2207568cb4eSPaul Mackerras flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; 2217568cb4eSPaul Mackerras flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; 2227568cb4eSPaul Mackerras if (addr0 & 0x40000000) 2237568cb4eSPaul Mackerras flags |= IORESOURCE_PREFETCH 2247568cb4eSPaul Mackerras | PCI_BASE_ADDRESS_MEM_PREFETCH; 2257568cb4eSPaul Mackerras } else if (addr0 & 0x01000000) 2267568cb4eSPaul Mackerras flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 2277568cb4eSPaul Mackerras return flags; 2287568cb4eSPaul Mackerras } 2297568cb4eSPaul Mackerras 2307568cb4eSPaul Mackerras 2317568cb4eSPaul Mackerras static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) 2327568cb4eSPaul Mackerras { 2337568cb4eSPaul Mackerras u64 base, size; 2347568cb4eSPaul Mackerras unsigned int flags; 2357568cb4eSPaul Mackerras struct resource *res; 236a7f67bdfSJeremy Kerr const u32 *addrs; 237a7f67bdfSJeremy Kerr u32 i; 2387568cb4eSPaul Mackerras int proplen; 2397568cb4eSPaul Mackerras 240e2eb6392SStephen Rothwell addrs = of_get_property(node, "assigned-addresses", &proplen); 2417568cb4eSPaul Mackerras if (!addrs) 2427568cb4eSPaul Mackerras return; 2431beb6a7dSBenjamin Herrenschmidt DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); 2447568cb4eSPaul Mackerras for (; proplen >= 20; proplen -= 20, addrs += 5) { 2457568cb4eSPaul Mackerras flags = pci_parse_of_flags(addrs[0]); 2467568cb4eSPaul Mackerras if (!flags) 2477568cb4eSPaul Mackerras continue; 248327e22dfSJon Loeliger base = of_read_number(&addrs[1], 2); 249327e22dfSJon Loeliger size = of_read_number(&addrs[3], 2); 2507568cb4eSPaul Mackerras if (!size) 2517568cb4eSPaul Mackerras continue; 2527568cb4eSPaul Mackerras i = addrs[0] & 0xff; 2531beb6a7dSBenjamin Herrenschmidt DBG(" base: %llx, size: %llx, i: %x\n", 2541beb6a7dSBenjamin Herrenschmidt (unsigned long long)base, (unsigned long long)size, i); 2551beb6a7dSBenjamin Herrenschmidt 2567568cb4eSPaul Mackerras if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { 2577568cb4eSPaul Mackerras res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; 2587568cb4eSPaul Mackerras } else if (i == dev->rom_base_reg) { 2597568cb4eSPaul Mackerras res = &dev->resource[PCI_ROM_RESOURCE]; 2607568cb4eSPaul Mackerras flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; 2617568cb4eSPaul Mackerras } else { 2627568cb4eSPaul Mackerras printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); 2637568cb4eSPaul Mackerras continue; 2647568cb4eSPaul Mackerras } 2657568cb4eSPaul Mackerras res->start = base; 2667568cb4eSPaul Mackerras res->end = base + size - 1; 2677568cb4eSPaul Mackerras res->flags = flags; 2687568cb4eSPaul Mackerras res->name = pci_name(dev); 2697568cb4eSPaul Mackerras fixup_resource(res, dev); 2707568cb4eSPaul Mackerras } 2717568cb4eSPaul Mackerras } 2727568cb4eSPaul Mackerras 2737568cb4eSPaul Mackerras struct pci_dev *of_create_pci_dev(struct device_node *node, 2747568cb4eSPaul Mackerras struct pci_bus *bus, int devfn) 2757568cb4eSPaul Mackerras { 2767568cb4eSPaul Mackerras struct pci_dev *dev; 2777568cb4eSPaul Mackerras const char *type; 2787568cb4eSPaul Mackerras 279bab41e9bSMichael Ellerman dev = alloc_pci_dev(); 2807568cb4eSPaul Mackerras if (!dev) 2817568cb4eSPaul Mackerras return NULL; 282e2eb6392SStephen Rothwell type = of_get_property(node, "device_type", NULL); 2837568cb4eSPaul Mackerras if (type == NULL) 2847568cb4eSPaul Mackerras type = ""; 2857568cb4eSPaul Mackerras 2861beb6a7dSBenjamin Herrenschmidt DBG(" create device, devfn: %x, type: %s\n", devfn, type); 2871beb6a7dSBenjamin Herrenschmidt 2887568cb4eSPaul Mackerras dev->bus = bus; 2897568cb4eSPaul Mackerras dev->sysdata = node; 2907568cb4eSPaul Mackerras dev->dev.parent = bus->bridge; 2917568cb4eSPaul Mackerras dev->dev.bus = &pci_bus_type; 2927568cb4eSPaul Mackerras dev->devfn = devfn; 2937568cb4eSPaul Mackerras dev->multifunction = 0; /* maybe a lie? */ 2947568cb4eSPaul Mackerras 2957568cb4eSPaul Mackerras dev->vendor = get_int_prop(node, "vendor-id", 0xffff); 2967568cb4eSPaul Mackerras dev->device = get_int_prop(node, "device-id", 0xffff); 2977568cb4eSPaul Mackerras dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); 2987568cb4eSPaul Mackerras dev->subsystem_device = get_int_prop(node, "subsystem-id", 0); 2997568cb4eSPaul Mackerras 3009d17a5c6SBenjamin Herrenschmidt dev->cfg_size = pci_cfg_space_size(dev); 3017568cb4eSPaul Mackerras 3027568cb4eSPaul Mackerras sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), 3037568cb4eSPaul Mackerras dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 3047568cb4eSPaul Mackerras dev->class = get_int_prop(node, "class-code", 0); 305b8a3a521SAuke Kok dev->revision = get_int_prop(node, "revision-id", 0); 3067568cb4eSPaul Mackerras 3071beb6a7dSBenjamin Herrenschmidt DBG(" class: 0x%x\n", dev->class); 308b8a3a521SAuke Kok DBG(" revision: 0x%x\n", dev->revision); 3091beb6a7dSBenjamin Herrenschmidt 3107568cb4eSPaul Mackerras dev->current_state = 4; /* unknown power state */ 311bb63ab13SLinas Vepstas dev->error_state = pci_channel_io_normal; 3128f2ea1fdSBenjamin Herrenschmidt dev->dma_mask = 0xffffffff; 3137568cb4eSPaul Mackerras 314bb53bb3dSJake Moilanen if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { 3157568cb4eSPaul Mackerras /* a PCI-PCI bridge */ 3167568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; 3177568cb4eSPaul Mackerras dev->rom_base_reg = PCI_ROM_ADDRESS1; 3187568cb4eSPaul Mackerras } else if (!strcmp(type, "cardbus")) { 3197568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; 3207568cb4eSPaul Mackerras } else { 3217568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_NORMAL; 3227568cb4eSPaul Mackerras dev->rom_base_reg = PCI_ROM_ADDRESS; 3230ebfff14SBenjamin Herrenschmidt /* Maybe do a default OF mapping here */ 3247568cb4eSPaul Mackerras dev->irq = NO_IRQ; 3257568cb4eSPaul Mackerras } 3267568cb4eSPaul Mackerras 3277568cb4eSPaul Mackerras pci_parse_of_addrs(node, dev); 3287568cb4eSPaul Mackerras 3291beb6a7dSBenjamin Herrenschmidt DBG(" adding to system ...\n"); 3301beb6a7dSBenjamin Herrenschmidt 3317568cb4eSPaul Mackerras pci_device_add(dev, bus); 3327568cb4eSPaul Mackerras 3337568cb4eSPaul Mackerras return dev; 3347568cb4eSPaul Mackerras } 3357568cb4eSPaul Mackerras EXPORT_SYMBOL(of_create_pci_dev); 3367568cb4eSPaul Mackerras 3377568cb4eSPaul Mackerras void __devinit of_scan_bus(struct device_node *node, 3387568cb4eSPaul Mackerras struct pci_bus *bus) 3397568cb4eSPaul Mackerras { 3407568cb4eSPaul Mackerras struct device_node *child = NULL; 341a7f67bdfSJeremy Kerr const u32 *reg; 3427568cb4eSPaul Mackerras int reglen, devfn; 3437568cb4eSPaul Mackerras struct pci_dev *dev; 3447568cb4eSPaul Mackerras 3451beb6a7dSBenjamin Herrenschmidt DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); 3461beb6a7dSBenjamin Herrenschmidt 3477568cb4eSPaul Mackerras while ((child = of_get_next_child(node, child)) != NULL) { 3481beb6a7dSBenjamin Herrenschmidt DBG(" * %s\n", child->full_name); 349e2eb6392SStephen Rothwell reg = of_get_property(child, "reg", ®len); 3507568cb4eSPaul Mackerras if (reg == NULL || reglen < 20) 3517568cb4eSPaul Mackerras continue; 3527568cb4eSPaul Mackerras devfn = (reg[0] >> 8) & 0xff; 3531beb6a7dSBenjamin Herrenschmidt 3547568cb4eSPaul Mackerras /* create a new pci_dev for this device */ 3557568cb4eSPaul Mackerras dev = of_create_pci_dev(child, bus, devfn); 3567568cb4eSPaul Mackerras if (!dev) 3577568cb4eSPaul Mackerras continue; 3581beb6a7dSBenjamin Herrenschmidt DBG("dev header type: %x\n", dev->hdr_type); 3591beb6a7dSBenjamin Herrenschmidt 3607568cb4eSPaul Mackerras if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 3617568cb4eSPaul Mackerras dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 3627568cb4eSPaul Mackerras of_scan_pci_bridge(child, dev); 3637568cb4eSPaul Mackerras } 3647568cb4eSPaul Mackerras 3657568cb4eSPaul Mackerras do_bus_setup(bus); 3667568cb4eSPaul Mackerras } 3677568cb4eSPaul Mackerras EXPORT_SYMBOL(of_scan_bus); 3687568cb4eSPaul Mackerras 3697568cb4eSPaul Mackerras void __devinit of_scan_pci_bridge(struct device_node *node, 3707568cb4eSPaul Mackerras struct pci_dev *dev) 3717568cb4eSPaul Mackerras { 3727568cb4eSPaul Mackerras struct pci_bus *bus; 373a7f67bdfSJeremy Kerr const u32 *busrange, *ranges; 3747568cb4eSPaul Mackerras int len, i, mode; 3757568cb4eSPaul Mackerras struct resource *res; 3767568cb4eSPaul Mackerras unsigned int flags; 3777568cb4eSPaul Mackerras u64 size; 3787568cb4eSPaul Mackerras 3791beb6a7dSBenjamin Herrenschmidt DBG("of_scan_pci_bridge(%s)\n", node->full_name); 3801beb6a7dSBenjamin Herrenschmidt 3817568cb4eSPaul Mackerras /* parse bus-range property */ 382e2eb6392SStephen Rothwell busrange = of_get_property(node, "bus-range", &len); 3837568cb4eSPaul Mackerras if (busrange == NULL || len != 8) { 3841beb6a7dSBenjamin Herrenschmidt printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", 3857568cb4eSPaul Mackerras node->full_name); 3867568cb4eSPaul Mackerras return; 3877568cb4eSPaul Mackerras } 388e2eb6392SStephen Rothwell ranges = of_get_property(node, "ranges", &len); 3897568cb4eSPaul Mackerras if (ranges == NULL) { 3901beb6a7dSBenjamin Herrenschmidt printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", 3917568cb4eSPaul Mackerras node->full_name); 3927568cb4eSPaul Mackerras return; 3937568cb4eSPaul Mackerras } 3947568cb4eSPaul Mackerras 3957568cb4eSPaul Mackerras bus = pci_add_new_bus(dev->bus, dev, busrange[0]); 3967568cb4eSPaul Mackerras if (!bus) { 3977568cb4eSPaul Mackerras printk(KERN_ERR "Failed to create pci bus for %s\n", 3987568cb4eSPaul Mackerras node->full_name); 3997568cb4eSPaul Mackerras return; 4007568cb4eSPaul Mackerras } 4017568cb4eSPaul Mackerras 4027568cb4eSPaul Mackerras bus->primary = dev->bus->number; 4037568cb4eSPaul Mackerras bus->subordinate = busrange[1]; 4047568cb4eSPaul Mackerras bus->bridge_ctl = 0; 4057568cb4eSPaul Mackerras bus->sysdata = node; 4067568cb4eSPaul Mackerras 4077568cb4eSPaul Mackerras /* parse ranges property */ 4087568cb4eSPaul Mackerras /* PCI #address-cells == 3 and #size-cells == 2 always */ 4097568cb4eSPaul Mackerras res = &dev->resource[PCI_BRIDGE_RESOURCES]; 4107568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { 4117568cb4eSPaul Mackerras res->flags = 0; 4127568cb4eSPaul Mackerras bus->resource[i] = res; 4137568cb4eSPaul Mackerras ++res; 4147568cb4eSPaul Mackerras } 4157568cb4eSPaul Mackerras i = 1; 4167568cb4eSPaul Mackerras for (; len >= 32; len -= 32, ranges += 8) { 4177568cb4eSPaul Mackerras flags = pci_parse_of_flags(ranges[0]); 418327e22dfSJon Loeliger size = of_read_number(&ranges[6], 2); 4197568cb4eSPaul Mackerras if (flags == 0 || size == 0) 4207568cb4eSPaul Mackerras continue; 4217568cb4eSPaul Mackerras if (flags & IORESOURCE_IO) { 4227568cb4eSPaul Mackerras res = bus->resource[0]; 4237568cb4eSPaul Mackerras if (res->flags) { 4247568cb4eSPaul Mackerras printk(KERN_ERR "PCI: ignoring extra I/O range" 4257568cb4eSPaul Mackerras " for bridge %s\n", node->full_name); 4267568cb4eSPaul Mackerras continue; 4277568cb4eSPaul Mackerras } 4287568cb4eSPaul Mackerras } else { 4297568cb4eSPaul Mackerras if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { 4307568cb4eSPaul Mackerras printk(KERN_ERR "PCI: too many memory ranges" 4317568cb4eSPaul Mackerras " for bridge %s\n", node->full_name); 4327568cb4eSPaul Mackerras continue; 4337568cb4eSPaul Mackerras } 4347568cb4eSPaul Mackerras res = bus->resource[i]; 4357568cb4eSPaul Mackerras ++i; 4367568cb4eSPaul Mackerras } 437327e22dfSJon Loeliger res->start = of_read_number(&ranges[1], 2); 4387568cb4eSPaul Mackerras res->end = res->start + size - 1; 4397568cb4eSPaul Mackerras res->flags = flags; 4407568cb4eSPaul Mackerras fixup_resource(res, dev); 4417568cb4eSPaul Mackerras } 4427568cb4eSPaul Mackerras sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 4437568cb4eSPaul Mackerras bus->number); 4441beb6a7dSBenjamin Herrenschmidt DBG(" bus name: %s\n", bus->name); 4457568cb4eSPaul Mackerras 4467568cb4eSPaul Mackerras mode = PCI_PROBE_NORMAL; 4477568cb4eSPaul Mackerras if (ppc_md.pci_probe_mode) 4487568cb4eSPaul Mackerras mode = ppc_md.pci_probe_mode(bus); 4491beb6a7dSBenjamin Herrenschmidt DBG(" probe mode: %d\n", mode); 4501beb6a7dSBenjamin Herrenschmidt 4517568cb4eSPaul Mackerras if (mode == PCI_PROBE_DEVTREE) 4527568cb4eSPaul Mackerras of_scan_bus(node, bus); 4537568cb4eSPaul Mackerras else if (mode == PCI_PROBE_NORMAL) 4547568cb4eSPaul Mackerras pci_scan_child_bus(bus); 4557568cb4eSPaul Mackerras } 4567568cb4eSPaul Mackerras EXPORT_SYMBOL(of_scan_pci_bridge); 4577568cb4eSPaul Mackerras 4587568cb4eSPaul Mackerras void __devinit scan_phb(struct pci_controller *hose) 4597568cb4eSPaul Mackerras { 4607568cb4eSPaul Mackerras struct pci_bus *bus; 461*44ef3390SStephen Rothwell struct device_node *node = hose->dn; 4627568cb4eSPaul Mackerras int i, mode; 4637568cb4eSPaul Mackerras struct resource *res; 4647568cb4eSPaul Mackerras 4651beb6a7dSBenjamin Herrenschmidt DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 4661beb6a7dSBenjamin Herrenschmidt 467803d4573SBenjamin Herrenschmidt bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); 4687568cb4eSPaul Mackerras if (bus == NULL) { 4697568cb4eSPaul Mackerras printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 4707568cb4eSPaul Mackerras hose->global_number); 4717568cb4eSPaul Mackerras return; 4727568cb4eSPaul Mackerras } 4737568cb4eSPaul Mackerras bus->secondary = hose->first_busno; 4747568cb4eSPaul Mackerras hose->bus = bus; 4757568cb4eSPaul Mackerras 4763d5134eeSBenjamin Herrenschmidt pcibios_map_io_space(bus); 4773d5134eeSBenjamin Herrenschmidt 4787568cb4eSPaul Mackerras bus->resource[0] = res = &hose->io_resource; 4793d5134eeSBenjamin Herrenschmidt if (res->flags && request_resource(&ioport_resource, res)) { 4807568cb4eSPaul Mackerras printk(KERN_ERR "Failed to request PCI IO region " 4817568cb4eSPaul Mackerras "on PCI domain %04x\n", hose->global_number); 4823d5134eeSBenjamin Herrenschmidt DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", 4833d5134eeSBenjamin Herrenschmidt res->start, res->end); 4843d5134eeSBenjamin Herrenschmidt } 4857568cb4eSPaul Mackerras 4867568cb4eSPaul Mackerras for (i = 0; i < 3; ++i) { 4877568cb4eSPaul Mackerras res = &hose->mem_resources[i]; 4887568cb4eSPaul Mackerras bus->resource[i+1] = res; 4897568cb4eSPaul Mackerras if (res->flags && request_resource(&iomem_resource, res)) 4907568cb4eSPaul Mackerras printk(KERN_ERR "Failed to request PCI memory region " 4917568cb4eSPaul Mackerras "on PCI domain %04x\n", hose->global_number); 4927568cb4eSPaul Mackerras } 4937568cb4eSPaul Mackerras 4947568cb4eSPaul Mackerras mode = PCI_PROBE_NORMAL; 49599a565baSs.hauer@pengutronix.de 4961beb6a7dSBenjamin Herrenschmidt if (node && ppc_md.pci_probe_mode) 4977568cb4eSPaul Mackerras mode = ppc_md.pci_probe_mode(bus); 4981beb6a7dSBenjamin Herrenschmidt DBG(" probe mode: %d\n", mode); 4997568cb4eSPaul Mackerras if (mode == PCI_PROBE_DEVTREE) { 5007568cb4eSPaul Mackerras bus->subordinate = hose->last_busno; 5017568cb4eSPaul Mackerras of_scan_bus(node, bus); 5027568cb4eSPaul Mackerras } 50399a565baSs.hauer@pengutronix.de 5047568cb4eSPaul Mackerras if (mode == PCI_PROBE_NORMAL) 5057568cb4eSPaul Mackerras hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 5067568cb4eSPaul Mackerras } 5077568cb4eSPaul Mackerras 5087568cb4eSPaul Mackerras static int __init pcibios_init(void) 5097568cb4eSPaul Mackerras { 5107568cb4eSPaul Mackerras struct pci_controller *hose, *tmp; 5117568cb4eSPaul Mackerras 5127568cb4eSPaul Mackerras /* For now, override phys_mem_access_prot. If we need it, 5137568cb4eSPaul Mackerras * later, we may move that initialization to each ppc_md 5147568cb4eSPaul Mackerras */ 5157568cb4eSPaul Mackerras ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 5167568cb4eSPaul Mackerras 517e884e9c5SOlof Johansson printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); 5187568cb4eSPaul Mackerras 5197568cb4eSPaul Mackerras /* Scan all of the recorded PCI controllers. */ 52092eb4602SJohn Rose list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 5217568cb4eSPaul Mackerras scan_phb(hose); 52292eb4602SJohn Rose pci_bus_add_devices(hose->bus); 52392eb4602SJohn Rose } 5247568cb4eSPaul Mackerras 5257568cb4eSPaul Mackerras if (pci_probe_only) 5267568cb4eSPaul Mackerras pcibios_claim_of_setup(); 5277568cb4eSPaul Mackerras else 5287568cb4eSPaul Mackerras /* FIXME: `else' will be removed when 5297568cb4eSPaul Mackerras pci_assign_unassigned_resources() is able to work 5307568cb4eSPaul Mackerras correctly with [partially] allocated PCI tree. */ 5317568cb4eSPaul Mackerras pci_assign_unassigned_resources(); 5327568cb4eSPaul Mackerras 5337568cb4eSPaul Mackerras /* Call machine dependent final fixup */ 5347568cb4eSPaul Mackerras if (ppc_md.pcibios_fixup) 5357568cb4eSPaul Mackerras ppc_md.pcibios_fixup(); 5367568cb4eSPaul Mackerras 537e884e9c5SOlof Johansson printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 5387568cb4eSPaul Mackerras 5397568cb4eSPaul Mackerras return 0; 5407568cb4eSPaul Mackerras } 5417568cb4eSPaul Mackerras 5427568cb4eSPaul Mackerras subsys_initcall(pcibios_init); 5437568cb4eSPaul Mackerras 5447568cb4eSPaul Mackerras int pcibios_enable_device(struct pci_dev *dev, int mask) 5457568cb4eSPaul Mackerras { 5467568cb4eSPaul Mackerras u16 cmd, oldcmd; 5477568cb4eSPaul Mackerras int i; 5487568cb4eSPaul Mackerras 5497568cb4eSPaul Mackerras pci_read_config_word(dev, PCI_COMMAND, &cmd); 5507568cb4eSPaul Mackerras oldcmd = cmd; 5517568cb4eSPaul Mackerras 5527568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES; i++) { 5537568cb4eSPaul Mackerras struct resource *res = &dev->resource[i]; 5547568cb4eSPaul Mackerras 5557568cb4eSPaul Mackerras /* Only set up the requested stuff */ 5567568cb4eSPaul Mackerras if (!(mask & (1<<i))) 5577568cb4eSPaul Mackerras continue; 5587568cb4eSPaul Mackerras 5597568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 5607568cb4eSPaul Mackerras cmd |= PCI_COMMAND_IO; 5617568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 5627568cb4eSPaul Mackerras cmd |= PCI_COMMAND_MEMORY; 5637568cb4eSPaul Mackerras } 5647568cb4eSPaul Mackerras 5657568cb4eSPaul Mackerras if (cmd != oldcmd) { 5667568cb4eSPaul Mackerras printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n", 5677568cb4eSPaul Mackerras pci_name(dev), cmd); 5687568cb4eSPaul Mackerras /* Enable the appropriate bits in the PCI command register. */ 5697568cb4eSPaul Mackerras pci_write_config_word(dev, PCI_COMMAND, cmd); 5707568cb4eSPaul Mackerras } 5717568cb4eSPaul Mackerras return 0; 5727568cb4eSPaul Mackerras } 5737568cb4eSPaul Mackerras 5747568cb4eSPaul Mackerras /* Decide whether to display the domain number in /proc */ 5757568cb4eSPaul Mackerras int pci_proc_domain(struct pci_bus *bus) 5767568cb4eSPaul Mackerras { 5777568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(bus); 5783eb523b9SArnd Bergmann return hose->buid != 0; 579eecba334SStephen Rothwell } 5807568cb4eSPaul Mackerras 5817568cb4eSPaul Mackerras void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 5827568cb4eSPaul Mackerras struct device_node *dev, int prim) 5837568cb4eSPaul Mackerras { 584a7f67bdfSJeremy Kerr const unsigned int *ranges; 585a7f67bdfSJeremy Kerr unsigned int pci_space; 5867568cb4eSPaul Mackerras unsigned long size; 5877568cb4eSPaul Mackerras int rlen = 0; 5887568cb4eSPaul Mackerras int memno = 0; 5897568cb4eSPaul Mackerras struct resource *res; 590a8bda5ddSStephen Rothwell int np, na = of_n_addr_cells(dev); 5917568cb4eSPaul Mackerras unsigned long pci_addr, cpu_phys_addr; 5927568cb4eSPaul Mackerras 5937568cb4eSPaul Mackerras np = na + 5; 5947568cb4eSPaul Mackerras 5957568cb4eSPaul Mackerras /* From "PCI Binding to 1275" 5967568cb4eSPaul Mackerras * The ranges property is laid out as an array of elements, 5977568cb4eSPaul Mackerras * each of which comprises: 5987568cb4eSPaul Mackerras * cells 0 - 2: a PCI address 5997568cb4eSPaul Mackerras * cells 3 or 3+4: a CPU physical address 6007568cb4eSPaul Mackerras * (size depending on dev->n_addr_cells) 6017568cb4eSPaul Mackerras * cells 4+5 or 5+6: the size of the range 6027568cb4eSPaul Mackerras */ 603e2eb6392SStephen Rothwell ranges = of_get_property(dev, "ranges", &rlen); 604b5166cc2SBenjamin Herrenschmidt if (ranges == NULL) 605b5166cc2SBenjamin Herrenschmidt return; 606b5166cc2SBenjamin Herrenschmidt hose->io_base_phys = 0; 6077568cb4eSPaul Mackerras while ((rlen -= np * sizeof(unsigned int)) >= 0) { 6087568cb4eSPaul Mackerras res = NULL; 6097568cb4eSPaul Mackerras pci_space = ranges[0]; 6107568cb4eSPaul Mackerras pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; 611e557a1c9SBenjamin Herrenschmidt cpu_phys_addr = of_translate_address(dev, &ranges[3]); 6127568cb4eSPaul Mackerras size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; 6137568cb4eSPaul Mackerras ranges += np; 6147568cb4eSPaul Mackerras if (size == 0) 6157568cb4eSPaul Mackerras continue; 6167568cb4eSPaul Mackerras 6177568cb4eSPaul Mackerras /* Now consume following elements while they are contiguous */ 6187568cb4eSPaul Mackerras while (rlen >= np * sizeof(unsigned int)) { 6197568cb4eSPaul Mackerras unsigned long addr, phys; 6207568cb4eSPaul Mackerras 6217568cb4eSPaul Mackerras if (ranges[0] != pci_space) 6227568cb4eSPaul Mackerras break; 6237568cb4eSPaul Mackerras addr = ((unsigned long)ranges[1] << 32) | ranges[2]; 6247568cb4eSPaul Mackerras phys = ranges[3]; 6257568cb4eSPaul Mackerras if (na >= 2) 6267568cb4eSPaul Mackerras phys = (phys << 32) | ranges[4]; 6277568cb4eSPaul Mackerras if (addr != pci_addr + size || 6287568cb4eSPaul Mackerras phys != cpu_phys_addr + size) 6297568cb4eSPaul Mackerras break; 6307568cb4eSPaul Mackerras 6317568cb4eSPaul Mackerras size += ((unsigned long)ranges[na+3] << 32) 6327568cb4eSPaul Mackerras | ranges[na+4]; 6337568cb4eSPaul Mackerras ranges += np; 6347568cb4eSPaul Mackerras rlen -= np * sizeof(unsigned int); 6357568cb4eSPaul Mackerras } 6367568cb4eSPaul Mackerras 6377568cb4eSPaul Mackerras switch ((pci_space >> 24) & 0x3) { 6387568cb4eSPaul Mackerras case 1: /* I/O space */ 63911fbb00cSPaul Mackerras hose->io_base_phys = cpu_phys_addr - pci_addr; 64011fbb00cSPaul Mackerras /* handle from 0 to top of I/O window */ 64111fbb00cSPaul Mackerras hose->pci_io_size = pci_addr + size; 6427568cb4eSPaul Mackerras 6437568cb4eSPaul Mackerras res = &hose->io_resource; 6447568cb4eSPaul Mackerras res->flags = IORESOURCE_IO; 6457568cb4eSPaul Mackerras res->start = pci_addr; 6467568cb4eSPaul Mackerras DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number, 6477568cb4eSPaul Mackerras res->start, res->start + size - 1); 6487568cb4eSPaul Mackerras break; 6497568cb4eSPaul Mackerras case 2: /* memory space */ 6507568cb4eSPaul Mackerras memno = 0; 6517568cb4eSPaul Mackerras while (memno < 3 && hose->mem_resources[memno].flags) 6527568cb4eSPaul Mackerras ++memno; 6537568cb4eSPaul Mackerras 6547568cb4eSPaul Mackerras if (memno == 0) 6557568cb4eSPaul Mackerras hose->pci_mem_offset = cpu_phys_addr - pci_addr; 6567568cb4eSPaul Mackerras if (memno < 3) { 6577568cb4eSPaul Mackerras res = &hose->mem_resources[memno]; 6587568cb4eSPaul Mackerras res->flags = IORESOURCE_MEM; 6597568cb4eSPaul Mackerras res->start = cpu_phys_addr; 6607568cb4eSPaul Mackerras DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number, 6617568cb4eSPaul Mackerras res->start, res->start + size - 1); 6627568cb4eSPaul Mackerras } 6637568cb4eSPaul Mackerras break; 6647568cb4eSPaul Mackerras } 6657568cb4eSPaul Mackerras if (res != NULL) { 6667568cb4eSPaul Mackerras res->name = dev->full_name; 6677568cb4eSPaul Mackerras res->end = res->start + size - 1; 6687568cb4eSPaul Mackerras res->parent = NULL; 6697568cb4eSPaul Mackerras res->sibling = NULL; 6707568cb4eSPaul Mackerras res->child = NULL; 6717568cb4eSPaul Mackerras } 6727568cb4eSPaul Mackerras } 6737568cb4eSPaul Mackerras } 6747568cb4eSPaul Mackerras 6753d5134eeSBenjamin Herrenschmidt #ifdef CONFIG_HOTPLUG 6763d5134eeSBenjamin Herrenschmidt 6773d5134eeSBenjamin Herrenschmidt int pcibios_unmap_io_space(struct pci_bus *bus) 6787568cb4eSPaul Mackerras { 6793d5134eeSBenjamin Herrenschmidt struct pci_controller *hose; 6807568cb4eSPaul Mackerras 6813d5134eeSBenjamin Herrenschmidt WARN_ON(bus == NULL); 682de821204SBenjamin Herrenschmidt 6833d5134eeSBenjamin Herrenschmidt /* If this is not a PHB, we only flush the hash table over 6843d5134eeSBenjamin Herrenschmidt * the area mapped by this bridge. We don't play with the PTE 6853d5134eeSBenjamin Herrenschmidt * mappings since we might have to deal with sub-page alignemnts 6863d5134eeSBenjamin Herrenschmidt * so flushing the hash table is the only sane way to make sure 6873d5134eeSBenjamin Herrenschmidt * that no hash entries are covering that removed bridge area 6883d5134eeSBenjamin Herrenschmidt * while still allowing other busses overlapping those pages 689de821204SBenjamin Herrenschmidt */ 6903d5134eeSBenjamin Herrenschmidt if (bus->self) { 6913d5134eeSBenjamin Herrenschmidt struct resource *res = bus->resource[0]; 6923d5134eeSBenjamin Herrenschmidt 6933d5134eeSBenjamin Herrenschmidt DBG("IO unmapping for PCI-PCI bridge %s\n", 6943d5134eeSBenjamin Herrenschmidt pci_name(bus->self)); 6953d5134eeSBenjamin Herrenschmidt 6963d5134eeSBenjamin Herrenschmidt __flush_hash_table_range(&init_mm, res->start + _IO_BASE, 6973d5134eeSBenjamin Herrenschmidt res->end - res->start + 1); 6983d5134eeSBenjamin Herrenschmidt return 0; 6997568cb4eSPaul Mackerras } 7007568cb4eSPaul Mackerras 7013d5134eeSBenjamin Herrenschmidt /* Get the host bridge */ 7023d5134eeSBenjamin Herrenschmidt hose = pci_bus_to_host(bus); 7033d5134eeSBenjamin Herrenschmidt 7043d5134eeSBenjamin Herrenschmidt /* Check if we have IOs allocated */ 7053d5134eeSBenjamin Herrenschmidt if (hose->io_base_alloc == 0) 7063d5134eeSBenjamin Herrenschmidt return 0; 7073d5134eeSBenjamin Herrenschmidt 708*44ef3390SStephen Rothwell DBG("IO unmapping for PHB %s\n", hose->dn->full_name); 7093d5134eeSBenjamin Herrenschmidt DBG(" alloc=0x%p\n", hose->io_base_alloc); 7103d5134eeSBenjamin Herrenschmidt 7113d5134eeSBenjamin Herrenschmidt /* This is a PHB, we fully unmap the IO area */ 7123d5134eeSBenjamin Herrenschmidt vunmap(hose->io_base_alloc); 7133d5134eeSBenjamin Herrenschmidt 7143d5134eeSBenjamin Herrenschmidt return 0; 7153d5134eeSBenjamin Herrenschmidt } 7163d5134eeSBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(pcibios_unmap_io_space); 7173d5134eeSBenjamin Herrenschmidt 7183d5134eeSBenjamin Herrenschmidt #endif /* CONFIG_HOTPLUG */ 7193d5134eeSBenjamin Herrenschmidt 7203d5134eeSBenjamin Herrenschmidt int __devinit pcibios_map_io_space(struct pci_bus *bus) 7217568cb4eSPaul Mackerras { 7223d5134eeSBenjamin Herrenschmidt struct vm_struct *area; 7233d5134eeSBenjamin Herrenschmidt unsigned long phys_page; 7243d5134eeSBenjamin Herrenschmidt unsigned long size_page; 7257568cb4eSPaul Mackerras unsigned long io_virt_offset; 7263d5134eeSBenjamin Herrenschmidt struct pci_controller *hose; 7277568cb4eSPaul Mackerras 7283d5134eeSBenjamin Herrenschmidt WARN_ON(bus == NULL); 729de821204SBenjamin Herrenschmidt 7303d5134eeSBenjamin Herrenschmidt /* If this not a PHB, nothing to do, page tables still exist and 7313d5134eeSBenjamin Herrenschmidt * thus HPTEs will be faulted in when needed 7323d5134eeSBenjamin Herrenschmidt */ 7333d5134eeSBenjamin Herrenschmidt if (bus->self) { 7343d5134eeSBenjamin Herrenschmidt DBG("IO mapping for PCI-PCI bridge %s\n", 7353d5134eeSBenjamin Herrenschmidt pci_name(bus->self)); 7363d5134eeSBenjamin Herrenschmidt DBG(" virt=0x%016lx...0x%016lx\n", 7373d5134eeSBenjamin Herrenschmidt bus->resource[0]->start + _IO_BASE, 7383d5134eeSBenjamin Herrenschmidt bus->resource[0]->end + _IO_BASE); 7397568cb4eSPaul Mackerras return 0; 7407568cb4eSPaul Mackerras } 7417568cb4eSPaul Mackerras 7423d5134eeSBenjamin Herrenschmidt /* Get the host bridge */ 7433d5134eeSBenjamin Herrenschmidt hose = pci_bus_to_host(bus); 7443d5134eeSBenjamin Herrenschmidt phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE); 7453d5134eeSBenjamin Herrenschmidt size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE); 7467568cb4eSPaul Mackerras 7473d5134eeSBenjamin Herrenschmidt /* Make sure IO area address is clear */ 7483d5134eeSBenjamin Herrenschmidt hose->io_base_alloc = NULL; 7497568cb4eSPaul Mackerras 7503d5134eeSBenjamin Herrenschmidt /* If there's no IO to map on that bus, get away too */ 7513d5134eeSBenjamin Herrenschmidt if (hose->pci_io_size == 0 || hose->io_base_phys == 0) 7523d5134eeSBenjamin Herrenschmidt return 0; 7533d5134eeSBenjamin Herrenschmidt 7543d5134eeSBenjamin Herrenschmidt /* Let's allocate some IO space for that guy. We don't pass 7553d5134eeSBenjamin Herrenschmidt * VM_IOREMAP because we don't care about alignment tricks that 7563d5134eeSBenjamin Herrenschmidt * the core does in that case. Maybe we should due to stupid card 7573d5134eeSBenjamin Herrenschmidt * with incomplete address decoding but I'd rather not deal with 7583d5134eeSBenjamin Herrenschmidt * those outside of the reserved 64K legacy region. 7593d5134eeSBenjamin Herrenschmidt */ 7603d5134eeSBenjamin Herrenschmidt area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END); 7613d5134eeSBenjamin Herrenschmidt if (area == NULL) 7623d5134eeSBenjamin Herrenschmidt return -ENOMEM; 7633d5134eeSBenjamin Herrenschmidt hose->io_base_alloc = area->addr; 7643d5134eeSBenjamin Herrenschmidt hose->io_base_virt = (void __iomem *)(area->addr + 7653d5134eeSBenjamin Herrenschmidt hose->io_base_phys - phys_page); 7663d5134eeSBenjamin Herrenschmidt 767*44ef3390SStephen Rothwell DBG("IO mapping for PHB %s\n", hose->dn->full_name); 7683d5134eeSBenjamin Herrenschmidt DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", 7693d5134eeSBenjamin Herrenschmidt hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); 7703d5134eeSBenjamin Herrenschmidt DBG(" size=0x%016lx (alloc=0x%016lx)\n", 7713d5134eeSBenjamin Herrenschmidt hose->pci_io_size, size_page); 7723d5134eeSBenjamin Herrenschmidt 7733d5134eeSBenjamin Herrenschmidt /* Establish the mapping */ 7743d5134eeSBenjamin Herrenschmidt if (__ioremap_at(phys_page, area->addr, size_page, 7753d5134eeSBenjamin Herrenschmidt _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL) 7763d5134eeSBenjamin Herrenschmidt return -ENOMEM; 7773d5134eeSBenjamin Herrenschmidt 7783d5134eeSBenjamin Herrenschmidt /* Fixup hose IO resource */ 7793d5134eeSBenjamin Herrenschmidt io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE; 7803d5134eeSBenjamin Herrenschmidt hose->io_resource.start += io_virt_offset; 7813d5134eeSBenjamin Herrenschmidt hose->io_resource.end += io_virt_offset; 7823d5134eeSBenjamin Herrenschmidt 7833d5134eeSBenjamin Herrenschmidt DBG(" hose->io_resource=0x%016lx...0x%016lx\n", 7843d5134eeSBenjamin Herrenschmidt hose->io_resource.start, hose->io_resource.end); 7857568cb4eSPaul Mackerras 7867568cb4eSPaul Mackerras return 0; 7877568cb4eSPaul Mackerras } 7883d5134eeSBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(pcibios_map_io_space); 7897568cb4eSPaul Mackerras 7907568cb4eSPaul Mackerras static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) 7917568cb4eSPaul Mackerras { 7927568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 793c256f4b9SAnton Blanchard unsigned long offset; 7947568cb4eSPaul Mackerras 7957568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) { 7963d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 797c256f4b9SAnton Blanchard res->start += offset; 798c256f4b9SAnton Blanchard res->end += offset; 7997568cb4eSPaul Mackerras } else if (res->flags & IORESOURCE_MEM) { 8007568cb4eSPaul Mackerras res->start += hose->pci_mem_offset; 8017568cb4eSPaul Mackerras res->end += hose->pci_mem_offset; 8027568cb4eSPaul Mackerras } 8037568cb4eSPaul Mackerras } 8047568cb4eSPaul Mackerras 8057568cb4eSPaul Mackerras void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, 8067568cb4eSPaul Mackerras struct pci_bus *bus) 8077568cb4eSPaul Mackerras { 8087568cb4eSPaul Mackerras /* Update device resources. */ 8097568cb4eSPaul Mackerras int i; 8107568cb4eSPaul Mackerras 8113d5134eeSBenjamin Herrenschmidt DBG("%s: Fixup resources:\n", pci_name(dev)); 8123d5134eeSBenjamin Herrenschmidt for (i = 0; i < PCI_NUM_RESOURCES; i++) { 8133d5134eeSBenjamin Herrenschmidt struct resource *res = &dev->resource[i]; 8143d5134eeSBenjamin Herrenschmidt if (!res->flags) 8153d5134eeSBenjamin Herrenschmidt continue; 8163d5134eeSBenjamin Herrenschmidt 8173d5134eeSBenjamin Herrenschmidt DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n", 8183d5134eeSBenjamin Herrenschmidt i, res->flags, res->start, res->end); 8193d5134eeSBenjamin Herrenschmidt 8203d5134eeSBenjamin Herrenschmidt fixup_resource(res, dev); 8213d5134eeSBenjamin Herrenschmidt 8223d5134eeSBenjamin Herrenschmidt DBG(" > %08lx:0x%016lx...0x%016lx\n", 8233d5134eeSBenjamin Herrenschmidt res->flags, res->start, res->end); 8243d5134eeSBenjamin Herrenschmidt } 8257568cb4eSPaul Mackerras } 8267568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_fixup_device_resources); 8277568cb4eSPaul Mackerras 82812d04eefSBenjamin Herrenschmidt void __devinit pcibios_setup_new_device(struct pci_dev *dev) 82912d04eefSBenjamin Herrenschmidt { 83012d04eefSBenjamin Herrenschmidt struct dev_archdata *sd = &dev->dev.archdata; 83112d04eefSBenjamin Herrenschmidt 83212d04eefSBenjamin Herrenschmidt sd->of_node = pci_device_to_OF_node(dev); 83312d04eefSBenjamin Herrenschmidt 83412d04eefSBenjamin Herrenschmidt DBG("PCI device %s OF node: %s\n", pci_name(dev), 83512d04eefSBenjamin Herrenschmidt sd->of_node ? sd->of_node->full_name : "<none>"); 83612d04eefSBenjamin Herrenschmidt 83712d04eefSBenjamin Herrenschmidt sd->dma_ops = pci_dma_ops; 83812d04eefSBenjamin Herrenschmidt #ifdef CONFIG_NUMA 83912d04eefSBenjamin Herrenschmidt sd->numa_node = pcibus_to_node(dev->bus); 84012d04eefSBenjamin Herrenschmidt #else 84112d04eefSBenjamin Herrenschmidt sd->numa_node = -1; 84212d04eefSBenjamin Herrenschmidt #endif 84312d04eefSBenjamin Herrenschmidt if (ppc_md.pci_dma_dev_setup) 84412d04eefSBenjamin Herrenschmidt ppc_md.pci_dma_dev_setup(dev); 84512d04eefSBenjamin Herrenschmidt } 84612d04eefSBenjamin Herrenschmidt EXPORT_SYMBOL(pcibios_setup_new_device); 847463ce0e1SBenjamin Herrenschmidt 8487568cb4eSPaul Mackerras static void __devinit do_bus_setup(struct pci_bus *bus) 8497568cb4eSPaul Mackerras { 8507568cb4eSPaul Mackerras struct pci_dev *dev; 8517568cb4eSPaul Mackerras 85212d04eefSBenjamin Herrenschmidt if (ppc_md.pci_dma_bus_setup) 85312d04eefSBenjamin Herrenschmidt ppc_md.pci_dma_bus_setup(bus); 8547568cb4eSPaul Mackerras 8557568cb4eSPaul Mackerras list_for_each_entry(dev, &bus->devices, bus_list) 85612d04eefSBenjamin Herrenschmidt pcibios_setup_new_device(dev); 8577568cb4eSPaul Mackerras 858f90bb153SBenjamin Herrenschmidt /* Read default IRQs and fixup if necessary */ 859f90bb153SBenjamin Herrenschmidt list_for_each_entry(dev, &bus->devices, bus_list) { 860f90bb153SBenjamin Herrenschmidt pci_read_irq_line(dev); 861f90bb153SBenjamin Herrenschmidt if (ppc_md.pci_irq_fixup) 862f90bb153SBenjamin Herrenschmidt ppc_md.pci_irq_fixup(dev); 863f90bb153SBenjamin Herrenschmidt } 8647568cb4eSPaul Mackerras } 8657568cb4eSPaul Mackerras 8667568cb4eSPaul Mackerras void __devinit pcibios_fixup_bus(struct pci_bus *bus) 8677568cb4eSPaul Mackerras { 8687568cb4eSPaul Mackerras struct pci_dev *dev = bus->self; 8694c9d2800SBenjamin Herrenschmidt struct device_node *np; 8704c9d2800SBenjamin Herrenschmidt 8714c9d2800SBenjamin Herrenschmidt np = pci_bus_to_OF_node(bus); 8724c9d2800SBenjamin Herrenschmidt 8734c9d2800SBenjamin Herrenschmidt DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>"); 8747568cb4eSPaul Mackerras 8757568cb4eSPaul Mackerras if (dev && pci_probe_only && 8767568cb4eSPaul Mackerras (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 8777568cb4eSPaul Mackerras /* This is a subordinate bridge */ 8787568cb4eSPaul Mackerras 8797568cb4eSPaul Mackerras pci_read_bridge_bases(bus); 8807568cb4eSPaul Mackerras pcibios_fixup_device_resources(dev, bus); 8817568cb4eSPaul Mackerras } 8827568cb4eSPaul Mackerras 8837568cb4eSPaul Mackerras do_bus_setup(bus); 8847568cb4eSPaul Mackerras 8857568cb4eSPaul Mackerras if (!pci_probe_only) 8867568cb4eSPaul Mackerras return; 8877568cb4eSPaul Mackerras 8887568cb4eSPaul Mackerras list_for_each_entry(dev, &bus->devices, bus_list) 8897568cb4eSPaul Mackerras if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) 8907568cb4eSPaul Mackerras pcibios_fixup_device_resources(dev, bus); 8917568cb4eSPaul Mackerras } 8927568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_fixup_bus); 8937568cb4eSPaul Mackerras 894f2c4583aSBenjamin Herrenschmidt unsigned long pci_address_to_pio(phys_addr_t address) 895d4e4b352SStephen Rothwell { 896d4e4b352SStephen Rothwell struct pci_controller *hose, *tmp; 897d4e4b352SStephen Rothwell 898d4e4b352SStephen Rothwell list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 899d4e4b352SStephen Rothwell if (address >= hose->io_base_phys && 900f2c4583aSBenjamin Herrenschmidt address < (hose->io_base_phys + hose->pci_io_size)) { 901f2c4583aSBenjamin Herrenschmidt unsigned long base = 9023d5134eeSBenjamin Herrenschmidt (unsigned long)hose->io_base_virt - _IO_BASE; 903f2c4583aSBenjamin Herrenschmidt return base + (address - hose->io_base_phys); 904f2c4583aSBenjamin Herrenschmidt } 905d4e4b352SStephen Rothwell } 906d4e4b352SStephen Rothwell return (unsigned int)-1; 907d4e4b352SStephen Rothwell } 908d4e4b352SStephen Rothwell EXPORT_SYMBOL_GPL(pci_address_to_pio); 909d4e4b352SStephen Rothwell 9107568cb4eSPaul Mackerras 9117568cb4eSPaul Mackerras #define IOBASE_BRIDGE_NUMBER 0 9127568cb4eSPaul Mackerras #define IOBASE_MEMORY 1 9137568cb4eSPaul Mackerras #define IOBASE_IO 2 9147568cb4eSPaul Mackerras #define IOBASE_ISA_IO 3 9157568cb4eSPaul Mackerras #define IOBASE_ISA_MEM 4 9167568cb4eSPaul Mackerras 9177568cb4eSPaul Mackerras long sys_pciconfig_iobase(long which, unsigned long in_bus, 9187568cb4eSPaul Mackerras unsigned long in_devfn) 9197568cb4eSPaul Mackerras { 9207568cb4eSPaul Mackerras struct pci_controller* hose; 9217568cb4eSPaul Mackerras struct list_head *ln; 9227568cb4eSPaul Mackerras struct pci_bus *bus = NULL; 9237568cb4eSPaul Mackerras struct device_node *hose_node; 9247568cb4eSPaul Mackerras 9257568cb4eSPaul Mackerras /* Argh ! Please forgive me for that hack, but that's the 9267568cb4eSPaul Mackerras * simplest way to get existing XFree to not lockup on some 9277568cb4eSPaul Mackerras * G5 machines... So when something asks for bus 0 io base 9287568cb4eSPaul Mackerras * (bus 0 is HT root), we return the AGP one instead. 9297568cb4eSPaul Mackerras */ 9307568cb4eSPaul Mackerras if (machine_is_compatible("MacRISC4")) 9317568cb4eSPaul Mackerras if (in_bus == 0) 9327568cb4eSPaul Mackerras in_bus = 0xf0; 9337568cb4eSPaul Mackerras 9347568cb4eSPaul Mackerras /* That syscall isn't quite compatible with PCI domains, but it's 9357568cb4eSPaul Mackerras * used on pre-domains setup. We return the first match 9367568cb4eSPaul Mackerras */ 9377568cb4eSPaul Mackerras 9387568cb4eSPaul Mackerras for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { 9397568cb4eSPaul Mackerras bus = pci_bus_b(ln); 940545da94fSBenjamin Herrenschmidt if (in_bus >= bus->number && in_bus <= bus->subordinate) 9417568cb4eSPaul Mackerras break; 9427568cb4eSPaul Mackerras bus = NULL; 9437568cb4eSPaul Mackerras } 9447568cb4eSPaul Mackerras if (bus == NULL || bus->sysdata == NULL) 9457568cb4eSPaul Mackerras return -ENODEV; 9467568cb4eSPaul Mackerras 9477568cb4eSPaul Mackerras hose_node = (struct device_node *)bus->sysdata; 9487568cb4eSPaul Mackerras hose = PCI_DN(hose_node)->phb; 9497568cb4eSPaul Mackerras 9507568cb4eSPaul Mackerras switch (which) { 9517568cb4eSPaul Mackerras case IOBASE_BRIDGE_NUMBER: 9527568cb4eSPaul Mackerras return (long)hose->first_busno; 9537568cb4eSPaul Mackerras case IOBASE_MEMORY: 9547568cb4eSPaul Mackerras return (long)hose->pci_mem_offset; 9557568cb4eSPaul Mackerras case IOBASE_IO: 9567568cb4eSPaul Mackerras return (long)hose->io_base_phys; 9577568cb4eSPaul Mackerras case IOBASE_ISA_IO: 9587568cb4eSPaul Mackerras return (long)isa_io_base; 9597568cb4eSPaul Mackerras case IOBASE_ISA_MEM: 9607568cb4eSPaul Mackerras return -EINVAL; 9617568cb4eSPaul Mackerras } 9627568cb4eSPaul Mackerras 9637568cb4eSPaul Mackerras return -EOPNOTSUPP; 9647568cb4eSPaul Mackerras } 965357518faSAnton Blanchard 966357518faSAnton Blanchard #ifdef CONFIG_NUMA 967357518faSAnton Blanchard int pcibus_to_node(struct pci_bus *bus) 968357518faSAnton Blanchard { 969357518faSAnton Blanchard struct pci_controller *phb = pci_bus_to_host(bus); 970357518faSAnton Blanchard return phb->node; 971357518faSAnton Blanchard } 972357518faSAnton Blanchard EXPORT_SYMBOL(pcibus_to_node); 973357518faSAnton Blanchard #endif 974