Revert "PCI/PM: Assume ports without DLL Link Active train links in 100 ms"
This reverts commitec411e02b7
. Patrick reported that this commit broke hybrid graphics on a ThinkPad X1 Extreme 2nd with Intel UHD Graphics 630 and NVIDIA GeForce GTX 1650 Mobile: nouveau 0000:01:00.0: fifo: PBDMA0: 01000000 [] ch 0 [00ff992000 DRM] subc 0 mthd 0008 data 00000000 Karol reported that this commit broke Nouveau firmware loading on a Lenovo P1G2 with Intel UHD Graphics 630 and NVIDIA TU117GLM [Quadro T1000 Mobile]: nouveau 0000:01:00.0: acr: AHESASC binary failed In both cases, revertingec411e02b7
solved the problem. Unfortunately, this revert will reintroduce the "Thunderbolt bridges take long time to resume from D3cold" problem: https://bugzilla.kernel.org/show_bug.cgi?id=206837 Link: https://lore.kernel.org/r/CAErSpo5sTeK_my1dEhWp7aHD0xOp87+oHYWkTjbL7ALgDbXo-Q@mail.gmail.com Link: https://lore.kernel.org/r/CACO55tsAEa5GXw5oeJPG=mcn+qxNvspXreJYWDJGZBy5v82JDA@mail.gmail.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=208597 Reported-by: Patrick Volkerding <volkerdi@gmail.com> Reported-by: Karol Herbst <kherbst@redhat.com> Fixes:ec411e02b7
("PCI/PM: Assume ports without DLL Link Active train links in 100 ms") Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
62ca18a089
commit
d08c30d7a0
|
@ -4638,8 +4638,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
|
|||
* pcie_wait_for_link_delay - Wait until link is active or inactive
|
||||
* @pdev: Bridge device
|
||||
* @active: waiting for active or inactive?
|
||||
* @delay: Delay to wait after link has become active (in ms). Specify %0
|
||||
* for no delay.
|
||||
* @delay: Delay to wait after link has become active (in ms)
|
||||
*
|
||||
* Use this to wait till link becomes active or inactive.
|
||||
*/
|
||||
|
@ -4680,7 +4679,7 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
|
|||
msleep(10);
|
||||
timeout -= 10;
|
||||
}
|
||||
if (active && ret && delay)
|
||||
if (active && ret)
|
||||
msleep(delay);
|
||||
else if (ret != active)
|
||||
pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
|
||||
|
@ -4801,28 +4800,17 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)
|
|||
if (!pcie_downstream_port(dev))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Per PCIe r5.0, sec 6.6.1, for downstream ports that support
|
||||
* speeds > 5 GT/s, we must wait for link training to complete
|
||||
* before the mandatory delay.
|
||||
*
|
||||
* We can only tell when link training completes via DLL Link
|
||||
* Active, which is required for downstream ports that support
|
||||
* speeds > 5 GT/s (sec 7.5.3.6). Unfortunately some common
|
||||
* devices do not implement Link Active reporting even when it's
|
||||
* required, so we'll check for that directly instead of checking
|
||||
* the supported link speed. We assume devices without Link Active
|
||||
* reporting can train in 100 ms regardless of speed.
|
||||
*/
|
||||
if (dev->link_active_reporting) {
|
||||
pci_dbg(dev, "waiting for link to train\n");
|
||||
if (!pcie_wait_for_link_delay(dev, true, 0)) {
|
||||
if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
|
||||
pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
|
||||
msleep(delay);
|
||||
} else {
|
||||
pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
|
||||
delay);
|
||||
if (!pcie_wait_for_link_delay(dev, true, delay)) {
|
||||
/* Did not train, no need to wait any further */
|
||||
return;
|
||||
}
|
||||
}
|
||||
pci_dbg(child, "waiting %d ms to become accessible\n", delay);
|
||||
msleep(delay);
|
||||
|
||||
if (!pci_device_is_present(child)) {
|
||||
pci_dbg(child, "waiting additional %d ms to become accessible\n", delay);
|
||||
|
|
Loading…
Reference in New Issue