powerpc/powernv: Reserve the correct PE number
We're assigning PE numbers after the completion of PCI probe. During the PCI probe, we had PE#0 as the super container to encompass all PCI devices. However, that's inappropriate since PELTM has ascending order of priority on search on P7IOC. So we need PE#127 takes the role that PE#0 has previously. For PHB3, we still have PE#0 as the reserved PE. The patch supposes that the underly firmware has built the RID to PE# mapping after resetting IODA tables: all PELTM entries except last one has invalid mapping on P7IOC, but all RTEs have binding to PE#0. The reserved PE# is being exported by firmware by device tree. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>hifive-unleashed-5.1
parent
631ad691b5
commit
36954dc78d
|
@ -1209,12 +1209,13 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
||||||
pr_err(" Failed to map registers !\n");
|
pr_err(" Failed to map registers !\n");
|
||||||
|
|
||||||
/* Initialize more IODA stuff */
|
/* Initialize more IODA stuff */
|
||||||
|
phb->ioda.total_pe = 1;
|
||||||
prop32 = of_get_property(np, "ibm,opal-num-pes", NULL);
|
prop32 = of_get_property(np, "ibm,opal-num-pes", NULL);
|
||||||
if (!prop32)
|
if (prop32)
|
||||||
phb->ioda.total_pe = 1;
|
|
||||||
else
|
|
||||||
phb->ioda.total_pe = be32_to_cpup(prop32);
|
phb->ioda.total_pe = be32_to_cpup(prop32);
|
||||||
|
prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL);
|
||||||
|
if (prop32)
|
||||||
|
phb->ioda.reserved_pe = be32_to_cpup(prop32);
|
||||||
phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
|
phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
|
||||||
/* FW Has already off top 64k of M32 space (MSI space) */
|
/* FW Has already off top 64k of M32 space (MSI space) */
|
||||||
phb->ioda.m32_size += 0x10000;
|
phb->ioda.m32_size += 0x10000;
|
||||||
|
@ -1243,7 +1244,7 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
||||||
if (phb->type == PNV_PHB_IODA1)
|
if (phb->type == PNV_PHB_IODA1)
|
||||||
phb->ioda.io_segmap = aux + iomap_off;
|
phb->ioda.io_segmap = aux + iomap_off;
|
||||||
phb->ioda.pe_array = aux + pemap_off;
|
phb->ioda.pe_array = aux + pemap_off;
|
||||||
set_bit(0, phb->ioda.pe_alloc);
|
set_bit(phb->ioda.reserved_pe, phb->ioda.pe_alloc);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&phb->ioda.pe_dma_list);
|
INIT_LIST_HEAD(&phb->ioda.pe_dma_list);
|
||||||
INIT_LIST_HEAD(&phb->ioda.pe_list);
|
INIT_LIST_HEAD(&phb->ioda.pe_list);
|
||||||
|
@ -1268,8 +1269,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
||||||
segment_size);
|
segment_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n",
|
pr_info(" %d (%d) PE's M32: 0x%x [segment=0x%x]"
|
||||||
|
" IO: 0x%x [segment=0x%x]\n",
|
||||||
phb->ioda.total_pe,
|
phb->ioda.total_pe,
|
||||||
|
phb->ioda.reserved_pe,
|
||||||
phb->ioda.m32_size, phb->ioda.m32_segsize,
|
phb->ioda.m32_size, phb->ioda.m32_segsize,
|
||||||
phb->ioda.io_size, phb->ioda.io_segsize);
|
phb->ioda.io_size, phb->ioda.io_segsize);
|
||||||
|
|
||||||
|
@ -1306,13 +1309,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
||||||
rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
|
rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
|
||||||
if (rc)
|
if (rc)
|
||||||
pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc);
|
pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc);
|
||||||
|
|
||||||
/*
|
|
||||||
* On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset
|
|
||||||
* has cleared the RTT which has the same effect
|
|
||||||
*/
|
|
||||||
if (ioda_type == PNV_PHB_IODA1)
|
|
||||||
opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init pnv_pci_init_ioda2_phb(struct device_node *np)
|
void __init pnv_pci_init_ioda2_phb(struct device_node *np)
|
||||||
|
|
|
@ -242,11 +242,15 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
|
||||||
/*
|
/*
|
||||||
* Get the PE#. During the PCI probe stage, we might not
|
* Get the PE#. During the PCI probe stage, we might not
|
||||||
* setup that yet. So all ER errors should be mapped to
|
* setup that yet. So all ER errors should be mapped to
|
||||||
* PE#0
|
* reserved PE.
|
||||||
*/
|
*/
|
||||||
pe_no = PCI_DN(dn)->pe_number;
|
pe_no = PCI_DN(dn)->pe_number;
|
||||||
if (pe_no == IODA_INVALID_PE)
|
if (pe_no == IODA_INVALID_PE) {
|
||||||
pe_no = 0;
|
if (phb->type == PNV_PHB_P5IOC2)
|
||||||
|
pe_no = 0;
|
||||||
|
else
|
||||||
|
pe_no = phb->ioda.reserved_pe;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read freeze status */
|
/* Read freeze status */
|
||||||
rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
|
rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
|
||||||
|
|
|
@ -125,6 +125,7 @@ struct pnv_phb {
|
||||||
struct {
|
struct {
|
||||||
/* Global bridge info */
|
/* Global bridge info */
|
||||||
unsigned int total_pe;
|
unsigned int total_pe;
|
||||||
|
unsigned int reserved_pe;
|
||||||
unsigned int m32_size;
|
unsigned int m32_size;
|
||||||
unsigned int m32_segsize;
|
unsigned int m32_segsize;
|
||||||
unsigned int m32_pci_base;
|
unsigned int m32_pci_base;
|
||||||
|
|
Loading…
Reference in New Issue