[Skiboot] [PATCH 1/4] hw/phb4: Skip FRESET PERST when coming from CRESET

Oliver O'Halloran oohall at gmail.com
Wed Mar 20 19:56:53 AEDT 2019


PERST is asserted at the beginning of the CRESET process to prevent
the downstream device from interacting with the host while the PHB logic
is being reset and re-initialised. There is at least a 100ms wait during
the CRESET processing so it's not necessary to wait this time again
in the FRESET handler.

This patch extends the delay after re-setting the PHB logic to extend
to the 250ms PERST wait period that we typically use and sets the
skip_perst flag so that we don't wait this time again in the FRESET
handler.

Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
NB: In boot we jump directly into the FRESET_START state and skip CRESET
entirely so this patch should not affect boot time at all. It might make
fast-reset slightly faster.
---
 hw/phb4.c      | 24 +++++++++++++++++++++++-
 include/phb4.h |  1 +
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hw/phb4.c b/hw/phb4.c
index e103ee5fd93b..4f15b2b9a4b4 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2569,6 +2569,7 @@ static void phb4_lane_eq_change(struct phb4 *p, uint32_t vdid)
 }
 
 #define min(x,y) ((x) < (y) ? x : y)
+#define max(x,y) ((x) < (y) ? x : y)
 
 static bool phb4_link_optimal(struct pci_slot *slot, uint32_t *vdid)
 {
@@ -3222,6 +3223,7 @@ static int64_t phb4_creset(struct pci_slot *slot)
 	struct phb4 *p = phb_to_phb4(slot->phb);
 	struct capp *capp = p->capp;
 	uint64_t pbcq_status, reg;
+	uint64_t creset_time, wait_time;
 
 	/* Don't even try fixing a broken PHB */
 	if (p->broken)
@@ -3232,6 +3234,8 @@ static int64_t phb4_creset(struct pci_slot *slot)
 	case PHB4_SLOT_CRESET_START:
 		PHBDBG(p, "CRESET: Starts\n");
 
+		p->creset_start_time = mftb();
+
 		phb4_prepare_link_change(slot, false);
 		/* Clear error inject register, preventing recursive errors */
 		xscom_write(p->chip_id, p->pe_xscom + 0x2, 0x0);
@@ -3337,8 +3341,26 @@ static int64_t phb4_creset(struct pci_slot *slot)
 		p->flags &= ~PHB4_CFG_USE_ASB;
 		phb4_init_hw(p);
 		pci_slot_set_state(slot, PHB4_SLOT_CRESET_FRESET);
-		return pci_slot_set_sm_timeout(slot, msecs_to_tb(100));
+
+		/*
+		 * wait either 100ms (for the ETU logic) or until we've had
+		 * PERST asserted for 250ms.
+		 */
+		creset_time = tb_to_msecs(mftb() - p->creset_start_time);
+		if (creset_time < 250)
+			wait_time = max(100, 250 - creset_time);
+		else
+			wait_time = 100;
+		PHBDBG(p, "CRESET: wait_time = %lld\n", wait_time);
+		return pci_slot_set_sm_timeout(slot, msecs_to_tb(wait_time));
+
 	case PHB4_SLOT_CRESET_FRESET:
+		/*
+		 * We asserted PERST at the beginning of the CRESET and we
+		 * have waited long enough, so we can skip it in the freset
+		 * procedure.
+		 */
+		p->skip_perst = true;
 		pci_slot_set_state(slot, PHB4_SLOT_NORMAL);
 		return slot->ops.freset(slot);
 	default:
diff --git a/include/phb4.h b/include/phb4.h
index adf458094349..605effecfba1 100644
--- a/include/phb4.h
+++ b/include/phb4.h
@@ -195,6 +195,7 @@ struct phb4 {
 	uint32_t		num_pes;
 	uint32_t		max_num_pes;
 	uint32_t		num_irqs;
+	uint64_t		creset_start_time;
 
 	/* SkiBoot owned in-memory tables */
 	uint16_t		*tbl_rtt;
-- 
2.20.1



More information about the Skiboot mailing list