#define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH())
/*
- * End of the PCI memory resource.
+ * Start of the PCI memory resource, which starts at the end of the
+ * maximum system physical RAM address.
*/
-#define TILE_PCI_MEM_END \
- ((1ULL << CHIP_PA_WIDTH()) + TILE_PCI_BAR_WINDOW_TOP)
-
-/*
- * Start of the PCI memory resource.
- */
-#define TILE_PCI_MEM_START (TILE_PCI_MEM_END - TILE_PCI_BAR_WINDOW_SIZE)
+#define TILE_PCI_MEM_START (1ULL << CHIP_PA_WIDTH())
/*
* Structure of a PCI controller (host bridge) on Gx.
int index; /* PCI domain number */
struct pci_bus *root_bus;
+ /* PCI memory space resource for this controller. */
+ struct resource mem_space;
+ char mem_space_name[32];
+
uint64_t mem_offset; /* cpu->bus memory mapping offset. */
- int last_busno;
+ int first_busno;
struct pci_ops *ops;
/* Table that maps the INTx numbers to Linux irq numbers. */
int irq_intx_table[4];
- struct resource mem_space;
-
/* Address ranges that are routed to this controller/bridge. */
struct resource mem_resources[3];
};
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
- struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
- struct pci_bus_region *region);
-
/*
* The PCI address space does not equal the physical memory address
* space (we have an IOMMU). The IDE and SCSI device layers use this
/* 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.
*/
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;
{
resource_size_t offset;
LIST_HEAD(resources);
+ int next_busno;
int i;
tile_pci_init();
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;
* 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;
}
}
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;
- }
}
/*
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.
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,
}
/*
- * 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.
*/
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,
}
/*
- * 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.
*/