diff mbox series

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

Message ID 20190320085656.32078-1-oohall@gmail.com
State Accepted
Headers show
Series [1/4] hw/phb4: Skip FRESET PERST when coming from CRESET | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (b392d785eb49630b9f00fef8d17944ed82b2c1fe)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Oliver O'Halloran March 20, 2019, 8:56 a.m. UTC
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@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(-)

Comments

Stewart Smith March 29, 2019, 5:02 a.m. UTC | #1
"Oliver O'Halloran" <oohall@gmail.com> writes:
> 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@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.

Series merged to master as of 722cf1c2ed56907fd9cc64c3f406f998d7e44992
and I hope (with fix discussed on internal Slack), that we're all okay
(I couldn't really recreate that EEH it turns out, but the fix *seemed*
to make sense... so I'm only *slightly* YOLOing it?)
diff mbox series

Patch

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;