diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-18 16:06:19 (GMT) |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-18 20:54:16 (GMT) |
commit | f6d2ce00da145ae31ec22d21daca6ca5e22b3c84 (patch) | |
tree | bb030290bc253b37bfad91de618c6f080f0b0af9 /arch/tile/kernel/pci_gx.c | |
parent | f1006257893917dfb1e0d74cb47b18c0e2908693 (diff) | |
download | linux-f6d2ce00da145ae31ec22d21daca6ca5e22b3c84.tar.xz |
tile: updates to pci root complex from community feedback
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/pci_gx.c')
-rw-r--r-- | arch/tile/kernel/pci_gx.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index 27f7ab0..fa75264 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -96,21 +96,6 @@ static struct pci_ops tile_cfg_ops; /* Mask of CPUs that should receive PCIe interrupts. */ static struct cpumask intr_cpus_map; -/* PCI I/O space support is not implemented. */ -static struct resource pci_ioport_resource = { - .name = "PCI IO", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO, -}; - -static struct resource pci_iomem_resource = { - .name = "PCI mem", - .start = TILE_PCI_MEM_START, - .end = TILE_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - /* * We don't need to worry about the alignment of resources. */ @@ -437,9 +422,26 @@ out: struct pci_controller *controller = &pci_controllers[i]; controller->index = i; - controller->last_busno = 0xff; controller->ops = &tile_cfg_ops; + /* + * The PCI memory resource is located above the PA space. + * For every host bridge, the BAR window or the MMIO aperture + * is in range [3GB, 4GB - 1] of a 4GB space beyond the + * PA space. + */ + + controller->mem_offset = TILE_PCI_MEM_START + + (i * TILE_PCI_BAR_WINDOW_TOP); + controller->mem_space.start = controller->mem_offset + + TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE; + controller->mem_space.end = controller->mem_offset + + TILE_PCI_BAR_WINDOW_TOP - 1; + controller->mem_space.flags = IORESOURCE_MEM; + snprintf(controller->mem_space_name, + sizeof(controller->mem_space_name), + "PCI mem domain %d", i); + controller->mem_space.name = controller->mem_space_name; } return num_rc_controllers; @@ -588,6 +590,7 @@ int __init pcibios_init(void) { resource_size_t offset; LIST_HEAD(resources); + int next_busno; int i; tile_pci_init(); @@ -628,7 +631,7 @@ int __init pcibios_init(void) msleep(250); /* Scan all of the recorded PCI controllers. */ - for (i = 0; i < num_rc_controllers; i++) { + for (next_busno = 0, i = 0; i < num_rc_controllers; i++) { struct pci_controller *controller = &pci_controllers[i]; gxio_trio_context_t *trio_context = controller->trio; TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; @@ -843,13 +846,14 @@ int __init pcibios_init(void) * The memory range for the PCI root bus should not overlap * with the physical RAM */ - pci_add_resource_offset(&resources, &iomem_resource, - 1ULL << CHIP_PA_WIDTH()); + pci_add_resource_offset(&resources, &controller->mem_space, + controller->mem_offset); - bus = pci_scan_root_bus(NULL, 0, controller->ops, + controller->first_busno = next_busno; + bus = pci_scan_root_bus(NULL, next_busno, controller->ops, controller, &resources); controller->root_bus = bus; - controller->last_busno = bus->subordinate; + next_busno = bus->subordinate + 1; } @@ -1011,20 +1015,9 @@ alloc_mem_map_failed: } subsys_initcall(pcibios_init); -/* - * PCI scan code calls the arch specific pcibios_fixup_bus() each time it scans - * a new bridge. Called after each bus is probed, but before its children are - * examined. - */ +/* Note: to be deleted after Linux 3.6 merge. */ void __devinit pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_dev *dev = bus->self; - - if (!dev) { - /* This is the root bus. */ - bus->resource[0] = &pci_ioport_resource; - bus->resource[1] = &pci_iomem_resource; - } } /* @@ -1124,7 +1117,10 @@ void __iomem *ioremap(resource_size_t phys_addr, unsigned long size) got_it: trio_fd = controller->trio->fd; - offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + phys_addr; + /* Convert the resource start to the bus address offset. */ + start = phys_addr - controller->mem_offset; + + offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + start; /* * We need to keep the PCI bus address's in-page offset in the VA. @@ -1172,11 +1168,11 @@ static int __devinit tile_cfg_read(struct pci_bus *bus, void *mmio_addr; /* - * Map all accesses to the local device (bus == 0) into the + * Map all accesses to the local device on root bus into the * MMIO space of the MAC. Accesses to the downstream devices * go to the PIO space. */ - if (busnum == 0) { + if (pci_is_root_bus(bus)) { if (device == 0) { /* * This is the internal downstream P2P bridge, @@ -1205,11 +1201,11 @@ static int __devinit tile_cfg_read(struct pci_bus *bus, } /* - * Accesses to the directly attached device (bus == 1) have to be + * Accesses to the directly attached device have to be * sent as type-0 configs. */ - if (busnum == 1) { + if (busnum == (controller->first_busno + 1)) { /* * There is only one device off of our built-in P2P bridge. */ @@ -1303,11 +1299,11 @@ static int __devinit tile_cfg_write(struct pci_bus *bus, u8 val_8 = (u8)val; /* - * Map all accesses to the local device (bus == 0) into the + * Map all accesses to the local device on root bus into the * MMIO space of the MAC. Accesses to the downstream devices * go to the PIO space. */ - if (busnum == 0) { + if (pci_is_root_bus(bus)) { if (device == 0) { /* * This is the internal downstream P2P bridge, @@ -1336,11 +1332,11 @@ static int __devinit tile_cfg_write(struct pci_bus *bus, } /* - * Accesses to the directly attached device (bus == 1) have to be + * Accesses to the directly attached device have to be * sent as type-0 configs. */ - if (busnum == 1) { + if (busnum == (controller->first_busno + 1)) { /* * There is only one device off of our built-in P2P bridge. */ |