mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-07-16 01:03:57 -04:00
PCI/PM: Reduce D3hot delay with usleep_range()
PCIe r6.0, sec 5.9, requires a 10ms delay between programming a device to change to or from D3hot and the time the device is next accessed (unless Readiness Notifications are used). The 10ms value (PCI_PM_D3HOT_WAIT) doesn't appear directly here because some chipsets require 120ms for devices *below* them (pci_pm_d3hot_delay) and some devices require more or less than 10ms (dev->d3hot_delay). But msleep(10) typically waits about *20*ms, which is more than we need. Switch to usleep_range() to improve the delay accuracy. Based on a commit from Sajid in the Pixel 6 kernel tree [1]. On a Pixel 6, the 10ms delay for the Exynos PCIe device delayed for an average of 19ms. Switching to usleep_range() decreased the resume time by about 9ms. [1] https://android.googlesource.com/kernel/gs/+/18a8cad68d8e6d50f339a716a18295e6d987cee3 [bhelgaas commit log, add timers-howto.rst link] Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/timers/timers-howto.rst?id=v5.19#n73 Link: https://lore.kernel.org/r/20220921212735.2131588-1-willmcvicker@google.com Signed-off-by: Sajid Dalvi <sdalvi@google.com> Signed-off-by: Will McVicker <willmcvicker@google.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
This commit is contained in:
parent
4c00cba122
commit
3e347969a5
1 changed files with 8 additions and 6 deletions
|
@ -66,13 +66,15 @@ struct pci_pme_device {
|
||||||
|
|
||||||
static void pci_dev_d3_sleep(struct pci_dev *dev)
|
static void pci_dev_d3_sleep(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
unsigned int delay = dev->d3hot_delay;
|
unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
|
||||||
|
unsigned int upper;
|
||||||
|
|
||||||
if (delay < pci_pm_d3hot_delay)
|
if (delay_ms) {
|
||||||
delay = pci_pm_d3hot_delay;
|
/* Use a 20% upper bound, 1ms minimum */
|
||||||
|
upper = max(DIV_ROUND_CLOSEST(delay_ms, 5), 1U);
|
||||||
if (delay)
|
usleep_range(delay_ms * USEC_PER_MSEC,
|
||||||
msleep(delay);
|
(delay_ms + upper) * USEC_PER_MSEC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pci_reset_supported(struct pci_dev *dev)
|
bool pci_reset_supported(struct pci_dev *dev)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue