aboutsummaryrefslogtreecommitdiff
path: root/hw/phb4.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-07-12 12:06:44 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-07-13 10:19:45 +1000
commitd63ed063f5dcb443be3226d2c7a48f2f4326e717 (patch)
tree905da36d5bc7dbe2912d951ae1dda67c60c22eb3 /hw/phb4.c
parentc5f23f29b6eef8e6c413d066e3bec5a8300a7cb8 (diff)
downloadskiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.zip
skiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.tar.gz
skiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.tar.bz2
phb4: Fix PHB4 fence recovery
We had a few problems: - We used the wrong register to trigger the reset (spec bug) - We should clear the PFIR and NFIR while the reset is asserted - ... and in the right order ! - We should only apply the DD1 workaround after the reset has been lifted. - We should ensure we use ASB whenever we are fenced or doing a CRESET - Make config ops write with ASB Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/phb4.c')
-rw-r--r--hw/phb4.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/hw/phb4.c b/hw/phb4.c
index 23b9f50..40c67b7 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -1854,9 +1854,6 @@ static void phb4_read_phb_status(struct phb4 *p,
phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_SRCID,
&stat->sourceId);
- /* Restore config space to MMIO instead of ASB */
- p->flags &= ~PHB4_CFG_USE_ASB;
-
/* PEC NFIR, same as P8/PHB3 */
xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &stat->nFir);
xscom_read(p->chip_id, p->pe_stk_xscom + 0x3, &stat->nFirMask);
@@ -2410,19 +2407,22 @@ static int64_t phb4_creset(struct pci_slot *slot)
xscom_write(p->chip_id, p->pe_stk_xscom + 0x2,
0x000000f000000000);
+ /*
+ * Force use of ASB for register access until the PHB has
+ * been fully reset.
+ */
+ p->flags |= PHB4_CFG_USE_ASB;
+
/* Clear errors, following the proper sequence */
phb4_err_clear(p);
- /* Clear errors in NFIR and raise ETU reset */
- xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &p->nfir_cache);
- xscom_read(p->chip_id, p->pci_stk_xscom + 0x0, &p->pfir_cache);
-
- xscom_write(p->chip_id, p->pci_stk_xscom + 0x0,
+ /* Actual reset */
+ xscom_write(p->chip_id, p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET,
0x8000000000000000);
- /* DD1 errata: write to PEST to force update */
- phb4_ioda_sel(p, IODA3_TBL_PESTA, PHB4_RESERVED_PE_NUM(p), false);
- out_be64(p->regs + PHB_IODA_DATA0, 0);
+ /* Clear errors in PFIR and NFIR */
+ xscom_read(p->chip_id, p->pci_stk_xscom + 0x0, &p->pfir_cache);
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &p->nfir_cache);
pci_slot_set_state(slot, PHB4_SLOT_CRESET_WAIT_CQ);
slot->retries = 500;
@@ -2438,8 +2438,14 @@ static int64_t phb4_creset(struct pci_slot *slot)
xscom_write(p->chip_id, p->pci_stk_xscom + 0x1,
~p->pfir_cache);
- // Clear PHB from reset
- xscom_write(p->chip_id, p->pci_stk_xscom + 0x0, 0x0);
+ /* Clear PHB from reset */
+ xscom_write(p->chip_id,
+ p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET, 0x0);
+
+ /* DD1 errata: write to PEST to force update */
+ phb4_ioda_sel(p, IODA3_TBL_PESTA, PHB4_RESERVED_PE_NUM(p),
+ false);
+ phb4_write_reg(p, PHB_IODA_DATA0, 0);
pci_slot_set_state(slot, PHB4_SLOT_CRESET_REINIT);
return pci_slot_set_sm_timeout(slot, msecs_to_tb(100));
@@ -2455,6 +2461,7 @@ static int64_t phb4_creset(struct pci_slot *slot)
PHBDBG(p, "CRESET: Reinitialization\n");
p->flags &= ~PHB4_AIB_FENCED;
p->flags &= ~PHB4_CAPP_RECOVERY;
+ p->flags &= ~PHB4_CFG_USE_ASB;
phb4_init_hw(p, false);
pci_slot_set_state(slot, PHB4_SLOT_CRESET_FRESET);
return pci_slot_set_sm_timeout(slot, msecs_to_tb(100));