summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2019-03-20 19:56:53 +1100
committerStewart Smith <stewart@linux.ibm.com>2019-03-28 15:24:13 +1100
commit70edcbb4b39d5d90fd487f6f8c6dd459e36935bc (patch)
tree8ed102f580f903efe5ce66ec2257a8cb9372d0ad
parent6225d11924933f0541fd3b1a6192a7fcda279f1f (diff)
downloadblackbird-skiboot-70edcbb4b39d5d90fd487f6f8c6dd459e36935bc.tar.gz
blackbird-skiboot-70edcbb4b39d5d90fd487f6f8c6dd459e36935bc.zip
hw/phb4: Skip FRESET PERST when coming from CRESET
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> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--hw/phb4.c24
-rw-r--r--include/phb4.h1
2 files changed, 24 insertions, 1 deletions
diff --git a/hw/phb4.c b/hw/phb4.c
index 8af3d34f..edf54440 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 adf45809..605effec 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;
OpenPOWER on IntegriCloud