diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-11-04 03:32:47 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-11-05 22:13:52 -0500 |
commit | 36954dc78d8a1dcd4780cf4bd0fc6292791821b9 (patch) | |
tree | 896bea4d43edad65577bd4e061fa846bd57df786 /arch | |
parent | 631ad691b5818291d89af9be607d2fe40be0886e (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 1 |
3 files changed, 17 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 198566e1da71..084cdfa40682 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -1209,12 +1209,13 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1209 | pr_err(" Failed to map registers !\n"); | 1209 | pr_err(" Failed to map registers !\n"); |
1210 | 1210 | ||
1211 | /* Initialize more IODA stuff */ | 1211 | /* Initialize more IODA stuff */ |
1212 | phb->ioda.total_pe = 1; | ||
1212 | prop32 = of_get_property(np, "ibm,opal-num-pes", NULL); | 1213 | prop32 = of_get_property(np, "ibm,opal-num-pes", NULL); |
1213 | if (!prop32) | 1214 | if (prop32) |
1214 | phb->ioda.total_pe = 1; | ||
1215 | else | ||
1216 | phb->ioda.total_pe = be32_to_cpup(prop32); | 1215 | phb->ioda.total_pe = be32_to_cpup(prop32); |
1217 | 1216 | prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL); | |
1217 | if (prop32) | ||
1218 | phb->ioda.reserved_pe = be32_to_cpup(prop32); | ||
1218 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); | 1219 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); |
1219 | /* FW Has already off top 64k of M32 space (MSI space) */ | 1220 | /* FW Has already off top 64k of M32 space (MSI space) */ |
1220 | phb->ioda.m32_size += 0x10000; | 1221 | phb->ioda.m32_size += 0x10000; |
@@ -1243,7 +1244,7 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1243 | if (phb->type == PNV_PHB_IODA1) | 1244 | if (phb->type == PNV_PHB_IODA1) |
1244 | phb->ioda.io_segmap = aux + iomap_off; | 1245 | phb->ioda.io_segmap = aux + iomap_off; |
1245 | phb->ioda.pe_array = aux + pemap_off; | 1246 | phb->ioda.pe_array = aux + pemap_off; |
1246 | set_bit(0, phb->ioda.pe_alloc); | 1247 | set_bit(phb->ioda.reserved_pe, phb->ioda.pe_alloc); |
1247 | 1248 | ||
1248 | INIT_LIST_HEAD(&phb->ioda.pe_dma_list); | 1249 | INIT_LIST_HEAD(&phb->ioda.pe_dma_list); |
1249 | INIT_LIST_HEAD(&phb->ioda.pe_list); | 1250 | INIT_LIST_HEAD(&phb->ioda.pe_list); |
@@ -1268,8 +1269,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1268 | segment_size); | 1269 | segment_size); |
1269 | #endif | 1270 | #endif |
1270 | 1271 | ||
1271 | pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n", | 1272 | pr_info(" %d (%d) PE's M32: 0x%x [segment=0x%x]" |
1273 | " IO: 0x%x [segment=0x%x]\n", | ||
1272 | phb->ioda.total_pe, | 1274 | phb->ioda.total_pe, |
1275 | phb->ioda.reserved_pe, | ||
1273 | phb->ioda.m32_size, phb->ioda.m32_segsize, | 1276 | phb->ioda.m32_size, phb->ioda.m32_segsize, |
1274 | phb->ioda.io_size, phb->ioda.io_segsize); | 1277 | phb->ioda.io_size, phb->ioda.io_segsize); |
1275 | 1278 | ||
@@ -1306,13 +1309,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1306 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | 1309 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); |
1307 | if (rc) | 1310 | if (rc) |
1308 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); | 1311 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); |
1309 | |||
1310 | /* | ||
1311 | * On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset | ||
1312 | * has cleared the RTT which has the same effect | ||
1313 | */ | ||
1314 | if (ioda_type == PNV_PHB_IODA1) | ||
1315 | opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); | ||
1316 | } | 1312 | } |
1317 | 1313 | ||
1318 | void __init pnv_pci_init_ioda2_phb(struct device_node *np) | 1314 | void __init pnv_pci_init_ioda2_phb(struct device_node *np) |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 921ae673baf3..4eb33a9ed532 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -242,11 +242,15 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, | |||
242 | /* | 242 | /* |
243 | * Get the PE#. During the PCI probe stage, we might not | 243 | * Get the PE#. During the PCI probe stage, we might not |
244 | * setup that yet. So all ER errors should be mapped to | 244 | * setup that yet. So all ER errors should be mapped to |
245 | * PE#0 | 245 | * reserved PE. |
246 | */ | 246 | */ |
247 | pe_no = PCI_DN(dn)->pe_number; | 247 | pe_no = PCI_DN(dn)->pe_number; |
248 | if (pe_no == IODA_INVALID_PE) | 248 | if (pe_no == IODA_INVALID_PE) { |
249 | pe_no = 0; | 249 | if (phb->type == PNV_PHB_P5IOC2) |
250 | pe_no = 0; | ||
251 | else | ||
252 | pe_no = phb->ioda.reserved_pe; | ||
253 | } | ||
250 | 254 | ||
251 | /* Read freeze status */ | 255 | /* Read freeze status */ |
252 | rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, | 256 | rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 64d3b12e5b6d..911c24ef033e 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -125,6 +125,7 @@ struct pnv_phb { | |||
125 | struct { | 125 | struct { |
126 | /* Global bridge info */ | 126 | /* Global bridge info */ |
127 | unsigned int total_pe; | 127 | unsigned int total_pe; |
128 | unsigned int reserved_pe; | ||
128 | unsigned int m32_size; | 129 | unsigned int m32_size; |
129 | unsigned int m32_segsize; | 130 | unsigned int m32_segsize; |
130 | unsigned int m32_pci_base; | 131 | unsigned int m32_pci_base; |