/* * Support PCI/PCIe on PowerNV platforms * * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #define DEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "powernv.h" #include "pci.h" struct resource_wrap { struct list_head link; resource_size_t size; resource_size_t align; struct pci_dev *dev; /* Set if it's a device */ struct pci_bus *bus; /* Set if it's a bridge */ }; static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe, struct va_format *vaf) { char pfix[32]; if (pe->pdev) strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix)); else sprintf(pfix, "%04x:%02x ", pci_domain_nr(pe->pbus), pe->pbus->number); return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf); } #define define_pe_printk_level(func, kern_level) \ static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \ { \ struct va_format vaf; \ va_list args; \ int r; \ \ va_start(args, fmt); \ \ vaf.fmt = fmt; \ vaf.va = &args; \ \ r = __pe_printk(kern_level, pe, &vaf); \ va_end(args); \ \ return r; \ } \ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); /* Calculate resource usage & alignment requirement of a single * device. This will also assign all resources within the device * for a given type starting at 0 for the biggest one and then * assigning in decreasing order of size. */ static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags, resource_size_t *size, resource_size_t *align) { resource_size_t start; struct resource *r; int i; pr_devel(" -> CDR %s\n", pci_name(dev)); *size = *align = 0; /* Clear the resources out and mark them all unset */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) { r = &dev->resource[i]; if (!(r->flags & flags)) continue; if (r->start) { r->end -= r->start; r->start = 0; } r->flags |= IORESOURCE_UNSET; } /* We currently keep all memory resources together, we * will handle prefetch & 64-bit separately in the future * but for now we stick everybody in M32 */ start = 0; for (;;) { resource_size_t max_size = 0; int max_no = -1; /* Find next biggest resource */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) { r = &dev->resource[i]; if (!(r->flags & IORESOURCE_UNSET) || !(r->flags & flags)) continue; if (resource_size(r) > max_size) { max_size = resource_size(r); max_no = i; } } if (max_no < 0) break; r = &dev->resource[max_no]; if (max_size > *align) *align = max_size; *size += max_size; r->start = start; start += max_size; r->end = r->start + max_size - 1; r->flags &= ~IORESOURCE_UNSET; pr_devel(" -> R%d %016llx..%016llx\n", max_no, r->start, r->end); } pr_devel(" <- CDR %s size=%llx align=%llx\n", pci_name(dev), *size, *align); } /* Allocate a resource "wrap" for a given device or bridge and * insert it at the right position in the sorted list */ static void __devinit pnv_ioda_add_wrap(struct list_head *list, struct pci_bus *bus, struct pci_dev *dev, resource_size_t size, resource_size_t align) { struct resource_wrap *w1, *w = kzalloc(sizeof(*w), GFP_KERNEL); w->size = size; w->align = align; w->dev = dev; w->bus = bus; list_for_each_entry(w1, list, link) { if (w1->align < align) { list_add_tail(&w->link, &w1->link); return; } } list_add_tail(&w->link, list); } /* Offset device resources of a given type */ static void __devinit pnv_ioda_offset_dev(struct pci_dev *dev, unsigned int flags, resource_size_t offset) { struct resource *r; int i; pr_devel(" -> ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); for (i = 0; i <= PCI_ROM_RESOURCE; i++) { r = &dev->resource[i]; if (r->flags & flags) { dev->resource[i].start += offset; dev->resource[i].end += offset; } } pr_devel(" <- ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); } /* Offset bus resources (& all children) of a given type */ static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus, unsigned int flags, resource_size_t offset) { struct resource *r; struct pci_dev *dev; struct pci_bus *cbus; int i; pr_devel(" -> OBR %s [%x] +%016llx\n", bus->self ? pci_name(bus->self) : "root", flags, offset); for (i = 0; i < 2; i++) { r = bus->resource[i]; if (r && (r->flags & flags)) { bus->resource[i]->start += offset; bus->resource[i]->end += offset; } } list_for_each_entry(dev, &bus->devices, bus_list) pnv_ioda_offset_dev(dev, flags, offset); list_for_each_entry(cbus, &bus->children, node) pnv_ioda_offset_bus(cbus, flags, offset); pr_devel(" <- OBR %s [%x]\n", bus->self ? pci_name(bus->self) : "root", flags); } /* This is the guts of our IODA resource allocation. This is called * recursively for each bus in the system. It calculates all the * necessary size and requirements for children and assign them * resources such that: * * - Each function fits in it's own contiguous set of IO/M32 * segment * * - All segments behind a P2P bridge are contiguous and obey * alignment constraints of those bridges */ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, resource_size_t *size, resource_size_t *align) { struct pci_controller *hose = pci_bus_to_host(bus); struct pnv_phb *phb = hose->private_data; resource_size_t dev_size, dev_align, start; resource_size_t min_align, min_balign; struct pci_dev *cdev; struct pci_bus *cbus; struct list_head head; struct resource_wrap *w; unsigned int bres; *size = *align = 0; pr_devel("-> CBR %s [%x]\n", bus->self ? pci_name(bus->self) : "root", flags); /* Calculate alignment requirements based on the type * of resource we are working on */ if (flags & IORESOURCE_IO) { bres = 0; min_align = phb->ioda.io_segsize; min_balign = 0x1000; } else { bres = 1; min_align = phb->ioda.m32_segsize; min_balign = 0x100000; } /* Gather all our children resources ordered by alignment */ INIT_LIST_HEAD(&head); /* - Busses */ list_for_each_entry(cbus, &bus->children, node) { pnv_ioda_calc_bus(cbus, flags, &dev_size, &dev_align); pnv_ioda_add_wrap(&head, cbus, NULL, dev_size, dev_align); } /* - Devices */ list_for_each_entry(cdev, &bus->devices, bus_list) { pnv_ioda_calc_dev(cdev, flags, &dev_size, &dev_align); /* Align them to segment size */ if (dev_align < min_align) dev_align = min_align; pnv_ioda_add_wrap(&head, NULL, cdev, dev_size, dev_align); } if (list_empty(&head)) goto empty; /* Now we can do two things: assign offsets to them within that * level and get our total alignment & size requirements. The * assignment algorithm is going to be uber-trivial for now, we * can try to be smarter later at filling out holes. */ start = bus->self ? 0 : bus->resource[bres]->start; /* Don't hand out IO 0 */ if ((flags & IORESOURCE_IO) && !bus->self) start += 0x1000; while(!list_empty(&head)) { w = list_first_entry(&head, struct resource_wrap, link); list_del(&w->link); if (w->size) { if (start) { start = ALIGN(start, w->align); if (w->dev) pnv_ioda_offset_dev(w->dev,flags,start); else if (w->bus) pnv_ioda_offset_bus(w->bus,flags,start); } if (w->align > *align) *align = w->align; } start += w->size; kfree(w); } *size = start; /* Align and setup bridge resources */ *align = max_t(resource_size_t, *align, max_t(resource_size_t, min_align, min_balign)); *size = ALIGN(*size, max_t(resource_size_t, min_align, min_balign)); empty: /* Only setup P2P's, not the PHB itself */ if (bus->self) { WARN_ON(bus->resource[bres] == NULL); bus->resource[bres]->start = 0; bus->resource[bres]->flags = (*size) ? flags : 0; bus->resource[bres]->end = (*size) ? (*size - 1) : 0; /* Clear prefetch bus resources for now */ bus->resource[2]->flags = 0; } pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n", bus->self ? pci_name(bus->self) : "root", flags,*size,*align); } static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) { struct device_node *np; np = pci_device_to_OF_node(dev); if (!np) return NULL; return PCI_DN(np); } static void __devinit pnv_ioda_setup_pe_segments(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn = pnv_ioda_get_pdn(dev); unsigned int pe, i; resource_size_t pos; struct resource io_res; struct resource m32_res; struct pci_bus_region region; int rc; /* Anything not referenced in the device-tree gets PE#0 */ pe = pdn ? pdn->pe_number : 0; /* Calculate the device min/max */ io_res.start = m32_res.start = (resource_size_t)-1; io_res.end = m32_res.end = 0; io_res.flags = IORESOURCE_IO; m32_res.flags = IORESOURCE_MEM; for (i = 0; i <= PCI_ROM_RESOURCE; i++) { struct resource *r = NULL; if (dev->resource[i].flags & IORESOURCE_IO) r = &io_res; if (dev->resource[i].flags & IORESOURCE_MEM) r = &m32_res; if (!r) continue; if (dev->resource[i].start < r->start) r->start = dev->resource[i].start; if (dev->resource[i].end > r->end) r->end = dev->resource[i].end; } /* Setup IO segments */ if (io_res.start < io_res.end) { pcibios_resource_to_bus(dev, ®ion, &io_res); pos = region.start; i = pos / phb->ioda.io_segsize; while(i < phb->ioda.total_pe && pos <= region.end) { if (phb->ioda.io_segmap[i]) { pr_err("%s: Trying to use IO seg #%d which is" " already used by PE# %d\n", pci_name(dev), i, phb->ioda.io_segmap[i]); /* XXX DO SOMETHING TO DISABLE DEVICE ? */ break; } phb->ioda.io_segmap[i] = pe; rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, OPAL_IO_WINDOW_TYPE, 0, i); if (rc != OPAL_SUCCESS) { pr_err("%s: OPAL error %d setting up mapping" " for IO seg# %d\n", pci_name(dev), rc, i); /* XXX DO SOMETHING TO DISABLE DEVICE ? */ break; } pos += phb->ioda.io_segsize; i++; }; } /* Setup M32 segments */ if (m32_res.start < m32_res.end) { pcibios_resource_to_bus(dev, ®ion, &m32_res); pos = region.start; i = pos / phb->ioda.m32_segsize; while(i < phb->ioda.total_pe && pos <= region.end) { if (phb->ioda.m32_segmap[i]) { pr_err("%s: Trying to use M32 seg #%d which is" " already used by PE# %d\n", pci_name(dev), i, phb->ioda.m32_segmap[i]); /* XXX DO SOMETHING TO DISABLE DEVICE ? */ break; } phb->ioda.m32_segmap[i] = pe; rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, OPAL_M32_WINDOW_TYPE, 0, i); if (rc != OPAL_SUCCESS) { pr_err("%s: OPAL error %d setting up mapping" " for M32 seg# %d\n", pci_name(dev), rc, i); /* XXX DO SOMETHING TO DISABLE DEVICE ? */ break; } pos += phb->ioda.m32_segsize; i++; } } } /* Check if a resource still fits in the total IO or M32 range * for a given PHB */ static int __devinit pnv_ioda_resource_fit(struct pci_controller *hose, struct resource *r) { struct resource *bounds; if (r->flags & IORESOURCE_IO) bounds = &hose->io_resource; else if (r->flags & IORESOURCE_MEM) bounds = &hose->mem_resources[0]; else return 1; if (r->start >= bounds->start && r->end <= bounds->end) return 1; r->flags = 0; return 0; } static void __devinit pnv_ioda_update_resources(struct pci_bus *bus) { struct pci_controller *hose = pci_bus_to_host(bus); struct pci_bus *cbus; struct pci_dev *cdev; unsigned int i; u16 cmd; /* Clear all device enables */ list_for_each_entry(cdev, &bus->devices, bus_list) { pci_read_config_word(cdev, PCI_COMMAND, &cmd); cmd &= ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER); pci_write_config_word(cdev, PCI_COMMAND, cmd); } /* Check if bus resources fit in our IO or M32 range */ for (i = 0; bus->self && (i < 2); i++) { struct resource *r = bus->resource[i]; if (r && !pnv_ioda_resource_fit(hose, r)) pr_err("%s: Bus %d resource %d disabled, no room\n", pci_name(bus->self), bus->number, i); } /* Update self if it's not a PHB */ if (bus->self) pci_setup_bridge(bus); /* Update child devices */ list_for_each_entry(cdev, &bus->devices, bus_list) { /* Check if resource fits, if not, disabled it */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) { struct resource *r = &cdev->resource[i]; if (!pnv_ioda_resource_fit(hose, r)) pr_err("%s: Resource %d disabled, no room\n", pci_name(cdev), i); } /* Assign segments */ pnv_ioda_setup_pe_segments(cdev); /* Update HW BARs */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) pci_update_resource(cdev, i); } /* Update child busses */ list_for_each_entry(cbus, &bus->children, node) pnv_ioda_update_resources(cbus); } static int __devinit pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; do { pe = find_next_zero_bit(phb->ioda.pe_alloc, phb->ioda.total_pe, 0); if (pe >= phb->ioda.total_pe) return IODA_INVALID_PE; } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); phb->ioda.pe_array[pe].pe_number = pe; return pe; } static void __devinit pnv_ioda_free_pe(struct pnv_phb *phb, int pe) { WARN_ON(phb->ioda.pe_array[pe].pdev); memset(&phb->ioda.pe_array[pe], 0, sizeof(struct pnv_ioda_pe)); clear_bit(pe, phb->ioda.pe_alloc); } /* Currently those 2 are only used when MSIs are enabled, this will change * but in the meantime, we need to protect them to avoid warnings */ #ifdef CONFIG_PCI_MSI static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn = pnv_ioda_get_pdn(dev); if (!pdn) return NULL; if (pdn->pe_number == IODA_INVALID_PE) return NULL; return &phb->ioda.pe_array[pdn->pe_number]; } static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) { struct pnv_ioda_pe *pe = __pnv_ioda_get_one_pe(dev); while (!pe && dev->bus->self) { dev = dev->bus->self; pe = __pnv_ioda_get_one_pe(dev); if (pe) pe = pe->bus_pe; } return pe; } #endif /* CONFIG_PCI_MSI */ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) { struct pci_dev *parent; uint8_t bcomp, dcomp, fcomp; long rc, rid_end, rid; /* Bus validation ? */ if (pe->pbus) { int count; dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; parent = pe->pbus->self; count = pe->pbus->subordinate - pe->pbus->secondary + 1; switch(count) { case 1: bcomp = OpalPciBusAll; break; case 2: bcomp = OpalPciBus7Bits; break; case 4: bcomp = OpalPciBus6Bits; break; case 8: bcomp = OpalPciBus5Bits; break; case 16: bcomp = OpalPciBus4Bits; break; case 32: bcomp = OpalPciBus3Bits; break; default: pr_err("%s: Number of subordinate busses %d" " unsupported\n", pci_name(pe->pbus->self), count); /* Do an exact match only */ bcomp = OpalPciBusAll; } rid_end = pe->rid + (count << 8); } else { parent = pe->pdev->bus->self; bcomp = OpalPciBusAll; dcomp = OPAL_COMPARE_RID_DEVICE_NUMBER; fcomp = OPAL_COMPARE_RID_FUNCTION_NUMBER; rid_end = pe->rid + 1; } /* Associate PE in PELT */ rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, bcomp, dcomp, fcomp, OPAL_MAP_PE); if (rc) { pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc); return -ENXIO; } opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); /* Add to all parents PELT-V */ while (parent) { struct pci_dn *pdn = pnv_ioda_get_pdn(parent); if (pdn && pdn->pe_number != IODA_INVALID_PE) { rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, pe->pe_number, 1); /* XXX What to do in case of error ? */ } parent = parent->bus->self; } /* Setup reverse map */ for (rid = pe->rid; rid < rid_end; rid++) phb->ioda.pe_rmap[rid] = pe->pe_number; /* Setup one MVTs on IODA1 */ if (phb->type == PNV_PHB_IODA1) { pe->mve_number = pe->pe_number; rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, pe->pe_number); if (rc) { pe_err(pe, "OPAL error %ld setting up MVE %d\n", rc, pe->mve_number); pe->mve_number = -1; } else { rc = opal_pci_set_mve_enable(phb->opal_id, pe->mve_number, 1); if (rc) { pe_err(pe, "OPAL error %ld enabling MVE %d\n", rc, pe->mve_number); pe->mve_number = -1; } } } else if (phb->type == PNV_PHB_IODA2) pe->mve_number = 0; return 0; } static void __devinit pnv_ioda_link_pe_by_weight(struct pnv_phb *phb, struct pnv_ioda_pe *pe) { struct pnv_ioda_pe *lpe; list_for_each_entry(lpe, &phb->ioda.pe_list, link) { if (lpe->dma_weight < pe->dma_weight) { list_add_tail(&pe->link, &lpe->link); return; } } list_add_tail(&pe->link, &phb->ioda.pe_list); } static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev) { /* This is quite simplistic. The "base" weight of a device * is 10. 0 means no DMA is to be accounted for it. */ /* If it's a bridge, no DMA */ if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) return 0; /* Reduce the weight of slow USB controllers */ if (dev->class == PCI_CLASS_SERIAL_USB_UHCI || dev->class == PCI_CLASS_SERIAL_USB_OHCI || dev->class == PCI_CLASS_SERIAL_USB_EHCI) return 3; /* Increase the weight of RAID (includes Obsidian) */ if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) return 15; /* Default */ return 10; } static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn = pnv_ioda_get_pdn(dev); struct pnv_ioda_pe *pe; int pe_num; if (!pdn) { pr_err("%s: Device tree node not associated properly\n", pci_name(dev)); return NULL; } if (pdn->pe_number != IODA_INVALID_PE) return NULL; /* PE#0 has been pre-set */ if (dev->bus->number == 0) pe_num = 0; else pe_num = pnv_ioda_alloc_pe(phb); if (pe_num == IODA_INVALID_PE) { pr_warning("%s: Not enough PE# available, disabling device\n", pci_name(dev)); return NULL; } /* NOTE: We get only one ref to the pci_dev for the pdn, not for the * pointer in the PE data structure, both should be destroyed at the * same time. However, this needs to be looked at more closely again * once we actually start removing things (Hotplug, SR-IOV, ...) * * At some point we want to remove the PDN completely anyways */ pe = &phb->ioda.pe_array[pe_num]; pci_dev_get(dev); pdn->pcidev = dev; pdn->pe_number = pe_num; pe->pdev = dev; pe->pbus = NULL; pe->tce32_seg = -1; pe->mve_number = -1; pe->rid = dev->bus->number << 8 | pdn->devfn; pe_info(pe, "Associated device to PE\n"); if (pnv_ioda_configure_pe(phb, pe)) { /* XXX What do we do here ? */ if (pe_num) pnv_ioda_free_pe(phb, pe_num); pdn->pe_number = IODA_INVALID_PE; pe->pdev = NULL; pci_dev_put(dev); return NULL; } /* Assign a DMA weight to the device */ pe->dma_weight = pnv_ioda_dma_weight(dev); if (pe->dma_weight != 0) { phb->ioda.dma_weight += pe->dma_weight; phb->ioda.dma_pe_count++; } /* Link the PE */ pnv_ioda_link_pe_by_weight(phb, pe); return pe; } static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) { struct pci_dev *dev; list_for_each_entry(dev, &bus->devices, bus_list) { struct pci_dn *pdn = pnv_ioda_get_pdn(dev); if (pdn == NULL) { pr_warn("%s: No device node associated with device !\n", pci_name(dev)); continue; } pci_dev_get(dev); pdn->pcidev = dev; pdn->pe_number = pe->pe_number; pe->dma_weight += pnv_ioda_dma_weight(dev); if (dev->subordinate) pnv_ioda_setup_same_PE(dev->subordinate, pe); } } static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, struct pnv_ioda_pe *ppe) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; struct pci_bus *bus = dev->subordinate; struct pnv_ioda_pe *pe; int pe_num; if (!bus) { pr_warning("%s: Bridge without a subordinate bus !\n", pci_name(dev)); return; } pe_num = pnv_ioda_alloc_pe(phb); if (pe_num == IODA_INVALID_PE) { pr_warning("%s: Not enough PE# available, disabling bus\n", pci_name(dev)); return; } pe = &phb->ioda.pe_array[pe_num]; ppe->bus_pe = pe; pe->pbus = bus; pe->pdev = NULL; pe->tce32_seg = -1; pe->mve_number = -1; pe->rid = bus->secondary << 8; pe->dma_weight = 0; pe_info(pe, "Secondary busses %d..%d associated with PE\n", bus->secondary, bus->subordinate); if (pnv_ioda_configure_pe(phb, pe)) { /* XXX What do we do here ? */ if (pe_num) pnv_ioda_free_pe(phb, pe_num); pe->pbus = NULL; return; } /* Associate it with all child devices */ pnv_ioda_setup_same_PE(bus, pe); /* Account for one DMA PE if at least one DMA capable device exist * below the bridge */ if (pe->dma_weight != 0) { phb->ioda.dma_weight += pe->dma_weight; phb->ioda.dma_pe_count++; } /* Link the PE */ pnv_ioda_link_pe_by_weight(phb, pe); } static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus) { struct pci_dev *dev; struct pnv_ioda_pe *pe; list_for_each_entry(dev, &bus->devices, bus_list) { pe = pnv_ioda_setup_dev_PE(dev); if (pe == NULL) continue; /* Leaving the PCIe domain ... single PE# */ if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) pnv_ioda_setup_bus_PE(dev, pe); else if (dev->subordinate) pnv_ioda_setup_PEs(dev->subordinate); } } static void __devinit pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) { /* We delay DMA setup after we have assigned all PE# */ } static void __devinit pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) { struct pci_dev *dev; list_for_each_entry(dev, &bus->devices, bus_list) { set_iommu_table_base(&dev->dev, &pe->tce32_table); if (dev->subordinate) pnv_ioda_setup_bus_dma(pe, dev->subordinate); } } static void __devinit pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe, unsigned int base, unsigned int segs) { struct page *tce_mem = NULL; const __be64 *swinvp; struct iommu_table *tbl; unsigned int i; int64_t rc; void *addr; /* 256M DMA window, 4K TCE pages, 8 bytes TCE */ #define TCE32_TABLE_SIZE ((0x10000000 / 0x1000) * 8) /* XXX FIXME: Handle 64-bit only DMA devices */ /* XXX FIXME: Provide 64-bit DMA facilities & non-4K TCE tables etc.. */ /* XXX FIXME: Allocate multi-level tables on PHB3 */ /* We shouldn't already have a 32-bit DMA associated */ if (WARN_ON(pe->tce32_seg >= 0)) return; /* Grab a 32-bit TCE table */ pe->tce32_seg = base; pe_info(pe, " Setting up 32-bit TCE table at %08x..%08x\n", (base << 28), ((base + segs) << 28) - 1); /* XXX Currently, we allocate one big contiguous table for the * TCEs. We only really need one chunk per 256M of TCE space * (ie per segment) but that's an optimization for later, it * requires some added smarts with our get/put_tce implementation */ tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL, get_order(TCE32_TABLE_SIZE * segs)); if (!tce_mem) { pe_err(pe, " Failed to allocate a 32-bit TCE memory\n"); goto fail; } addr = page_address(tce_mem); memset(addr, 0, TCE32_TABLE_SIZE * segs); /* Configure HW */ for (i = 0; i < segs; i++) { rc = opal_pci_map_pe_dma_window(phb->opal_id, pe->pe_number, base + i, 1, __pa(addr) + TCE32_TABLE_SIZE * i, TCE32_TABLE_SIZE, 0x1000); if (rc) { pe_err(pe, " Failed to configure 32-bit TCE table," " err %ld\n", rc); goto fail; } } /* Setup linux iommu table */ tbl = &pe->tce32_table; pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, base << 28); /* OPAL variant of P7IOC SW invalidated TCEs */ swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); if (swinvp) { /* We need a couple more fields -- an address and a data * to or. Since the bus is only printed out on table free * errors, and on the first pass the data will be a relative * bus number, print that out instead. */ tbl->it_busno = 0; tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | TCE_PCI_SWINV_PAIR; } iommu_init_table(tbl, phb->hose->node); if (pe->pdev) set_iommu_table_base(&pe->pdev->dev, tbl); else pnv_ioda_setup_bus_dma(pe, pe->pbus); return; fail: /* XXX Failure: Try to fallback to 64-bit only ? */ if (pe->tce32_seg >= 0) pe->tce32_seg = -1; if (tce_mem) __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); } static void __devinit pnv_ioda_setup_dma(struct pnv_phb *phb) { struct pci_controller *hose = phb->hose; unsigned int residual, remaining, segs, tw, base; struct pnv_ioda_pe *pe; /* If we have more PE# than segments available, hand out one * per PE until we run out and let the rest fail. If not, * then we assign at least one segment per PE, plus more based * on the amount of devices under that PE */ if (phb->ioda.dma_pe_count > phb->ioda.tce32_count) residual = 0; else residual = phb->ioda.tce32_count - phb->ioda.dma_pe_count; pr_info("PCI: Domain %04x has %ld available 32-bit DMA segments\n", hose->global_number, phb->ioda.tce32_count); pr_info("PCI: %d PE# for a total weight of %d\n", phb->ioda.dma_pe_count, phb->ioda.dma_weight); /* Walk our PE list and configure their DMA segments, hand them * out one base segment plus any residual segments based on * weight */ remaining = phb->ioda.tce32_count; tw = phb->ioda.dma_weight; base = 0; list_for_each_entry(pe, &phb->ioda.pe_list, link) { if (!pe->dma_weight) continue; if (!remaining) { pe_warn(pe, "No DMA32 resources available\n"); continue; } segs = 1; if (residual) { segs += ((pe->dma_weight * residual) + (tw / 2)) / tw; if (segs > remaining) segs = remaining; } pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", pe->dma_weight, segs); pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); remaining -= segs; base += segs; } } #ifdef CONFIG_PCI_MSI static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, unsigned int hwirq, unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); unsigned int xive_num = hwirq - phb->msi_base; uint64_t addr64; uint32_t addr32, data; int rc; /* No PE assigned ? bail out ... no MSI for you ! */ if (pe == NULL) return -ENXIO; /* Check if we have an MVE */ if (pe->mve_number < 0) return -ENXIO; /* Assign XIVE to PE */ rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); if (rc) { pr_warn("%s: OPAL error %d setting XIVE %d PE\n", pci_name(dev), rc, xive_num); return -EIO; } if (is_64) { rc = opal_get_msi_64(phb->opal_id, pe->mve_number, xive_num, 1, &addr64, &data); if (rc) { pr_warn("%s: OPAL error %d getting 64-bit MSI data\n", pci_name(dev), rc); return -EIO; } msg->address_hi = addr64 >> 32; msg->address_lo = addr64 & 0xfffffffful; } else { rc = opal_get_msi_32(phb->opal_id, pe->mve_number, xive_num, 1, &addr32, &data); if (rc) { pr_warn("%s: OPAL error %d getting 32-bit MSI data\n", pci_name(dev), rc); return -EIO; } msg->address_hi = 0; msg->address_lo = addr32; } msg->data = data; pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," " address=%x_%08x data=%x PE# %d\n", pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, msg->address_hi, msg->address_lo, data, pe->pe_number); return 0; } static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { unsigned int bmap_size; const __be32 *prop = of_get_property(phb->hose->dn, "ibm,opal-msi-ranges", NULL); if (!prop) { /* BML Fallback */ prop = of_get_property(phb->hose->dn, "msi-ranges", NULL); } if (!prop) return; phb->msi_base = be32_to_cpup(prop); phb->msi_count = be32_to_cpup(prop + 1); bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); if (!phb->msi_map) { pr_err("PCI %d: Failed to allocate MSI bitmap !\n", phb->hose->global_number); return; } phb->msi_setup = pnv_pci_ioda_msi_setup; phb->msi32_support = 1; pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", phb->msi_count, phb->msi_base); } #else static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } #endif /* CONFIG_PCI_MSI */ /* This is the starting point of our IODA specific resource * allocation process */ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose) { resource_size_t size, align; struct pci_bus *child; /* Associate PEs per functions */ pnv_ioda_setup_PEs(hose->bus); /* Calculate all resources */ pnv_ioda_calc_bus(hose->bus, IORESOURCE_IO, &size, &align); pnv_ioda_calc_bus(hose->bus, IORESOURCE_MEM, &size, &align); /* Apply then to HW */ pnv_ioda_update_resources(hose->bus); /* Setup DMA */ pnv_ioda_setup_dma(hose->private_data); /* Configure PCI Express settings */ list_for_each_entry(child, &hose->bus->children, node) { struct pci_dev *self = child->self; if (!self) continue; pcie_bus_configure_settings(child, self->pcie_mpss); } } /* Prevent enabling devices for which we couldn't properly * assign a PE */ static int __devinit pnv_pci_enable_device_hook(struct pci_dev *dev) { struct pci_dn *pdn = pnv_ioda_get_pdn(dev); if (!pdn || pdn->pe_number == IODA_INVALID_PE) return -EINVAL; return 0; } static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn) { return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; } void __init pnv_pci_init_ioda1_phb(struct device_node *np) { struct pci_controller *hose; static int primary = 1; struct pnv_phb *phb; unsigned long size, m32map_off, iomap_off, pemap_off; const u64 *prop64; u64 phb_id; void *aux; long rc; pr_info(" Initializing IODA OPAL PHB %s\n", np->full_name); prop64 = of_get_property(np, "ibm,opal-phbid", NULL); if (!prop64) { pr_err(" Missing \"ibm,opal-phbid\" property !\n"); return; } phb_id = be64_to_cpup(prop64); pr_debug(" PHB-ID : 0x%016llx\n", phb_id); phb = alloc_bootmem(sizeof(struct pnv_phb)); if (phb) { memset(phb, 0, sizeof(struct pnv_phb)); phb->hose = hose = pcibios_alloc_controller(np); } if (!phb || !phb->hose) { pr_err("PCI: Failed to allocate PCI controller for %s\n", np->full_name); return; } spin_lock_init(&phb->lock); /* XXX Use device-tree */ hose->first_busno = 0; hose->last_busno = 0xff; hose->private_data = phb; phb->opal_id = phb_id; phb->type = PNV_PHB_IODA1; /* We parse "ranges" now since we need to deduce the register base * from the IO base */ pci_process_bridge_OF_ranges(phb->hose, np, primary); primary = 0; /* Magic formula from Milton */ phb->regs = of_iomap(np, 0); if (phb->regs == NULL) pr_err(" Failed to map registers !\n"); /* XXX This is hack-a-thon. This needs to be changed so that: * - we obtain stuff like PE# etc... from device-tree * - we properly re-allocate M32 ourselves * (the OFW one isn't very good) */ /* Initialize more IODA stuff */ phb->ioda.total_pe = 128; phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); /* OFW Has already off top 64k of M32 space (MSI space) */ phb->ioda.m32_size += 0x10000; phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; phb->ioda.m32_pci_base = hose->mem_resources[0].start - hose->pci_mem_offset; phb->ioda.io_size = hose->pci_io_size; phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ /* Allocate aux data & arrays */ size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); m32map_off = size; size += phb->ioda.total_pe; iomap_off = size; size += phb->ioda.total_pe; pemap_off = size; size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); aux = alloc_bootmem(size); memset(aux, 0, size); phb->ioda.pe_alloc = aux; phb->ioda.m32_segmap = aux + m32map_off; phb->ioda.io_segmap = aux + iomap_off; phb->ioda.pe_array = aux + pemap_off; set_bit(0, phb->ioda.pe_alloc); INIT_LIST_HEAD(&phb->ioda.pe_list); /* Calculate how many 32-bit TCE segments we have */ phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28; /* Clear unusable m64 */ hose->mem_resources[1].flags = 0; hose->mem_resources[1].start = 0; hose->mem_resources[1].end = 0; hose->mem_resources[2].flags = 0; hose->mem_resources[2].start = 0; hose->mem_resources[2].end = 0; #if 0 rc = opal_pci_set_phb_mem_window(opal->phb_id, window_type, window_num, starting_real_address, starting_pci_address, segment_size); #endif pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n", phb->ioda.total_pe, phb->ioda.m32_size, phb->ioda.m32_segsize, phb->ioda.io_size, phb->ioda.io_segsize); if (phb->regs) { pr_devel(" BUID = 0x%016llx\n", in_be64(phb->regs + 0x100)); pr_devel(" PHB2_CR = 0x%016llx\n", in_be64(phb->regs + 0x160)); pr_devel(" IO_BAR = 0x%016llx\n", in_be64(phb->regs + 0x170)); pr_devel(" IO_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x178)); pr_devel(" IO_SAR = 0x%016llx\n", in_be64(phb->regs + 0x180)); pr_devel(" M32_BAR = 0x%016llx\n", in_be64(phb->regs + 0x190)); pr_devel(" M32_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x198)); pr_devel(" M32_SAR = 0x%016llx\n", in_be64(phb->regs + 0x1a0)); } phb->hose->ops = &pnv_pci_ops; /* Setup RID -> PE mapping function */ phb->bdfn_to_pe = pnv_ioda_bdfn_to_pe; /* Setup TCEs */ phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; /* Setup MSI support */ pnv_pci_init_ioda_msis(phb); /* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an * odd combination which essentially means that we skip all resource * fixups and assignments in the generic code, and do it all * ourselves here */ pci_probe_only = 1; ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; pci_add_flags(PCI_REASSIGN_ALL_RSRC); /* Reset IODA tables to a clean state */ rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); if (rc) pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); } void __init pnv_pci_init_ioda_hub(struct device_node *np) { struct device_node *phbn; const u64 *prop64; u64 hub_id; pr_info("Probing IODA IO-Hub %s\n", np->full_name); prop64 = of_get_property(np, "ibm,opal-hubid", NULL); if (!prop64) { pr_err(" Missing \"ibm,opal-hubid\" property !\n"); return; } hub_id = be64_to_cpup(prop64); pr_devel(" HUB-ID : 0x%016llx\n", hub_id); /* Count child PHBs */ for_each_child_of_node(np, phbn) { /* Look for IODA1 PHBs */ if (of_device_is_compatible(phbn, "ibm,ioda-phb")) pnv_pci_init_ioda1_phb(phbn); } }