diff mbox series

[2/3] hw/phb4: Set trace enable where it's used

Message ID 20190530032056.26355-2-oohall@gmail.com
State Accepted
Headers show
Series [1/3] hw/phb4: Add missing LTSSM states | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (76f7316bc8fc8a18fdbfcbc0e1fe1bb992d2a7d7)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot fail 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 May 30, 2019, 3:20 a.m. UTC
The current LTSSM state was added to the PHB4 link trace output in
961547bceed3 ("phb4: Enhanced PCIe training tracing"). That patch
split enabling the LTSSM state output from the rest of the tracing code
in phb4_training_trace() to ensure that it would capture events from
right after PERST is lifted.

This is not really necessary since LTSSM state changes occur over
milliseconds. We lose nothing by delaying the enable slightly so
this patch moves it into phb4_training_trace() to keep the tracing
code in one place.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 hw/phb4.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/hw/phb4.c b/hw/phb4.c
index cbe6b668f146..0c549e18f664 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2658,11 +2658,21 @@  static bool phb4_link_optimal(struct pci_slot *slot, uint32_t *vdid)
  */
 static void phb4_training_trace(struct phb4 *p)
 {
-	uint64_t reg, reglast = -1;
+	uint64_t trwctl, reg, reglast = -1;
 	unsigned long now, start = mftb();
+	bool enabled;
+
+	/*
+	 * Enable the DLP trace outputs. If we don't the LTSSM state in
+	 * PHB_PCIE_DLP_TRAIN_CTL won't be updated and always reads zero.
+	 */
+	trwctl = phb4_read_reg(p, PHB_PCIE_DLP_TRWCTL);
+	enabled = !!(trwctl & PHB_PCIE_DLP_TRWCTL_EN);
+	if (!enabled) {
+		phb4_write_reg(p, PHB_PCIE_DLP_TRWCTL,
+				trwctl | PHB_PCIE_DLP_TRWCTL_EN);
+	}
 
-	if (!pci_tracing)
-		return;
 
 	while(1) {
 		now = mftb();
@@ -2684,6 +2694,13 @@  static void phb4_training_trace(struct phb4 *p)
 			break;
 		}
 	}
+
+	/*
+	 * The trace enable bit is a clock gate for the tracing logic. Turn
+	 * it off to save power if we're not using it otherwise.
+	 */
+	if (!enabled)
+		phb4_write_reg(p, PHB_PCIE_DLP_TRWCTL, trwctl);
 }
 
 /*
@@ -2976,7 +2993,6 @@  static int64_t phb4_hreset(struct pci_slot *slot)
 static int64_t phb4_freset(struct pci_slot *slot)
 {
 	struct phb4 *p = phb_to_phb4(slot->phb);
-	uint64_t reg;
 
 	switch(slot->state) {
 	case PHB4_SLOT_NORMAL:
@@ -3007,17 +3023,11 @@  static int64_t phb4_freset(struct pci_slot *slot)
 		/* Clear link errors before we deassert PERST */
 		phb4_err_clear_regb(p);
 
-		if (pci_tracing) {
-			/* Enable tracing */
-			reg = in_be64(p->regs + PHB_PCIE_DLP_TRWCTL);
-			out_be64(p->regs + PHB_PCIE_DLP_TRWCTL,
-				 reg | PHB_PCIE_DLP_TRWCTL_EN);
-		}
-
 		PHBDBG(p, "FRESET: Deassert\n");
 		phb4_assert_perst(slot, false);
 
-		phb4_training_trace(p);
+		if (pci_tracing)
+			phb4_training_trace(p)
 
 		pci_slot_set_state(slot, PHB4_SLOT_LINK_START);
 		return slot->ops.poll_link(slot);