Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/20045
Change subject: sb/intel/bd82x6x/pcie: Add PCIe reset timeout ......................................................................
sb/intel/bd82x6x/pcie: Add PCIe reset timeout
If no device is found, make sure to wait 100msec and scan bridge again.
May introduce a boot delay of up to 100msec. As timestamps are used the delay is at maximum 100msec, no matter how many PCIe ports are there. The delay is only used in case no device is found. If a device has been found there's no need to wait.
Fixes a regression introduced by Change-Id: I6ee5e5f33824acdbca0f6ed28e90beab7fe10002 where a port is disabled as the connected device hasn't powered up yet.
Tested on Lenovo T430.
Change-Id: I990e2577f0acf7d1956b42af2611405f1421e6d3 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M src/southbridge/intel/bd82x6x/pcie.c 1 file changed, 24 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/45/20045/1
diff --git a/src/southbridge/intel/bd82x6x/pcie.c b/src/southbridge/intel/bd82x6x/pcie.c index 627b6f7..939890b 100644 --- a/src/southbridge/intel/bd82x6x/pcie.c +++ b/src/southbridge/intel/bd82x6x/pcie.c @@ -20,7 +20,12 @@ #include <device/pciexp.h> #include <device/pci_ids.h> #include <southbridge/intel/common/pciehp.h> +#include <timestamp.h> +#include <delay.h> #include "pch.h" + +static uint64_t ts_pcie_init = 0; +#define PCIE_RESET_DELAY 100000ULL
static void pch_pcie_pm_early(struct device *dev) { @@ -267,6 +272,8 @@ { /* Power Management init before enumeration */ pch_pcie_pm_early(dev); + /* Store time-stamp for PCIe reset timeout */ + ts_pcie_init = MAX(timestamp_get(), ts_pcie_init); }
static void pch_pcie_disable(device_t dev) @@ -279,11 +286,28 @@
static void pch_pciexp_scan_bridge(device_t dev) { + uint64_t delay; struct southbridge_intel_bd82x6x_config *config = dev->chip_info;
/* Normal PCIe Scan */ pciexp_scan_bridge(dev);
+ /* + * No device found ? + * Respect PCIe 1.0 Spec and wait at least 100msec after reset. + */ + delay = (timestamp_get() - ts_pcie_init) / timestamp_tick_freq_mhz(); + if (!dev_is_active_bridge(dev) && (delay < PCIE_RESET_DELAY)) { + delay = PCIE_RESET_DELAY - delay; + printk(BIOS_DEBUG, "%s: Waiting additional %lld usec\n", + dev_path(dev), delay); + + udelay(delay); + + /* Scan again */ + pciexp_scan_bridge(dev); + } + if (config->pcie_hotplug_map[PCI_FUNC(dev->path.pci.devfn)]) { intel_acpi_pcie_hotplug_scan_slot(dev->link_list); } else {