[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