[Skiboot] [PATCH 7/9] phb4: Fix PHB4 fence recovery
Benjamin Herrenschmidt
benh at kernel.crashing.org
Sat Jul 8 07:08:44 AEST 2017
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 at kernel.crashing.org>
---
hw/phb4.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/hw/phb4.c b/hw/phb4.c
index 1612652..7d4f30c 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -1853,9 +1853,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);
@@ -2409,19 +2406,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;
@@ -2437,8 +2437,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));
@@ -2454,6 +2460,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));
--
2.9.4
More information about the Skiboot
mailing list