mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-29 13:00:35 +00:00
powerpc/powernv: Setup PE for root bus
There is no parent bridge for root bus, meaning pcibios_setup_bridge() isn't invoked for root bus. The PE for root bus is the ancestor of other PEs in PELTV. It means we need PE for root bus populated before all others. This populates the PE for root bus in pcibios_setup_bridge() path if it's not populated yet. The PE number next to the reserved one is used as the PE# to avoid holes in continuous M64 space. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
ccd1c1911a
commit
63803c39c8
@ -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);
|
set_bit(phb->ioda.m64_bar_idx, &phb->ioda.m64_bar_alloc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strip off the segment used by the reserved PE, which is
|
* Exclude the segments for reserved and root bus PE, which
|
||||||
* expected to be 0 or last one of PE capability.
|
* are first or last two PEs.
|
||||||
*/
|
*/
|
||||||
r = &phb->hose->mem_resources[1];
|
r = &phb->hose->mem_resources[1];
|
||||||
if (phb->ioda.reserved_pe_idx == 0)
|
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))
|
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
|
else
|
||||||
pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
|
pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
|
||||||
phb->ioda.reserved_pe_idx);
|
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
|
* Exclude the segments for reserved and root bus PE, which
|
||||||
* is expected to be 0 or last supported PE#.
|
* are first or last two PEs.
|
||||||
*/
|
*/
|
||||||
r = &phb->hose->mem_resources[1];
|
r = &phb->hose->mem_resources[1];
|
||||||
if (phb->ioda.reserved_pe_idx == 0)
|
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))
|
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
|
else
|
||||||
WARN(1, "Wrong reserved PE#%d on PHB#%d\n",
|
WARN(1, "Wrong reserved PE#%d on PHB#%d\n",
|
||||||
phb->ioda.reserved_pe_idx, phb->hose->global_number);
|
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;
|
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 */
|
/* 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);
|
pe = phb->pick_m64_pe(bus, all);
|
||||||
|
|
||||||
/* The PE number isn't pinned by M64 */
|
/* 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;
|
struct pnv_ioda_pe *pe;
|
||||||
bool all = (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE);
|
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 */
|
/* Don't assign PE to PCI bus, which doesn't have subordinate devices */
|
||||||
if (list_empty(&bus->devices))
|
if (list_empty(&bus->devices))
|
||||||
return;
|
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.dma32_segmap[segno] = IODA_INVALID_PE;
|
||||||
}
|
}
|
||||||
phb->ioda.pe_array = aux + pemap_off;
|
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);
|
INIT_LIST_HEAD(&phb->ioda.pe_list);
|
||||||
mutex_init(&phb->ioda.pe_list_mutex);
|
mutex_init(&phb->ioda.pe_list_mutex);
|
||||||
|
@ -110,6 +110,8 @@ struct pnv_phb {
|
|||||||
/* Global bridge info */
|
/* Global bridge info */
|
||||||
unsigned int total_pe_num;
|
unsigned int total_pe_num;
|
||||||
unsigned int reserved_pe_idx;
|
unsigned int reserved_pe_idx;
|
||||||
|
unsigned int root_pe_idx;
|
||||||
|
bool root_pe_populated;
|
||||||
|
|
||||||
/* 32-bit MMIO window */
|
/* 32-bit MMIO window */
|
||||||
unsigned int m32_size;
|
unsigned int m32_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user