aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-08-27 22:57:45 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-29 06:04:00 +1000
commite4048499b915a0a53b2702dec14461c3f5914d67 (patch)
tree14ba6294f8c0f911bac9d23ac87cac9a40126fbe
parent434073649f932b6b4b6f240006a48e24205f5a11 (diff)
downloadskiboot-e4048499b915a0a53b2702dec14461c3f5914d67.zip
skiboot-e4048499b915a0a53b2702dec14461c3f5914d67.tar.gz
skiboot-e4048499b915a0a53b2702dec14461c3f5914d67.tar.bz2
PCI: Disable completion timeout
For PCIe devices, there are 2 bits used to control completion timeout as follows: PCIe Cap + 0x24, Device Capabilities 2 Register, bit#4 PCIe Cap + 0x28, Device Control 2 Register, bit#4 The patch adds function pci_disable_completion_timeout(), which is called during bootup or after PE reset. It's responsing to bug#114961 Suggested-by: Michael A. Perez <perezma@us.ibm.com> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--core/pci.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/core/pci.c b/core/pci.c
index 33a0fd7..7447314 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -605,9 +605,31 @@ static int pci_configure_mps(struct phb *phb,
return 0;
}
+static void pci_disable_completion_timeout(struct phb *phb, struct pci_device *pd)
+{
+ uint32_t ecap;
+ uint32_t val;
+
+ /* PCIE capability required */
+ if (!pci_has_cap(pd, PCI_CFG_CAP_ID_EXP, false))
+ return;
+
+ /* Check if it has capability to disable completion timeout */
+ ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
+ pci_cfg_read32(phb, pd->bdfn, ecap + PCIECAP_EXP_DCAP2, &val);
+ if (!(val & PCICAP_EXP_DCAP2_CMPTOUT_DIS))
+ return;
+
+ /* Disable completion timeout without more check */
+ pci_cfg_read32(phb, pd->bdfn, ecap + PCICAP_EXP_DCTL2, &val);
+ val |= PCICAP_EXP_DCTL2_CMPTOUT_DIS;
+ pci_cfg_write32(phb, pd->bdfn, ecap + PCICAP_EXP_DCTL2, val);
+}
+
void pci_device_init(struct phb *phb, struct pci_device *pd)
{
pci_configure_mps(phb, pd, NULL);
+ pci_disable_completion_timeout(phb, pd);
}
/*