@@ -236,6 +236,13 @@ static int pnv_ioda1_init_m64(struct pnv_phb *phb)
pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
phb->ioda.reserved_pe_idx);
+ /* Strip off the M64 segment corresponding to the PE#
+ * for PCI root bus, which is last supported PE# or
+ * (reserved PE# - 1).
+ */
+ if (phb->ioda.root_pe_idx != IODA_INVALID_PE)
+ r->end -= phb->ioda.m64_segsize;
+
return 0;
fail:
@@ -293,6 +300,13 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb)
pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
phb->ioda.reserved_pe_idx);
+ /* Strip off the M64 segment corresponding to the PE#
+ * for PCI root bus, which is last supported PE# or
+ * (reserved PE# - 1).
+ */
+ if (phb->ioda.root_pe_idx != IODA_INVALID_PE)
+ r->end -= phb->ioda.m64_segsize;
+
return 0;
fail:
@@ -3237,7 +3251,21 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
aux = memblock_virt_alloc(size, 0);
phb->ioda.pe_alloc = aux;
phb->ioda.pe_array = aux + pemap_off;
- set_bit(phb->ioda.reserved_pe_idx, phb->ioda.pe_alloc);
+
+ /* Choose number of PE for root bus, which shouldn't consume
+ * any M64 resource. So we avoid picking low-end PE#, which
+ * is usually bound with M64 resources closely.
+ */
+ pnv_ioda_reserve_pe(phb, phb->ioda.reserved_pe_idx);
+ if (phb->ioda.reserved_pe_idx == 0) {
+ phb->ioda.root_pe_idx = phb->ioda.total_pe_num - 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_dma_list);
INIT_LIST_HEAD(&phb->ioda.pe_list);
@@ -135,6 +135,7 @@ struct pnv_phb {
struct {
/* Global bridge info */
unsigned int total_pe_num;
+ unsigned int root_pe_idx;
unsigned int reserved_pe_idx;
/* 32-bit MMIO window */
pcibios_setup_bridge() is normally called to update PCI bridge windows. It allocates PE for PCI buses. However it is not called on a root bus which does not have an upstream bridge. This reserves PE# for a root bus in advance. This will be used in the subsequent patch to do setup. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- arch/powerpc/platforms/powernv/pci-ioda.c | 30 +++++++++++++++++++++++++++++- arch/powerpc/platforms/powernv/pci.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-)