[Skiboot] [RFC PATCH 23/23] pci-slot: Make skip_perst generic

Oliver O'Halloran oohall at gmail.com
Wed Apr 3 20:09:20 AEDT 2019


Using the generic freset meant that we lose the PERST skipping
optimisation. Add it back in to the generic FRESET.

Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
 core/pci-slot.c    | 11 +++++++++--
 hw/phb3.c          | 39 ++++++++++++++++++---------------------
 hw/phb4.c          | 36 +++++++++++++++++-------------------
 include/pci-slot.h |  1 +
 4 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/core/pci-slot.c b/core/pci-slot.c
index 14dd95ec0dd1..67e62d089f6a 100644
--- a/core/pci-slot.c
+++ b/core/pci-slot.c
@@ -126,11 +126,18 @@ int64_t pci_slot_generic_freset(struct pci_slot *slot)
 	// not strictly required...
 	assert(slot->ops.prepare_link_change);
 
-	switch(slot->state) {
+again:	switch(slot->state) {
 	case PCI_SLOT_STATE_NORMAL:
 	case PCI_SLOT_FRESET_START:
-		PCIERR(phb, bdfn, "FRESET: Prepare for link down\n");
 
+		if (slot->skip_perst) {
+			PCIDBG(phb, bdfn, "FRESET: Prepare for link down\n");
+			slot->skip_perst = false;
+			pci_slot_set_state(slot, PCI_SLOT_FRESET_LIFT_PERST);
+			goto again;
+		}
+
+		PCIERR(phb, bdfn, "FRESET: Prepare for link down\n");
 		// FIXME: Handle errors
 		if (slot->ops.prepare_link_change)
 			slot->ops.prepare_link_change(slot, false);
diff --git a/hw/phb3.c b/hw/phb3.c
index d86fb74bbbf9..4618231dee3b 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -4616,27 +4616,6 @@ static void phb3_create(struct dt_node *np)
 	p->spci_xscom = ((const uint32_t *)prop->prop)[1];
 	p->pci_xscom = ((const uint32_t *)prop->prop)[2];
 
-	/*
-	 * We skip the initial PERST assertion requested by the generic code
-	 * when doing a cold boot because we are coming out of cold boot already
-	 * so we save boot time that way. The PERST state machine will still
-	 * handle waiting for the link to come up, it will just avoid actually
-	 * asserting & deasserting the PERST output
-	 *
-	 * For a hot IPL, we still do a PERST
-	 *
-	 * Note: In absence of property (ie, FSP-less), we stick to the old
-	 * behaviour and set skip_perst to true
-	 */
-	p->skip_perst = true; /* Default */
-
-	iplp = dt_find_by_path(dt_root, "ipl-params/ipl-params");
-	if (iplp) {
-		const char *ipl_type = dt_prop_get_def(iplp, "cec-major-type", NULL);
-		if (ipl_type && (!strcmp(ipl_type, "hot")))
-			p->skip_perst = false;
-	}
-
 	/* By default link is assumed down */
 	p->has_link = false;
 
@@ -4655,6 +4634,24 @@ static void phb3_create(struct dt_node *np)
 	if (!slot)
 		PHBERR(p, "Cannot create PHB slot\n");
 
+	/*
+	 * We skip the initial PERST assertion requested by the generic code
+	 * when doing a cold boot because we are coming out of cold boot already
+	 * so we save boot time that way. The PERST state machine will still
+	 * handle waiting for the link to come up, it will just avoid actually
+	 * asserting & deasserting the PERST output
+	 *
+	 * For a hot IPL, we still do a PERST
+	 *
+	 * Note: In absence of property (ie, FSP-less), we stick to the old
+	 * behaviour and set skip_perst to true
+	 */
+	slot->skip_perst = true; /* Default */
+
+	iplp = dt_find_by_path(dt_root, "ipl-params/ipl-params");
+	if (iplp && dt_has_node_property(iplp, "cec-major-type", "hot"))
+		slot->skip_perst = false;
+
 	/* Hello ! */
 	path = dt_get_path(np);
 	PHBINF(p, "Found %s @[%d:%d]\n", path, p->chip_id, p->index);
diff --git a/hw/phb4.c b/hw/phb4.c
index 99e694059a80..bf42ca76410f 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -3366,7 +3366,7 @@ static int64_t phb4_creset(struct pci_slot *slot)
 		 * have waited long enough, so we can skip it in the freset
 		 * procedure.
 		 */
-		p->skip_perst = true;
+		slot->skip_perst = true;
 		pci_slot_set_state(slot, PHB4_SLOT_NORMAL);
 		return slot->ops.freset(slot);
 	default:
@@ -5600,6 +5600,19 @@ static void phb4_create(struct dt_node *np)
 	p->pci_stk_xscom = ((const uint32_t *)prop->prop)[3];
 	p->etu_xscom = ((const uint32_t *)prop->prop)[4];
 
+	/* By default link is assumed down */
+	p->has_link = false;
+
+	/* We register the PHB before we initialize it so we
+	 * get a useful OPAL ID for it
+	 */
+	pci_register_phb(&p->phb, phb4_get_opal_id(p->chip_id, p->index));
+
+	/* Create slot structure */
+	slot = phb4_slot_create(&p->phb);
+	if (!slot)
+		PHBERR(p, "Cannot create PHB slot\n");
+
 	/*
 	 * We skip the initial PERST assertion requested by the generic code
 	 * when doing a cold boot because we are coming out of cold boot already
@@ -5612,27 +5625,12 @@ static void phb4_create(struct dt_node *np)
 	 * Note: In absence of property (ie, FSP-less), we stick to the old
 	 * behaviour and set skip_perst to true
 	 */
-	p->skip_perst = true; /* Default */
+	slot->skip_perst = true; /* Default */
 
 	iplp = dt_find_by_path(dt_root, "ipl-params/ipl-params");
-	if (iplp) {
-		const char *ipl_type = dt_prop_get_def(iplp, "cec-major-type", NULL);
-		if (ipl_type && (!strcmp(ipl_type, "hot")))
-			p->skip_perst = false;
-	}
-
-	/* By default link is assumed down */
-	p->has_link = false;
+	if (iplp && dt_has_node_property(iplp, "cec-major-type", "hot"))
+		slot->skip_perst = false;
 
-	/* We register the PHB before we initialize it so we
-	 * get a useful OPAL ID for it
-	 */
-	pci_register_phb(&p->phb, phb4_get_opal_id(p->chip_id, p->index));
-
-	/* Create slot structure */
-	slot = phb4_slot_create(&p->phb);
-	if (!slot)
-		PHBERR(p, "Cannot create PHB slot\n");
 
 	/* Hello ! */
 	path = dt_get_path(np);
diff --git a/include/pci-slot.h b/include/pci-slot.h
index 9299ffae92e8..32101db6b84a 100644
--- a/include/pci-slot.h
+++ b/include/pci-slot.h
@@ -182,6 +182,7 @@ struct pci_slot {
 	uint8_t			power_state;
 
 	/* used by the set_power_state() function */
+	bool			skip_perst;
 	uint8_t			power_ctl_state;
 
 	/* Slot information */
-- 
2.20.1



More information about the Skiboot mailing list