|
@@ -194,14 +194,14 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb)
|
|
|
set_bit(phb->ioda.m64_bar_idx, &phb->ioda.m64_bar_alloc);
|
|
|
|
|
|
/*
|
|
|
- * Strip off the segment used by the reserved PE, which is
|
|
|
- * expected to be 0 or last one of PE capability.
|
|
|
+ * Exclude the segments for reserved and root bus PE, which
|
|
|
+ * are first or last two PEs.
|
|
|
*/
|
|
|
r = &phb->hose->mem_resources[1];
|
|
|
if (phb->ioda.reserved_pe_idx == 0)
|
|
|
- r->start += phb->ioda.m64_segsize;
|
|
|
+ r->start += (2 * phb->ioda.m64_segsize);
|
|
|
else if (phb->ioda.reserved_pe_idx == (phb->ioda.total_pe_num - 1))
|
|
|
- r->end -= phb->ioda.m64_segsize;
|
|
|
+ r->end -= (2 * phb->ioda.m64_segsize);
|
|
|
else
|
|
|
pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
|
|
|
phb->ioda.reserved_pe_idx);
|
|
@@ -281,14 +281,14 @@ static int pnv_ioda1_init_m64(struct pnv_phb *phb)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Exclude the segment used by the reserved PE, which
|
|
|
- * is expected to be 0 or last supported PE#.
|
|
|
+ * Exclude the segments for reserved and root bus PE, which
|
|
|
+ * are first or last two PEs.
|
|
|
*/
|
|
|
r = &phb->hose->mem_resources[1];
|
|
|
if (phb->ioda.reserved_pe_idx == 0)
|
|
|
- r->start += phb->ioda.m64_segsize;
|
|
|
+ r->start += (2 * phb->ioda.m64_segsize);
|
|
|
else if (phb->ioda.reserved_pe_idx == (phb->ioda.total_pe_num - 1))
|
|
|
- r->end -= phb->ioda.m64_segsize;
|
|
|
+ r->end -= (2 * phb->ioda.m64_segsize);
|
|
|
else
|
|
|
WARN(1, "Wrong reserved PE#%d on PHB#%d\n",
|
|
|
phb->ioda.reserved_pe_idx, phb->hose->global_number);
|
|
@@ -1062,8 +1062,13 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ /* PE number for root bus should have been reserved */
|
|
|
+ if (pci_is_root_bus(bus) &&
|
|
|
+ phb->ioda.root_pe_idx != IODA_INVALID_PE)
|
|
|
+ pe = &phb->ioda.pe_array[phb->ioda.root_pe_idx];
|
|
|
+
|
|
|
/* Check if PE is determined by M64 */
|
|
|
- if (phb->pick_m64_pe)
|
|
|
+ if (!pe && phb->pick_m64_pe)
|
|
|
pe = phb->pick_m64_pe(bus, all);
|
|
|
|
|
|
/* The PE number isn't pinned by M64 */
|
|
@@ -3226,6 +3231,15 @@ static void pnv_pci_setup_bridge(struct pci_bus *bus, unsigned long type)
|
|
|
struct pnv_ioda_pe *pe;
|
|
|
bool all = (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE);
|
|
|
|
|
|
+ /* The PE for root bus should be realized before any one else */
|
|
|
+ if (!phb->ioda.root_pe_populated) {
|
|
|
+ pe = pnv_ioda_setup_bus_PE(phb->hose->bus, false);
|
|
|
+ if (pe) {
|
|
|
+ phb->ioda.root_pe_idx = pe->pe_number;
|
|
|
+ phb->ioda.root_pe_populated = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* Don't assign PE to PCI bus, which doesn't have subordinate devices */
|
|
|
if (list_empty(&bus->devices))
|
|
|
return;
|
|
@@ -3499,7 +3513,22 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|
|
phb->ioda.dma32_segmap[segno] = IODA_INVALID_PE;
|
|
|
}
|
|
|
phb->ioda.pe_array = aux + pemap_off;
|
|
|
- set_bit(phb->ioda.reserved_pe_idx, phb->ioda.pe_alloc);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Choose PE number for root bus, which shouldn't have
|
|
|
+ * M64 resources consumed by its child devices. To pick
|
|
|
+ * the PE number adjacent to the reserved one if possible.
|
|
|
+ */
|
|
|
+ pnv_ioda_reserve_pe(phb, phb->ioda.reserved_pe_idx);
|
|
|
+ if (phb->ioda.reserved_pe_idx == 0) {
|
|
|
+ phb->ioda.root_pe_idx = 1;
|
|
|
+ pnv_ioda_reserve_pe(phb, phb->ioda.root_pe_idx);
|
|
|
+ } else if (phb->ioda.reserved_pe_idx == (phb->ioda.total_pe_num - 1)) {
|
|
|
+ phb->ioda.root_pe_idx = phb->ioda.reserved_pe_idx - 1;
|
|
|
+ pnv_ioda_reserve_pe(phb, phb->ioda.root_pe_idx);
|
|
|
+ } else {
|
|
|
+ phb->ioda.root_pe_idx = IODA_INVALID_PE;
|
|
|
+ }
|
|
|
|
|
|
INIT_LIST_HEAD(&phb->ioda.pe_list);
|
|
|
mutex_init(&phb->ioda.pe_list_mutex);
|