aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/pci.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/core/pci.c b/core/pci.c
index ecb94c2..6864e6f 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -360,12 +360,19 @@ static bool pci_enable_bridge(struct phb *phb, struct pci_device *pd)
uint16_t bctl;
bool was_reset = false;
int64_t ecap = 0;
+ uint32_t lcap = 0;
+ uint16_t lstat;
/* Disable master aborts, clear errors */
pci_cfg_read16(phb, pd->bdfn, PCI_CFG_BRCTL, &bctl);
bctl &= ~PCI_CFG_BRCTL_MABORT_REPORT;
pci_cfg_write16(phb, pd->bdfn, PCI_CFG_BRCTL, bctl);
+ if (pci_has_cap(pd, PCI_CFG_CAP_ID_EXP, false)) {
+ ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
+ pci_cfg_read32(phb, pd->bdfn, ecap+PCICAP_EXP_LCAP, &lcap);
+ }
+
/* PCI-E bridge, check the slot state. We don't do that on the
* root complex as this is handled separately and not all our
* RCs implement the standard register set.
@@ -374,7 +381,21 @@ static bool pci_enable_bridge(struct phb *phb, struct pci_device *pd)
pd->dev_type == PCIE_TYPE_SWITCH_DNPORT) {
uint16_t slctl, slcap, slsta, lctl;
- ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
+ /*
+ * No need to touch the power supply if the PCIe link has
+ * been up. Further more, the slot presence bit is lost while
+ * the PCIe link is up on the specific PCI topology. In that
+ * case, we need ignore the slot presence bit and go ahead for
+ * probing. Otherwise, the NVMe adapter won't be probed.
+ *
+ * PHB3 root port, PLX switch 8748 (10b5:8748), PLX swich 9733
+ * (10b5:9733), PMC 8546 swtich (11f8:8546), NVMe adapter
+ * (1c58:0023).
+ */
+ pci_cfg_read16(phb, pd->bdfn, ecap+PCICAP_EXP_LSTAT, &lstat);
+ if ((lcap & PCICAP_EXP_LCAP_DL_ACT_REP) &&
+ (lstat & PCICAP_EXP_LSTAT_DLLL_ACT))
+ return true;
/* Read the slot status & check for presence detect */
pci_cfg_read16(phb, pd->bdfn, ecap+PCICAP_EXP_SLOTSTAT, &slsta);
@@ -430,11 +451,6 @@ static bool pci_enable_bridge(struct phb *phb, struct pci_device *pd)
/* PCI-E bridge, wait for link */
if (pd->dev_type == PCIE_TYPE_ROOT_PORT ||
pd->dev_type == PCIE_TYPE_SWITCH_DNPORT) {
- uint32_t lcap;
-
- /* Read link caps */
- pci_cfg_read32(phb, pd->bdfn, ecap+PCICAP_EXP_LCAP, &lcap);
-
/* Did link capability say we got reporting ?
*
* If yes, wait up to 10s, if not, wait 1s if we didn't already