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> 34eecba334SStephen Rothwell #include <asm/firmware.h> 357568cb4eSPaul Mackerras 367568cb4eSPaul Mackerras #ifdef DEBUG 37f9e4ec57SMichael Ellerman #include <asm/udbg.h> 381beb6a7dSBenjamin Herrenschmidt #define DBG(fmt...) printk(fmt) 397568cb4eSPaul Mackerras #else 407568cb4eSPaul Mackerras #define DBG(fmt...) 417568cb4eSPaul Mackerras #endif 427568cb4eSPaul Mackerras 437568cb4eSPaul Mackerras unsigned long pci_probe_only = 1; 44f8ef2705SPaul Mackerras int pci_assign_all_buses = 0; 457568cb4eSPaul Mackerras 467568cb4eSPaul Mackerras static void fixup_resource(struct resource *res, struct pci_dev *dev); 477568cb4eSPaul Mackerras static void do_bus_setup(struct pci_bus *bus); 487568cb4eSPaul Mackerras 497568cb4eSPaul Mackerras /* pci_io_base -- the base address from which io bars are offsets. 507568cb4eSPaul Mackerras * This is the lowest I/O base address (so bar values are always positive), 517568cb4eSPaul Mackerras * and it *must* be the start of ISA space if an ISA bus exists because 523d5134eeSBenjamin Herrenschmidt * ISA drivers use hard coded offsets. If no ISA bus exists nothing 533d5134eeSBenjamin Herrenschmidt * is mapped on the first 64K of IO space 547568cb4eSPaul Mackerras */ 553d5134eeSBenjamin Herrenschmidt unsigned long pci_io_base = ISA_IO_BASE; 567568cb4eSPaul Mackerras EXPORT_SYMBOL(pci_io_base); 577568cb4eSPaul Mackerras 587568cb4eSPaul Mackerras LIST_HEAD(hose_list); 597568cb4eSPaul Mackerras 6057190708SStephen Rothwell static struct dma_mapping_ops *pci_dma_ops; 617568cb4eSPaul Mackerras 6298747770SStephen Rothwell void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) 6398747770SStephen Rothwell { 6498747770SStephen Rothwell pci_dma_ops = dma_ops; 6598747770SStephen Rothwell } 6698747770SStephen Rothwell 6757190708SStephen Rothwell struct dma_mapping_ops *get_pci_dma_ops(void) 6857190708SStephen Rothwell { 6957190708SStephen Rothwell return pci_dma_ops; 7057190708SStephen Rothwell } 7157190708SStephen Rothwell EXPORT_SYMBOL(get_pci_dma_ops); 7257190708SStephen Rothwell 737568cb4eSPaul Mackerras static void fixup_broken_pcnet32(struct pci_dev* dev) 747568cb4eSPaul Mackerras { 757568cb4eSPaul Mackerras if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 767568cb4eSPaul Mackerras dev->vendor = PCI_VENDOR_ID_AMD; 777568cb4eSPaul Mackerras pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); 787568cb4eSPaul Mackerras } 797568cb4eSPaul Mackerras } 807568cb4eSPaul Mackerras DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); 817568cb4eSPaul Mackerras 827568cb4eSPaul Mackerras void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 837568cb4eSPaul Mackerras struct resource *res) 847568cb4eSPaul Mackerras { 857568cb4eSPaul Mackerras unsigned long offset = 0; 867568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 877568cb4eSPaul Mackerras 887568cb4eSPaul Mackerras if (!hose) 897568cb4eSPaul Mackerras return; 907568cb4eSPaul Mackerras 917568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 923d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 937568cb4eSPaul Mackerras 947568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 957568cb4eSPaul Mackerras offset = hose->pci_mem_offset; 967568cb4eSPaul Mackerras 977568cb4eSPaul Mackerras region->start = res->start - offset; 987568cb4eSPaul Mackerras region->end = res->end - offset; 997568cb4eSPaul Mackerras } 1007568cb4eSPaul Mackerras 1017568cb4eSPaul Mackerras void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 1027568cb4eSPaul Mackerras struct pci_bus_region *region) 1037568cb4eSPaul Mackerras { 1047568cb4eSPaul Mackerras unsigned long offset = 0; 1057568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 1067568cb4eSPaul Mackerras 1077568cb4eSPaul Mackerras if (!hose) 1087568cb4eSPaul Mackerras return; 1097568cb4eSPaul Mackerras 1107568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 1113d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 1127568cb4eSPaul Mackerras 1137568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 1147568cb4eSPaul Mackerras offset = hose->pci_mem_offset; 1157568cb4eSPaul Mackerras 1167568cb4eSPaul Mackerras res->start = region->start + offset; 1177568cb4eSPaul Mackerras res->end = region->end + offset; 1187568cb4eSPaul Mackerras } 1197568cb4eSPaul Mackerras 1207568cb4eSPaul Mackerras #ifdef CONFIG_HOTPLUG 1217568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_resource_to_bus); 1227568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_bus_to_resource); 1237568cb4eSPaul Mackerras #endif 1247568cb4eSPaul Mackerras 1257568cb4eSPaul Mackerras /* 1267568cb4eSPaul Mackerras * We need to avoid collisions with `mirrored' VGA ports 1277568cb4eSPaul Mackerras * and other strange ISA hardware, so we always want the 1287568cb4eSPaul Mackerras * addresses to be allocated in the 0x000-0x0ff region 1297568cb4eSPaul Mackerras * modulo 0x400. 1307568cb4eSPaul Mackerras * 1317568cb4eSPaul Mackerras * Why? Because some silly external IO cards only decode 1327568cb4eSPaul Mackerras * the low 10 bits of the IO address. The 0x00-0xff region 1337568cb4eSPaul Mackerras * is reserved for motherboard devices that decode all 16 1347568cb4eSPaul Mackerras * bits, so it's ok to allocate at, say, 0x2800-0x28ff, 1357568cb4eSPaul Mackerras * but we want to try to avoid allocating at 0x2900-0x2bff 1367568cb4eSPaul Mackerras * which might have be mirrored at 0x0100-0x03ff.. 1377568cb4eSPaul Mackerras */ 1387568cb4eSPaul Mackerras void pcibios_align_resource(void *data, struct resource *res, 139e31dd6e4SGreg Kroah-Hartman resource_size_t size, resource_size_t align) 1407568cb4eSPaul Mackerras { 1417568cb4eSPaul Mackerras struct pci_dev *dev = data; 1427568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 143e31dd6e4SGreg Kroah-Hartman resource_size_t start = res->start; 1447568cb4eSPaul Mackerras unsigned long alignto; 1457568cb4eSPaul Mackerras 1467568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) { 1477568cb4eSPaul Mackerras unsigned long offset = (unsigned long)hose->io_base_virt - 1483d5134eeSBenjamin Herrenschmidt _IO_BASE; 1497568cb4eSPaul Mackerras /* Make sure we start at our min on all hoses */ 1507568cb4eSPaul Mackerras if (start - offset < PCIBIOS_MIN_IO) 1517568cb4eSPaul Mackerras start = PCIBIOS_MIN_IO + offset; 1527568cb4eSPaul Mackerras 1537568cb4eSPaul Mackerras /* 1547568cb4eSPaul Mackerras * Put everything into 0x00-0xff region modulo 0x400 1557568cb4eSPaul Mackerras */ 1567568cb4eSPaul Mackerras if (start & 0x300) 1577568cb4eSPaul Mackerras start = (start + 0x3ff) & ~0x3ff; 1587568cb4eSPaul Mackerras 1597568cb4eSPaul Mackerras } else if (res->flags & IORESOURCE_MEM) { 1607568cb4eSPaul Mackerras /* Make sure we start at our min on all hoses */ 1617568cb4eSPaul Mackerras if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM) 1627568cb4eSPaul Mackerras start = PCIBIOS_MIN_MEM + hose->pci_mem_offset; 1637568cb4eSPaul Mackerras 1647568cb4eSPaul Mackerras /* Align to multiple of size of minimum base. */ 1657568cb4eSPaul Mackerras alignto = max(0x1000UL, align); 1667568cb4eSPaul Mackerras start = ALIGN(start, alignto); 1677568cb4eSPaul Mackerras } 1687568cb4eSPaul Mackerras 1697568cb4eSPaul Mackerras res->start = start; 1707568cb4eSPaul Mackerras } 1717568cb4eSPaul Mackerras 172facf0787SLinas Vepstas void __devinit pcibios_claim_one_bus(struct pci_bus *b) 1737568cb4eSPaul Mackerras { 1747568cb4eSPaul Mackerras struct pci_dev *dev; 1757568cb4eSPaul Mackerras struct pci_bus *child_bus; 1767568cb4eSPaul Mackerras 1777568cb4eSPaul Mackerras list_for_each_entry(dev, &b->devices, bus_list) { 1787568cb4eSPaul Mackerras int i; 1797568cb4eSPaul Mackerras 1807568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES; i++) { 1817568cb4eSPaul Mackerras struct resource *r = &dev->resource[i]; 1827568cb4eSPaul Mackerras 1837568cb4eSPaul Mackerras if (r->parent || !r->start || !r->flags) 1847568cb4eSPaul Mackerras continue; 1857568cb4eSPaul Mackerras pci_claim_resource(dev, i); 1867568cb4eSPaul Mackerras } 1877568cb4eSPaul Mackerras } 1887568cb4eSPaul Mackerras 1897568cb4eSPaul Mackerras list_for_each_entry(child_bus, &b->children, node) 1907568cb4eSPaul Mackerras pcibios_claim_one_bus(child_bus); 1917568cb4eSPaul Mackerras } 192af9deabeSlinas #ifdef CONFIG_HOTPLUG 193af9deabeSlinas EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); 194af9deabeSlinas #endif 1957568cb4eSPaul Mackerras 1967568cb4eSPaul Mackerras static void __init pcibios_claim_of_setup(void) 1977568cb4eSPaul Mackerras { 1987568cb4eSPaul Mackerras struct pci_bus *b; 1997568cb4eSPaul Mackerras 200eecba334SStephen Rothwell if (firmware_has_feature(FW_FEATURE_ISERIES)) 201eecba334SStephen Rothwell return; 202eecba334SStephen Rothwell 2037568cb4eSPaul Mackerras list_for_each_entry(b, &pci_root_buses, node) 2047568cb4eSPaul Mackerras pcibios_claim_one_bus(b); 2057568cb4eSPaul Mackerras } 2067568cb4eSPaul Mackerras 2077568cb4eSPaul Mackerras static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 2087568cb4eSPaul Mackerras { 209a7f67bdfSJeremy Kerr const u32 *prop; 2107568cb4eSPaul Mackerras int len; 2117568cb4eSPaul Mackerras 212e2eb6392SStephen Rothwell prop = of_get_property(np, name, &len); 2137568cb4eSPaul Mackerras if (prop && len >= 4) 2147568cb4eSPaul Mackerras return *prop; 2157568cb4eSPaul Mackerras return def; 2167568cb4eSPaul Mackerras } 2177568cb4eSPaul Mackerras 2187568cb4eSPaul Mackerras static unsigned int pci_parse_of_flags(u32 addr0) 2197568cb4eSPaul Mackerras { 2207568cb4eSPaul Mackerras unsigned int flags = 0; 2217568cb4eSPaul Mackerras 2227568cb4eSPaul Mackerras if (addr0 & 0x02000000) { 2237568cb4eSPaul Mackerras flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; 2247568cb4eSPaul Mackerras flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; 2257568cb4eSPaul Mackerras flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; 2267568cb4eSPaul Mackerras if (addr0 & 0x40000000) 2277568cb4eSPaul Mackerras flags |= IORESOURCE_PREFETCH 2287568cb4eSPaul Mackerras | PCI_BASE_ADDRESS_MEM_PREFETCH; 2297568cb4eSPaul Mackerras } else if (addr0 & 0x01000000) 2307568cb4eSPaul Mackerras flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 2317568cb4eSPaul Mackerras return flags; 2327568cb4eSPaul Mackerras } 2337568cb4eSPaul Mackerras 2347568cb4eSPaul Mackerras 2357568cb4eSPaul Mackerras static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) 2367568cb4eSPaul Mackerras { 2377568cb4eSPaul Mackerras u64 base, size; 2387568cb4eSPaul Mackerras unsigned int flags; 2397568cb4eSPaul Mackerras struct resource *res; 240a7f67bdfSJeremy Kerr const u32 *addrs; 241a7f67bdfSJeremy Kerr u32 i; 2427568cb4eSPaul Mackerras int proplen; 2437568cb4eSPaul Mackerras 244e2eb6392SStephen Rothwell addrs = of_get_property(node, "assigned-addresses", &proplen); 2457568cb4eSPaul Mackerras if (!addrs) 2467568cb4eSPaul Mackerras return; 2471beb6a7dSBenjamin Herrenschmidt DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); 2487568cb4eSPaul Mackerras for (; proplen >= 20; proplen -= 20, addrs += 5) { 2497568cb4eSPaul Mackerras flags = pci_parse_of_flags(addrs[0]); 2507568cb4eSPaul Mackerras if (!flags) 2517568cb4eSPaul Mackerras continue; 252327e22dfSJon Loeliger base = of_read_number(&addrs[1], 2); 253327e22dfSJon Loeliger size = of_read_number(&addrs[3], 2); 2547568cb4eSPaul Mackerras if (!size) 2557568cb4eSPaul Mackerras continue; 2567568cb4eSPaul Mackerras i = addrs[0] & 0xff; 2571beb6a7dSBenjamin Herrenschmidt DBG(" base: %llx, size: %llx, i: %x\n", 2581beb6a7dSBenjamin Herrenschmidt (unsigned long long)base, (unsigned long long)size, i); 2591beb6a7dSBenjamin Herrenschmidt 2607568cb4eSPaul Mackerras if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { 2617568cb4eSPaul Mackerras res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; 2627568cb4eSPaul Mackerras } else if (i == dev->rom_base_reg) { 2637568cb4eSPaul Mackerras res = &dev->resource[PCI_ROM_RESOURCE]; 2647568cb4eSPaul Mackerras flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; 2657568cb4eSPaul Mackerras } else { 2667568cb4eSPaul Mackerras printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); 2677568cb4eSPaul Mackerras continue; 2687568cb4eSPaul Mackerras } 2697568cb4eSPaul Mackerras res->start = base; 2707568cb4eSPaul Mackerras res->end = base + size - 1; 2717568cb4eSPaul Mackerras res->flags = flags; 2727568cb4eSPaul Mackerras res->name = pci_name(dev); 2737568cb4eSPaul Mackerras fixup_resource(res, dev); 2747568cb4eSPaul Mackerras } 2757568cb4eSPaul Mackerras } 2767568cb4eSPaul Mackerras 2777568cb4eSPaul Mackerras struct pci_dev *of_create_pci_dev(struct device_node *node, 2787568cb4eSPaul Mackerras struct pci_bus *bus, int devfn) 2797568cb4eSPaul Mackerras { 2807568cb4eSPaul Mackerras struct pci_dev *dev; 2817568cb4eSPaul Mackerras const char *type; 2827568cb4eSPaul Mackerras 283bab41e9bSMichael Ellerman dev = alloc_pci_dev(); 2847568cb4eSPaul Mackerras if (!dev) 2857568cb4eSPaul Mackerras return NULL; 286e2eb6392SStephen Rothwell type = of_get_property(node, "device_type", NULL); 2877568cb4eSPaul Mackerras if (type == NULL) 2887568cb4eSPaul Mackerras type = ""; 2897568cb4eSPaul Mackerras 2901beb6a7dSBenjamin Herrenschmidt DBG(" create device, devfn: %x, type: %s\n", devfn, type); 2911beb6a7dSBenjamin Herrenschmidt 2927568cb4eSPaul Mackerras dev->bus = bus; 2937568cb4eSPaul Mackerras dev->sysdata = node; 2947568cb4eSPaul Mackerras dev->dev.parent = bus->bridge; 2957568cb4eSPaul Mackerras dev->dev.bus = &pci_bus_type; 2967568cb4eSPaul Mackerras dev->devfn = devfn; 2977568cb4eSPaul Mackerras dev->multifunction = 0; /* maybe a lie? */ 2987568cb4eSPaul Mackerras 2997568cb4eSPaul Mackerras dev->vendor = get_int_prop(node, "vendor-id", 0xffff); 3007568cb4eSPaul Mackerras dev->device = get_int_prop(node, "device-id", 0xffff); 3017568cb4eSPaul Mackerras dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); 3027568cb4eSPaul Mackerras dev->subsystem_device = get_int_prop(node, "subsystem-id", 0); 3037568cb4eSPaul Mackerras 3049d17a5c6SBenjamin Herrenschmidt dev->cfg_size = pci_cfg_space_size(dev); 3057568cb4eSPaul Mackerras 3067568cb4eSPaul Mackerras sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), 3077568cb4eSPaul Mackerras dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 3087568cb4eSPaul Mackerras dev->class = get_int_prop(node, "class-code", 0); 309b8a3a521SAuke Kok dev->revision = get_int_prop(node, "revision-id", 0); 3107568cb4eSPaul Mackerras 3111beb6a7dSBenjamin Herrenschmidt DBG(" class: 0x%x\n", dev->class); 312b8a3a521SAuke Kok DBG(" revision: 0x%x\n", dev->revision); 3131beb6a7dSBenjamin Herrenschmidt 3147568cb4eSPaul Mackerras dev->current_state = 4; /* unknown power state */ 315bb63ab13SLinas Vepstas dev->error_state = pci_channel_io_normal; 316*8f2ea1fdSBenjamin Herrenschmidt dev->dma_mask = 0xffffffff; 3177568cb4eSPaul Mackerras 318bb53bb3dSJake Moilanen if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { 3197568cb4eSPaul Mackerras /* a PCI-PCI bridge */ 3207568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; 3217568cb4eSPaul Mackerras dev->rom_base_reg = PCI_ROM_ADDRESS1; 3227568cb4eSPaul Mackerras } else if (!strcmp(type, "cardbus")) { 3237568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; 3247568cb4eSPaul Mackerras } else { 3257568cb4eSPaul Mackerras dev->hdr_type = PCI_HEADER_TYPE_NORMAL; 3267568cb4eSPaul Mackerras dev->rom_base_reg = PCI_ROM_ADDRESS; 3270ebfff14SBenjamin Herrenschmidt /* Maybe do a default OF mapping here */ 3287568cb4eSPaul Mackerras dev->irq = NO_IRQ; 3297568cb4eSPaul Mackerras } 3307568cb4eSPaul Mackerras 3317568cb4eSPaul Mackerras pci_parse_of_addrs(node, dev); 3327568cb4eSPaul Mackerras 3331beb6a7dSBenjamin Herrenschmidt DBG(" adding to system ...\n"); 3341beb6a7dSBenjamin Herrenschmidt 3357568cb4eSPaul Mackerras pci_device_add(dev, bus); 3367568cb4eSPaul Mackerras 3377568cb4eSPaul Mackerras return dev; 3387568cb4eSPaul Mackerras } 3397568cb4eSPaul Mackerras EXPORT_SYMBOL(of_create_pci_dev); 3407568cb4eSPaul Mackerras 3417568cb4eSPaul Mackerras void __devinit of_scan_bus(struct device_node *node, 3427568cb4eSPaul Mackerras struct pci_bus *bus) 3437568cb4eSPaul Mackerras { 3447568cb4eSPaul Mackerras struct device_node *child = NULL; 345a7f67bdfSJeremy Kerr const u32 *reg; 3467568cb4eSPaul Mackerras int reglen, devfn; 3477568cb4eSPaul Mackerras struct pci_dev *dev; 3487568cb4eSPaul Mackerras 3491beb6a7dSBenjamin Herrenschmidt DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); 3501beb6a7dSBenjamin Herrenschmidt 3517568cb4eSPaul Mackerras while ((child = of_get_next_child(node, child)) != NULL) { 3521beb6a7dSBenjamin Herrenschmidt DBG(" * %s\n", child->full_name); 353e2eb6392SStephen Rothwell reg = of_get_property(child, "reg", ®len); 3547568cb4eSPaul Mackerras if (reg == NULL || reglen < 20) 3557568cb4eSPaul Mackerras continue; 3567568cb4eSPaul Mackerras devfn = (reg[0] >> 8) & 0xff; 3571beb6a7dSBenjamin Herrenschmidt 3587568cb4eSPaul Mackerras /* create a new pci_dev for this device */ 3597568cb4eSPaul Mackerras dev = of_create_pci_dev(child, bus, devfn); 3607568cb4eSPaul Mackerras if (!dev) 3617568cb4eSPaul Mackerras continue; 3621beb6a7dSBenjamin Herrenschmidt DBG("dev header type: %x\n", dev->hdr_type); 3631beb6a7dSBenjamin Herrenschmidt 3647568cb4eSPaul Mackerras if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 3657568cb4eSPaul Mackerras dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 3667568cb4eSPaul Mackerras of_scan_pci_bridge(child, dev); 3677568cb4eSPaul Mackerras } 3687568cb4eSPaul Mackerras 3697568cb4eSPaul Mackerras do_bus_setup(bus); 3707568cb4eSPaul Mackerras } 3717568cb4eSPaul Mackerras EXPORT_SYMBOL(of_scan_bus); 3727568cb4eSPaul Mackerras 3737568cb4eSPaul Mackerras void __devinit of_scan_pci_bridge(struct device_node *node, 3747568cb4eSPaul Mackerras struct pci_dev *dev) 3757568cb4eSPaul Mackerras { 3767568cb4eSPaul Mackerras struct pci_bus *bus; 377a7f67bdfSJeremy Kerr const u32 *busrange, *ranges; 3787568cb4eSPaul Mackerras int len, i, mode; 3797568cb4eSPaul Mackerras struct resource *res; 3807568cb4eSPaul Mackerras unsigned int flags; 3817568cb4eSPaul Mackerras u64 size; 3827568cb4eSPaul Mackerras 3831beb6a7dSBenjamin Herrenschmidt DBG("of_scan_pci_bridge(%s)\n", node->full_name); 3841beb6a7dSBenjamin Herrenschmidt 3857568cb4eSPaul Mackerras /* parse bus-range property */ 386e2eb6392SStephen Rothwell busrange = of_get_property(node, "bus-range", &len); 3877568cb4eSPaul Mackerras if (busrange == NULL || len != 8) { 3881beb6a7dSBenjamin Herrenschmidt printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", 3897568cb4eSPaul Mackerras node->full_name); 3907568cb4eSPaul Mackerras return; 3917568cb4eSPaul Mackerras } 392e2eb6392SStephen Rothwell ranges = of_get_property(node, "ranges", &len); 3937568cb4eSPaul Mackerras if (ranges == NULL) { 3941beb6a7dSBenjamin Herrenschmidt printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", 3957568cb4eSPaul Mackerras node->full_name); 3967568cb4eSPaul Mackerras return; 3977568cb4eSPaul Mackerras } 3987568cb4eSPaul Mackerras 3997568cb4eSPaul Mackerras bus = pci_add_new_bus(dev->bus, dev, busrange[0]); 4007568cb4eSPaul Mackerras if (!bus) { 4017568cb4eSPaul Mackerras printk(KERN_ERR "Failed to create pci bus for %s\n", 4027568cb4eSPaul Mackerras node->full_name); 4037568cb4eSPaul Mackerras return; 4047568cb4eSPaul Mackerras } 4057568cb4eSPaul Mackerras 4067568cb4eSPaul Mackerras bus->primary = dev->bus->number; 4077568cb4eSPaul Mackerras bus->subordinate = busrange[1]; 4087568cb4eSPaul Mackerras bus->bridge_ctl = 0; 4097568cb4eSPaul Mackerras bus->sysdata = node; 4107568cb4eSPaul Mackerras 4117568cb4eSPaul Mackerras /* parse ranges property */ 4127568cb4eSPaul Mackerras /* PCI #address-cells == 3 and #size-cells == 2 always */ 4137568cb4eSPaul Mackerras res = &dev->resource[PCI_BRIDGE_RESOURCES]; 4147568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { 4157568cb4eSPaul Mackerras res->flags = 0; 4167568cb4eSPaul Mackerras bus->resource[i] = res; 4177568cb4eSPaul Mackerras ++res; 4187568cb4eSPaul Mackerras } 4197568cb4eSPaul Mackerras i = 1; 4207568cb4eSPaul Mackerras for (; len >= 32; len -= 32, ranges += 8) { 4217568cb4eSPaul Mackerras flags = pci_parse_of_flags(ranges[0]); 422327e22dfSJon Loeliger size = of_read_number(&ranges[6], 2); 4237568cb4eSPaul Mackerras if (flags == 0 || size == 0) 4247568cb4eSPaul Mackerras continue; 4257568cb4eSPaul Mackerras if (flags & IORESOURCE_IO) { 4267568cb4eSPaul Mackerras res = bus->resource[0]; 4277568cb4eSPaul Mackerras if (res->flags) { 4287568cb4eSPaul Mackerras printk(KERN_ERR "PCI: ignoring extra I/O range" 4297568cb4eSPaul Mackerras " for bridge %s\n", node->full_name); 4307568cb4eSPaul Mackerras continue; 4317568cb4eSPaul Mackerras } 4327568cb4eSPaul Mackerras } else { 4337568cb4eSPaul Mackerras if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { 4347568cb4eSPaul Mackerras printk(KERN_ERR "PCI: too many memory ranges" 4357568cb4eSPaul Mackerras " for bridge %s\n", node->full_name); 4367568cb4eSPaul Mackerras continue; 4377568cb4eSPaul Mackerras } 4387568cb4eSPaul Mackerras res = bus->resource[i]; 4397568cb4eSPaul Mackerras ++i; 4407568cb4eSPaul Mackerras } 441327e22dfSJon Loeliger res->start = of_read_number(&ranges[1], 2); 4427568cb4eSPaul Mackerras res->end = res->start + size - 1; 4437568cb4eSPaul Mackerras res->flags = flags; 4447568cb4eSPaul Mackerras fixup_resource(res, dev); 4457568cb4eSPaul Mackerras } 4467568cb4eSPaul Mackerras sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 4477568cb4eSPaul Mackerras bus->number); 4481beb6a7dSBenjamin Herrenschmidt DBG(" bus name: %s\n", bus->name); 4497568cb4eSPaul Mackerras 4507568cb4eSPaul Mackerras mode = PCI_PROBE_NORMAL; 4517568cb4eSPaul Mackerras if (ppc_md.pci_probe_mode) 4527568cb4eSPaul Mackerras mode = ppc_md.pci_probe_mode(bus); 4531beb6a7dSBenjamin Herrenschmidt DBG(" probe mode: %d\n", mode); 4541beb6a7dSBenjamin Herrenschmidt 4557568cb4eSPaul Mackerras if (mode == PCI_PROBE_DEVTREE) 4567568cb4eSPaul Mackerras of_scan_bus(node, bus); 4577568cb4eSPaul Mackerras else if (mode == PCI_PROBE_NORMAL) 4587568cb4eSPaul Mackerras pci_scan_child_bus(bus); 4597568cb4eSPaul Mackerras } 4607568cb4eSPaul Mackerras EXPORT_SYMBOL(of_scan_pci_bridge); 4617568cb4eSPaul Mackerras 4627568cb4eSPaul Mackerras void __devinit scan_phb(struct pci_controller *hose) 4637568cb4eSPaul Mackerras { 4647568cb4eSPaul Mackerras struct pci_bus *bus; 4657568cb4eSPaul Mackerras struct device_node *node = hose->arch_data; 4667568cb4eSPaul Mackerras int i, mode; 4677568cb4eSPaul Mackerras struct resource *res; 4687568cb4eSPaul Mackerras 4691beb6a7dSBenjamin Herrenschmidt DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 4701beb6a7dSBenjamin Herrenschmidt 471803d4573SBenjamin Herrenschmidt bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); 4727568cb4eSPaul Mackerras if (bus == NULL) { 4737568cb4eSPaul Mackerras printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 4747568cb4eSPaul Mackerras hose->global_number); 4757568cb4eSPaul Mackerras return; 4767568cb4eSPaul Mackerras } 4777568cb4eSPaul Mackerras bus->secondary = hose->first_busno; 4787568cb4eSPaul Mackerras hose->bus = bus; 4797568cb4eSPaul Mackerras 4803d5134eeSBenjamin Herrenschmidt if (!firmware_has_feature(FW_FEATURE_ISERIES)) 4813d5134eeSBenjamin Herrenschmidt pcibios_map_io_space(bus); 4823d5134eeSBenjamin Herrenschmidt 4837568cb4eSPaul Mackerras bus->resource[0] = res = &hose->io_resource; 4843d5134eeSBenjamin Herrenschmidt if (res->flags && request_resource(&ioport_resource, res)) { 4857568cb4eSPaul Mackerras printk(KERN_ERR "Failed to request PCI IO region " 4867568cb4eSPaul Mackerras "on PCI domain %04x\n", hose->global_number); 4873d5134eeSBenjamin Herrenschmidt DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", 4883d5134eeSBenjamin Herrenschmidt res->start, res->end); 4893d5134eeSBenjamin Herrenschmidt } 4907568cb4eSPaul Mackerras 4917568cb4eSPaul Mackerras for (i = 0; i < 3; ++i) { 4927568cb4eSPaul Mackerras res = &hose->mem_resources[i]; 4937568cb4eSPaul Mackerras bus->resource[i+1] = res; 4947568cb4eSPaul Mackerras if (res->flags && request_resource(&iomem_resource, res)) 4957568cb4eSPaul Mackerras printk(KERN_ERR "Failed to request PCI memory region " 4967568cb4eSPaul Mackerras "on PCI domain %04x\n", hose->global_number); 4977568cb4eSPaul Mackerras } 4987568cb4eSPaul Mackerras 4997568cb4eSPaul Mackerras mode = PCI_PROBE_NORMAL; 50099a565baSs.hauer@pengutronix.de 5011beb6a7dSBenjamin Herrenschmidt if (node && ppc_md.pci_probe_mode) 5027568cb4eSPaul Mackerras mode = ppc_md.pci_probe_mode(bus); 5031beb6a7dSBenjamin Herrenschmidt DBG(" probe mode: %d\n", mode); 5047568cb4eSPaul Mackerras if (mode == PCI_PROBE_DEVTREE) { 5057568cb4eSPaul Mackerras bus->subordinate = hose->last_busno; 5067568cb4eSPaul Mackerras of_scan_bus(node, bus); 5077568cb4eSPaul Mackerras } 50899a565baSs.hauer@pengutronix.de 5097568cb4eSPaul Mackerras if (mode == PCI_PROBE_NORMAL) 5107568cb4eSPaul Mackerras hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 5117568cb4eSPaul Mackerras } 5127568cb4eSPaul Mackerras 5137568cb4eSPaul Mackerras static int __init pcibios_init(void) 5147568cb4eSPaul Mackerras { 5157568cb4eSPaul Mackerras struct pci_controller *hose, *tmp; 5167568cb4eSPaul Mackerras 5177568cb4eSPaul Mackerras /* For now, override phys_mem_access_prot. If we need it, 5187568cb4eSPaul Mackerras * later, we may move that initialization to each ppc_md 5197568cb4eSPaul Mackerras */ 5207568cb4eSPaul Mackerras ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 5217568cb4eSPaul Mackerras 522eecba334SStephen Rothwell if (firmware_has_feature(FW_FEATURE_ISERIES)) 5237568cb4eSPaul Mackerras iSeries_pcibios_init(); 5247568cb4eSPaul Mackerras 525e884e9c5SOlof Johansson printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); 5267568cb4eSPaul Mackerras 5277568cb4eSPaul Mackerras /* Scan all of the recorded PCI controllers. */ 52892eb4602SJohn Rose list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 5297568cb4eSPaul Mackerras scan_phb(hose); 53092eb4602SJohn Rose pci_bus_add_devices(hose->bus); 53192eb4602SJohn Rose } 5327568cb4eSPaul Mackerras 533eecba334SStephen Rothwell if (!firmware_has_feature(FW_FEATURE_ISERIES)) { 5347568cb4eSPaul Mackerras if (pci_probe_only) 5357568cb4eSPaul Mackerras pcibios_claim_of_setup(); 5367568cb4eSPaul Mackerras else 5377568cb4eSPaul Mackerras /* FIXME: `else' will be removed when 5387568cb4eSPaul Mackerras pci_assign_unassigned_resources() is able to work 5397568cb4eSPaul Mackerras correctly with [partially] allocated PCI tree. */ 5407568cb4eSPaul Mackerras pci_assign_unassigned_resources(); 541eecba334SStephen Rothwell } 5427568cb4eSPaul Mackerras 5437568cb4eSPaul Mackerras /* Call machine dependent final fixup */ 5447568cb4eSPaul Mackerras if (ppc_md.pcibios_fixup) 5457568cb4eSPaul Mackerras ppc_md.pcibios_fixup(); 5467568cb4eSPaul Mackerras 547e884e9c5SOlof Johansson printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 5487568cb4eSPaul Mackerras 5497568cb4eSPaul Mackerras return 0; 5507568cb4eSPaul Mackerras } 5517568cb4eSPaul Mackerras 5527568cb4eSPaul Mackerras subsys_initcall(pcibios_init); 5537568cb4eSPaul Mackerras 5547568cb4eSPaul Mackerras int pcibios_enable_device(struct pci_dev *dev, int mask) 5557568cb4eSPaul Mackerras { 5567568cb4eSPaul Mackerras u16 cmd, oldcmd; 5577568cb4eSPaul Mackerras int i; 5587568cb4eSPaul Mackerras 5597568cb4eSPaul Mackerras pci_read_config_word(dev, PCI_COMMAND, &cmd); 5607568cb4eSPaul Mackerras oldcmd = cmd; 5617568cb4eSPaul Mackerras 5627568cb4eSPaul Mackerras for (i = 0; i < PCI_NUM_RESOURCES; i++) { 5637568cb4eSPaul Mackerras struct resource *res = &dev->resource[i]; 5647568cb4eSPaul Mackerras 5657568cb4eSPaul Mackerras /* Only set up the requested stuff */ 5667568cb4eSPaul Mackerras if (!(mask & (1<<i))) 5677568cb4eSPaul Mackerras continue; 5687568cb4eSPaul Mackerras 5697568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) 5707568cb4eSPaul Mackerras cmd |= PCI_COMMAND_IO; 5717568cb4eSPaul Mackerras if (res->flags & IORESOURCE_MEM) 5727568cb4eSPaul Mackerras cmd |= PCI_COMMAND_MEMORY; 5737568cb4eSPaul Mackerras } 5747568cb4eSPaul Mackerras 5757568cb4eSPaul Mackerras if (cmd != oldcmd) { 5767568cb4eSPaul Mackerras printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n", 5777568cb4eSPaul Mackerras pci_name(dev), cmd); 5787568cb4eSPaul Mackerras /* Enable the appropriate bits in the PCI command register. */ 5797568cb4eSPaul Mackerras pci_write_config_word(dev, PCI_COMMAND, cmd); 5807568cb4eSPaul Mackerras } 5817568cb4eSPaul Mackerras return 0; 5827568cb4eSPaul Mackerras } 5837568cb4eSPaul Mackerras 5847568cb4eSPaul Mackerras /* Decide whether to display the domain number in /proc */ 5857568cb4eSPaul Mackerras int pci_proc_domain(struct pci_bus *bus) 5867568cb4eSPaul Mackerras { 587eecba334SStephen Rothwell if (firmware_has_feature(FW_FEATURE_ISERIES)) 5887568cb4eSPaul Mackerras return 0; 589eecba334SStephen Rothwell else { 5907568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(bus); 5917568cb4eSPaul Mackerras return hose->buid; 592eecba334SStephen Rothwell } 5937568cb4eSPaul Mackerras } 5947568cb4eSPaul Mackerras 5957568cb4eSPaul Mackerras void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 5967568cb4eSPaul Mackerras struct device_node *dev, int prim) 5977568cb4eSPaul Mackerras { 598a7f67bdfSJeremy Kerr const unsigned int *ranges; 599a7f67bdfSJeremy Kerr unsigned int pci_space; 6007568cb4eSPaul Mackerras unsigned long size; 6017568cb4eSPaul Mackerras int rlen = 0; 6027568cb4eSPaul Mackerras int memno = 0; 6037568cb4eSPaul Mackerras struct resource *res; 604a8bda5ddSStephen Rothwell int np, na = of_n_addr_cells(dev); 6057568cb4eSPaul Mackerras unsigned long pci_addr, cpu_phys_addr; 6067568cb4eSPaul Mackerras 6077568cb4eSPaul Mackerras np = na + 5; 6087568cb4eSPaul Mackerras 6097568cb4eSPaul Mackerras /* From "PCI Binding to 1275" 6107568cb4eSPaul Mackerras * The ranges property is laid out as an array of elements, 6117568cb4eSPaul Mackerras * each of which comprises: 6127568cb4eSPaul Mackerras * cells 0 - 2: a PCI address 6137568cb4eSPaul Mackerras * cells 3 or 3+4: a CPU physical address 6147568cb4eSPaul Mackerras * (size depending on dev->n_addr_cells) 6157568cb4eSPaul Mackerras * cells 4+5 or 5+6: the size of the range 6167568cb4eSPaul Mackerras */ 617e2eb6392SStephen Rothwell ranges = of_get_property(dev, "ranges", &rlen); 618b5166cc2SBenjamin Herrenschmidt if (ranges == NULL) 619b5166cc2SBenjamin Herrenschmidt return; 620b5166cc2SBenjamin Herrenschmidt hose->io_base_phys = 0; 6217568cb4eSPaul Mackerras while ((rlen -= np * sizeof(unsigned int)) >= 0) { 6227568cb4eSPaul Mackerras res = NULL; 6237568cb4eSPaul Mackerras pci_space = ranges[0]; 6247568cb4eSPaul Mackerras pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; 625e557a1c9SBenjamin Herrenschmidt cpu_phys_addr = of_translate_address(dev, &ranges[3]); 6267568cb4eSPaul Mackerras size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; 6277568cb4eSPaul Mackerras ranges += np; 6287568cb4eSPaul Mackerras if (size == 0) 6297568cb4eSPaul Mackerras continue; 6307568cb4eSPaul Mackerras 6317568cb4eSPaul Mackerras /* Now consume following elements while they are contiguous */ 6327568cb4eSPaul Mackerras while (rlen >= np * sizeof(unsigned int)) { 6337568cb4eSPaul Mackerras unsigned long addr, phys; 6347568cb4eSPaul Mackerras 6357568cb4eSPaul Mackerras if (ranges[0] != pci_space) 6367568cb4eSPaul Mackerras break; 6377568cb4eSPaul Mackerras addr = ((unsigned long)ranges[1] << 32) | ranges[2]; 6387568cb4eSPaul Mackerras phys = ranges[3]; 6397568cb4eSPaul Mackerras if (na >= 2) 6407568cb4eSPaul Mackerras phys = (phys << 32) | ranges[4]; 6417568cb4eSPaul Mackerras if (addr != pci_addr + size || 6427568cb4eSPaul Mackerras phys != cpu_phys_addr + size) 6437568cb4eSPaul Mackerras break; 6447568cb4eSPaul Mackerras 6457568cb4eSPaul Mackerras size += ((unsigned long)ranges[na+3] << 32) 6467568cb4eSPaul Mackerras | ranges[na+4]; 6477568cb4eSPaul Mackerras ranges += np; 6487568cb4eSPaul Mackerras rlen -= np * sizeof(unsigned int); 6497568cb4eSPaul Mackerras } 6507568cb4eSPaul Mackerras 6517568cb4eSPaul Mackerras switch ((pci_space >> 24) & 0x3) { 6527568cb4eSPaul Mackerras case 1: /* I/O space */ 65311fbb00cSPaul Mackerras hose->io_base_phys = cpu_phys_addr - pci_addr; 65411fbb00cSPaul Mackerras /* handle from 0 to top of I/O window */ 65511fbb00cSPaul Mackerras hose->pci_io_size = pci_addr + size; 6567568cb4eSPaul Mackerras 6577568cb4eSPaul Mackerras res = &hose->io_resource; 6587568cb4eSPaul Mackerras res->flags = IORESOURCE_IO; 6597568cb4eSPaul Mackerras res->start = pci_addr; 6607568cb4eSPaul Mackerras DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number, 6617568cb4eSPaul Mackerras res->start, res->start + size - 1); 6627568cb4eSPaul Mackerras break; 6637568cb4eSPaul Mackerras case 2: /* memory space */ 6647568cb4eSPaul Mackerras memno = 0; 6657568cb4eSPaul Mackerras while (memno < 3 && hose->mem_resources[memno].flags) 6667568cb4eSPaul Mackerras ++memno; 6677568cb4eSPaul Mackerras 6687568cb4eSPaul Mackerras if (memno == 0) 6697568cb4eSPaul Mackerras hose->pci_mem_offset = cpu_phys_addr - pci_addr; 6707568cb4eSPaul Mackerras if (memno < 3) { 6717568cb4eSPaul Mackerras res = &hose->mem_resources[memno]; 6727568cb4eSPaul Mackerras res->flags = IORESOURCE_MEM; 6737568cb4eSPaul Mackerras res->start = cpu_phys_addr; 6747568cb4eSPaul Mackerras DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number, 6757568cb4eSPaul Mackerras res->start, res->start + size - 1); 6767568cb4eSPaul Mackerras } 6777568cb4eSPaul Mackerras break; 6787568cb4eSPaul Mackerras } 6797568cb4eSPaul Mackerras if (res != NULL) { 6807568cb4eSPaul Mackerras res->name = dev->full_name; 6817568cb4eSPaul Mackerras res->end = res->start + size - 1; 6827568cb4eSPaul Mackerras res->parent = NULL; 6837568cb4eSPaul Mackerras res->sibling = NULL; 6847568cb4eSPaul Mackerras res->child = NULL; 6857568cb4eSPaul Mackerras } 6867568cb4eSPaul Mackerras } 6877568cb4eSPaul Mackerras } 6887568cb4eSPaul Mackerras 6893d5134eeSBenjamin Herrenschmidt #ifdef CONFIG_HOTPLUG 6903d5134eeSBenjamin Herrenschmidt 6913d5134eeSBenjamin Herrenschmidt int pcibios_unmap_io_space(struct pci_bus *bus) 6927568cb4eSPaul Mackerras { 6933d5134eeSBenjamin Herrenschmidt struct pci_controller *hose; 6947568cb4eSPaul Mackerras 6953d5134eeSBenjamin Herrenschmidt WARN_ON(bus == NULL); 696de821204SBenjamin Herrenschmidt 6973d5134eeSBenjamin Herrenschmidt /* If this is not a PHB, we only flush the hash table over 6983d5134eeSBenjamin Herrenschmidt * the area mapped by this bridge. We don't play with the PTE 6993d5134eeSBenjamin Herrenschmidt * mappings since we might have to deal with sub-page alignemnts 7003d5134eeSBenjamin Herrenschmidt * so flushing the hash table is the only sane way to make sure 7013d5134eeSBenjamin Herrenschmidt * that no hash entries are covering that removed bridge area 7023d5134eeSBenjamin Herrenschmidt * while still allowing other busses overlapping those pages 703de821204SBenjamin Herrenschmidt */ 7043d5134eeSBenjamin Herrenschmidt if (bus->self) { 7053d5134eeSBenjamin Herrenschmidt struct resource *res = bus->resource[0]; 7063d5134eeSBenjamin Herrenschmidt 7073d5134eeSBenjamin Herrenschmidt DBG("IO unmapping for PCI-PCI bridge %s\n", 7083d5134eeSBenjamin Herrenschmidt pci_name(bus->self)); 7093d5134eeSBenjamin Herrenschmidt 7103d5134eeSBenjamin Herrenschmidt __flush_hash_table_range(&init_mm, res->start + _IO_BASE, 7113d5134eeSBenjamin Herrenschmidt res->end - res->start + 1); 7123d5134eeSBenjamin Herrenschmidt return 0; 7137568cb4eSPaul Mackerras } 7147568cb4eSPaul Mackerras 7153d5134eeSBenjamin Herrenschmidt /* Get the host bridge */ 7163d5134eeSBenjamin Herrenschmidt hose = pci_bus_to_host(bus); 7173d5134eeSBenjamin Herrenschmidt 7183d5134eeSBenjamin Herrenschmidt /* Check if we have IOs allocated */ 7193d5134eeSBenjamin Herrenschmidt if (hose->io_base_alloc == 0) 7203d5134eeSBenjamin Herrenschmidt return 0; 7213d5134eeSBenjamin Herrenschmidt 7223d5134eeSBenjamin Herrenschmidt DBG("IO unmapping for PHB %s\n", 7233d5134eeSBenjamin Herrenschmidt ((struct device_node *)hose->arch_data)->full_name); 7243d5134eeSBenjamin Herrenschmidt DBG(" alloc=0x%p\n", hose->io_base_alloc); 7253d5134eeSBenjamin Herrenschmidt 7263d5134eeSBenjamin Herrenschmidt /* This is a PHB, we fully unmap the IO area */ 7273d5134eeSBenjamin Herrenschmidt vunmap(hose->io_base_alloc); 7283d5134eeSBenjamin Herrenschmidt 7293d5134eeSBenjamin Herrenschmidt return 0; 7303d5134eeSBenjamin Herrenschmidt } 7313d5134eeSBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(pcibios_unmap_io_space); 7323d5134eeSBenjamin Herrenschmidt 7333d5134eeSBenjamin Herrenschmidt #endif /* CONFIG_HOTPLUG */ 7343d5134eeSBenjamin Herrenschmidt 7353d5134eeSBenjamin Herrenschmidt int __devinit pcibios_map_io_space(struct pci_bus *bus) 7367568cb4eSPaul Mackerras { 7373d5134eeSBenjamin Herrenschmidt struct vm_struct *area; 7383d5134eeSBenjamin Herrenschmidt unsigned long phys_page; 7393d5134eeSBenjamin Herrenschmidt unsigned long size_page; 7407568cb4eSPaul Mackerras unsigned long io_virt_offset; 7413d5134eeSBenjamin Herrenschmidt struct pci_controller *hose; 7427568cb4eSPaul Mackerras 7433d5134eeSBenjamin Herrenschmidt WARN_ON(bus == NULL); 744de821204SBenjamin Herrenschmidt 7453d5134eeSBenjamin Herrenschmidt /* If this not a PHB, nothing to do, page tables still exist and 7463d5134eeSBenjamin Herrenschmidt * thus HPTEs will be faulted in when needed 7473d5134eeSBenjamin Herrenschmidt */ 7483d5134eeSBenjamin Herrenschmidt if (bus->self) { 7493d5134eeSBenjamin Herrenschmidt DBG("IO mapping for PCI-PCI bridge %s\n", 7503d5134eeSBenjamin Herrenschmidt pci_name(bus->self)); 7513d5134eeSBenjamin Herrenschmidt DBG(" virt=0x%016lx...0x%016lx\n", 7523d5134eeSBenjamin Herrenschmidt bus->resource[0]->start + _IO_BASE, 7533d5134eeSBenjamin Herrenschmidt bus->resource[0]->end + _IO_BASE); 7547568cb4eSPaul Mackerras return 0; 7557568cb4eSPaul Mackerras } 7567568cb4eSPaul Mackerras 7573d5134eeSBenjamin Herrenschmidt /* Get the host bridge */ 7583d5134eeSBenjamin Herrenschmidt hose = pci_bus_to_host(bus); 7593d5134eeSBenjamin Herrenschmidt phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE); 7603d5134eeSBenjamin Herrenschmidt size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE); 7617568cb4eSPaul Mackerras 7623d5134eeSBenjamin Herrenschmidt /* Make sure IO area address is clear */ 7633d5134eeSBenjamin Herrenschmidt hose->io_base_alloc = NULL; 7647568cb4eSPaul Mackerras 7653d5134eeSBenjamin Herrenschmidt /* If there's no IO to map on that bus, get away too */ 7663d5134eeSBenjamin Herrenschmidt if (hose->pci_io_size == 0 || hose->io_base_phys == 0) 7673d5134eeSBenjamin Herrenschmidt return 0; 7683d5134eeSBenjamin Herrenschmidt 7693d5134eeSBenjamin Herrenschmidt /* Let's allocate some IO space for that guy. We don't pass 7703d5134eeSBenjamin Herrenschmidt * VM_IOREMAP because we don't care about alignment tricks that 7713d5134eeSBenjamin Herrenschmidt * the core does in that case. Maybe we should due to stupid card 7723d5134eeSBenjamin Herrenschmidt * with incomplete address decoding but I'd rather not deal with 7733d5134eeSBenjamin Herrenschmidt * those outside of the reserved 64K legacy region. 7743d5134eeSBenjamin Herrenschmidt */ 7753d5134eeSBenjamin Herrenschmidt area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END); 7763d5134eeSBenjamin Herrenschmidt if (area == NULL) 7773d5134eeSBenjamin Herrenschmidt return -ENOMEM; 7783d5134eeSBenjamin Herrenschmidt hose->io_base_alloc = area->addr; 7793d5134eeSBenjamin Herrenschmidt hose->io_base_virt = (void __iomem *)(area->addr + 7803d5134eeSBenjamin Herrenschmidt hose->io_base_phys - phys_page); 7813d5134eeSBenjamin Herrenschmidt 7823d5134eeSBenjamin Herrenschmidt DBG("IO mapping for PHB %s\n", 7833d5134eeSBenjamin Herrenschmidt ((struct device_node *)hose->arch_data)->full_name); 7843d5134eeSBenjamin Herrenschmidt DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", 7853d5134eeSBenjamin Herrenschmidt hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); 7863d5134eeSBenjamin Herrenschmidt DBG(" size=0x%016lx (alloc=0x%016lx)\n", 7873d5134eeSBenjamin Herrenschmidt hose->pci_io_size, size_page); 7883d5134eeSBenjamin Herrenschmidt 7893d5134eeSBenjamin Herrenschmidt /* Establish the mapping */ 7903d5134eeSBenjamin Herrenschmidt if (__ioremap_at(phys_page, area->addr, size_page, 7913d5134eeSBenjamin Herrenschmidt _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL) 7923d5134eeSBenjamin Herrenschmidt return -ENOMEM; 7933d5134eeSBenjamin Herrenschmidt 7943d5134eeSBenjamin Herrenschmidt /* Fixup hose IO resource */ 7953d5134eeSBenjamin Herrenschmidt io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE; 7963d5134eeSBenjamin Herrenschmidt hose->io_resource.start += io_virt_offset; 7973d5134eeSBenjamin Herrenschmidt hose->io_resource.end += io_virt_offset; 7983d5134eeSBenjamin Herrenschmidt 7993d5134eeSBenjamin Herrenschmidt DBG(" hose->io_resource=0x%016lx...0x%016lx\n", 8003d5134eeSBenjamin Herrenschmidt hose->io_resource.start, hose->io_resource.end); 8017568cb4eSPaul Mackerras 8027568cb4eSPaul Mackerras return 0; 8037568cb4eSPaul Mackerras } 8043d5134eeSBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(pcibios_map_io_space); 8057568cb4eSPaul Mackerras 8067568cb4eSPaul Mackerras static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) 8077568cb4eSPaul Mackerras { 8087568cb4eSPaul Mackerras struct pci_controller *hose = pci_bus_to_host(dev->bus); 809c256f4b9SAnton Blanchard unsigned long offset; 8107568cb4eSPaul Mackerras 8117568cb4eSPaul Mackerras if (res->flags & IORESOURCE_IO) { 8123d5134eeSBenjamin Herrenschmidt offset = (unsigned long)hose->io_base_virt - _IO_BASE; 813c256f4b9SAnton Blanchard res->start += offset; 814c256f4b9SAnton Blanchard res->end += offset; 8157568cb4eSPaul Mackerras } else if (res->flags & IORESOURCE_MEM) { 8167568cb4eSPaul Mackerras res->start += hose->pci_mem_offset; 8177568cb4eSPaul Mackerras res->end += hose->pci_mem_offset; 8187568cb4eSPaul Mackerras } 8197568cb4eSPaul Mackerras } 8207568cb4eSPaul Mackerras 8217568cb4eSPaul Mackerras void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, 8227568cb4eSPaul Mackerras struct pci_bus *bus) 8237568cb4eSPaul Mackerras { 8247568cb4eSPaul Mackerras /* Update device resources. */ 8257568cb4eSPaul Mackerras int i; 8267568cb4eSPaul Mackerras 8273d5134eeSBenjamin Herrenschmidt DBG("%s: Fixup resources:\n", pci_name(dev)); 8283d5134eeSBenjamin Herrenschmidt for (i = 0; i < PCI_NUM_RESOURCES; i++) { 8293d5134eeSBenjamin Herrenschmidt struct resource *res = &dev->resource[i]; 8303d5134eeSBenjamin Herrenschmidt if (!res->flags) 8313d5134eeSBenjamin Herrenschmidt continue; 8323d5134eeSBenjamin Herrenschmidt 8333d5134eeSBenjamin Herrenschmidt DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n", 8343d5134eeSBenjamin Herrenschmidt i, res->flags, res->start, res->end); 8353d5134eeSBenjamin Herrenschmidt 8363d5134eeSBenjamin Herrenschmidt fixup_resource(res, dev); 8373d5134eeSBenjamin Herrenschmidt 8383d5134eeSBenjamin Herrenschmidt DBG(" > %08lx:0x%016lx...0x%016lx\n", 8393d5134eeSBenjamin Herrenschmidt res->flags, res->start, res->end); 8403d5134eeSBenjamin Herrenschmidt } 8417568cb4eSPaul Mackerras } 8427568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_fixup_device_resources); 8437568cb4eSPaul Mackerras 84412d04eefSBenjamin Herrenschmidt void __devinit pcibios_setup_new_device(struct pci_dev *dev) 84512d04eefSBenjamin Herrenschmidt { 84612d04eefSBenjamin Herrenschmidt struct dev_archdata *sd = &dev->dev.archdata; 84712d04eefSBenjamin Herrenschmidt 84812d04eefSBenjamin Herrenschmidt sd->of_node = pci_device_to_OF_node(dev); 84912d04eefSBenjamin Herrenschmidt 85012d04eefSBenjamin Herrenschmidt DBG("PCI device %s OF node: %s\n", pci_name(dev), 85112d04eefSBenjamin Herrenschmidt sd->of_node ? sd->of_node->full_name : "<none>"); 85212d04eefSBenjamin Herrenschmidt 85312d04eefSBenjamin Herrenschmidt sd->dma_ops = pci_dma_ops; 85412d04eefSBenjamin Herrenschmidt #ifdef CONFIG_NUMA 85512d04eefSBenjamin Herrenschmidt sd->numa_node = pcibus_to_node(dev->bus); 85612d04eefSBenjamin Herrenschmidt #else 85712d04eefSBenjamin Herrenschmidt sd->numa_node = -1; 85812d04eefSBenjamin Herrenschmidt #endif 85912d04eefSBenjamin Herrenschmidt if (ppc_md.pci_dma_dev_setup) 86012d04eefSBenjamin Herrenschmidt ppc_md.pci_dma_dev_setup(dev); 86112d04eefSBenjamin Herrenschmidt } 86212d04eefSBenjamin Herrenschmidt EXPORT_SYMBOL(pcibios_setup_new_device); 863463ce0e1SBenjamin Herrenschmidt 8647568cb4eSPaul Mackerras static void __devinit do_bus_setup(struct pci_bus *bus) 8657568cb4eSPaul Mackerras { 8667568cb4eSPaul Mackerras struct pci_dev *dev; 8677568cb4eSPaul Mackerras 86812d04eefSBenjamin Herrenschmidt if (ppc_md.pci_dma_bus_setup) 86912d04eefSBenjamin Herrenschmidt ppc_md.pci_dma_bus_setup(bus); 8707568cb4eSPaul Mackerras 8717568cb4eSPaul Mackerras list_for_each_entry(dev, &bus->devices, bus_list) 87212d04eefSBenjamin Herrenschmidt pcibios_setup_new_device(dev); 8737568cb4eSPaul Mackerras 874f90bb153SBenjamin Herrenschmidt /* Read default IRQs and fixup if necessary */ 875f90bb153SBenjamin Herrenschmidt list_for_each_entry(dev, &bus->devices, bus_list) { 876f90bb153SBenjamin Herrenschmidt pci_read_irq_line(dev); 877f90bb153SBenjamin Herrenschmidt if (ppc_md.pci_irq_fixup) 878f90bb153SBenjamin Herrenschmidt ppc_md.pci_irq_fixup(dev); 879f90bb153SBenjamin Herrenschmidt } 8807568cb4eSPaul Mackerras } 8817568cb4eSPaul Mackerras 8827568cb4eSPaul Mackerras void __devinit pcibios_fixup_bus(struct pci_bus *bus) 8837568cb4eSPaul Mackerras { 8847568cb4eSPaul Mackerras struct pci_dev *dev = bus->self; 8854c9d2800SBenjamin Herrenschmidt struct device_node *np; 8864c9d2800SBenjamin Herrenschmidt 8874c9d2800SBenjamin Herrenschmidt np = pci_bus_to_OF_node(bus); 8884c9d2800SBenjamin Herrenschmidt 8894c9d2800SBenjamin Herrenschmidt DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>"); 8907568cb4eSPaul Mackerras 8917568cb4eSPaul Mackerras if (dev && pci_probe_only && 8927568cb4eSPaul Mackerras (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 8937568cb4eSPaul Mackerras /* This is a subordinate bridge */ 8947568cb4eSPaul Mackerras 8957568cb4eSPaul Mackerras pci_read_bridge_bases(bus); 8967568cb4eSPaul Mackerras pcibios_fixup_device_resources(dev, bus); 8977568cb4eSPaul Mackerras } 8987568cb4eSPaul Mackerras 8997568cb4eSPaul Mackerras do_bus_setup(bus); 9007568cb4eSPaul Mackerras 9017568cb4eSPaul Mackerras if (!pci_probe_only) 9027568cb4eSPaul Mackerras return; 9037568cb4eSPaul Mackerras 9047568cb4eSPaul Mackerras list_for_each_entry(dev, &bus->devices, bus_list) 9057568cb4eSPaul Mackerras if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) 9067568cb4eSPaul Mackerras pcibios_fixup_device_resources(dev, bus); 9077568cb4eSPaul Mackerras } 9087568cb4eSPaul Mackerras EXPORT_SYMBOL(pcibios_fixup_bus); 9097568cb4eSPaul Mackerras 910f2c4583aSBenjamin Herrenschmidt unsigned long pci_address_to_pio(phys_addr_t address) 911d4e4b352SStephen Rothwell { 912d4e4b352SStephen Rothwell struct pci_controller *hose, *tmp; 913d4e4b352SStephen Rothwell 914d4e4b352SStephen Rothwell list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 915d4e4b352SStephen Rothwell if (address >= hose->io_base_phys && 916f2c4583aSBenjamin Herrenschmidt address < (hose->io_base_phys + hose->pci_io_size)) { 917f2c4583aSBenjamin Herrenschmidt unsigned long base = 9183d5134eeSBenjamin Herrenschmidt (unsigned long)hose->io_base_virt - _IO_BASE; 919f2c4583aSBenjamin Herrenschmidt return base + (address - hose->io_base_phys); 920f2c4583aSBenjamin Herrenschmidt } 921d4e4b352SStephen Rothwell } 922d4e4b352SStephen Rothwell return (unsigned int)-1; 923d4e4b352SStephen Rothwell } 924d4e4b352SStephen Rothwell EXPORT_SYMBOL_GPL(pci_address_to_pio); 925d4e4b352SStephen Rothwell 9267568cb4eSPaul Mackerras 9277568cb4eSPaul Mackerras #define IOBASE_BRIDGE_NUMBER 0 9287568cb4eSPaul Mackerras #define IOBASE_MEMORY 1 9297568cb4eSPaul Mackerras #define IOBASE_IO 2 9307568cb4eSPaul Mackerras #define IOBASE_ISA_IO 3 9317568cb4eSPaul Mackerras #define IOBASE_ISA_MEM 4 9327568cb4eSPaul Mackerras 9337568cb4eSPaul Mackerras long sys_pciconfig_iobase(long which, unsigned long in_bus, 9347568cb4eSPaul Mackerras unsigned long in_devfn) 9357568cb4eSPaul Mackerras { 9367568cb4eSPaul Mackerras struct pci_controller* hose; 9377568cb4eSPaul Mackerras struct list_head *ln; 9387568cb4eSPaul Mackerras struct pci_bus *bus = NULL; 9397568cb4eSPaul Mackerras struct device_node *hose_node; 9407568cb4eSPaul Mackerras 9417568cb4eSPaul Mackerras /* Argh ! Please forgive me for that hack, but that's the 9427568cb4eSPaul Mackerras * simplest way to get existing XFree to not lockup on some 9437568cb4eSPaul Mackerras * G5 machines... So when something asks for bus 0 io base 9447568cb4eSPaul Mackerras * (bus 0 is HT root), we return the AGP one instead. 9457568cb4eSPaul Mackerras */ 9467568cb4eSPaul Mackerras if (machine_is_compatible("MacRISC4")) 9477568cb4eSPaul Mackerras if (in_bus == 0) 9487568cb4eSPaul Mackerras in_bus = 0xf0; 9497568cb4eSPaul Mackerras 9507568cb4eSPaul Mackerras /* That syscall isn't quite compatible with PCI domains, but it's 9517568cb4eSPaul Mackerras * used on pre-domains setup. We return the first match 9527568cb4eSPaul Mackerras */ 9537568cb4eSPaul Mackerras 9547568cb4eSPaul Mackerras for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { 9557568cb4eSPaul Mackerras bus = pci_bus_b(ln); 956545da94fSBenjamin Herrenschmidt if (in_bus >= bus->number && in_bus <= bus->subordinate) 9577568cb4eSPaul Mackerras break; 9587568cb4eSPaul Mackerras bus = NULL; 9597568cb4eSPaul Mackerras } 9607568cb4eSPaul Mackerras if (bus == NULL || bus->sysdata == NULL) 9617568cb4eSPaul Mackerras return -ENODEV; 9627568cb4eSPaul Mackerras 9637568cb4eSPaul Mackerras hose_node = (struct device_node *)bus->sysdata; 9647568cb4eSPaul Mackerras hose = PCI_DN(hose_node)->phb; 9657568cb4eSPaul Mackerras 9667568cb4eSPaul Mackerras switch (which) { 9677568cb4eSPaul Mackerras case IOBASE_BRIDGE_NUMBER: 9687568cb4eSPaul Mackerras return (long)hose->first_busno; 9697568cb4eSPaul Mackerras case IOBASE_MEMORY: 9707568cb4eSPaul Mackerras return (long)hose->pci_mem_offset; 9717568cb4eSPaul Mackerras case IOBASE_IO: 9727568cb4eSPaul Mackerras return (long)hose->io_base_phys; 9737568cb4eSPaul Mackerras case IOBASE_ISA_IO: 9747568cb4eSPaul Mackerras return (long)isa_io_base; 9757568cb4eSPaul Mackerras case IOBASE_ISA_MEM: 9767568cb4eSPaul Mackerras return -EINVAL; 9777568cb4eSPaul Mackerras } 9787568cb4eSPaul Mackerras 9797568cb4eSPaul Mackerras return -EOPNOTSUPP; 9807568cb4eSPaul Mackerras } 981357518faSAnton Blanchard 982357518faSAnton Blanchard #ifdef CONFIG_NUMA 983357518faSAnton Blanchard int pcibus_to_node(struct pci_bus *bus) 984357518faSAnton Blanchard { 985357518faSAnton Blanchard struct pci_controller *phb = pci_bus_to_host(bus); 986357518faSAnton Blanchard return phb->node; 987357518faSAnton Blanchard } 988357518faSAnton Blanchard EXPORT_SYMBOL(pcibus_to_node); 989357518faSAnton Blanchard #endif 990