diff options
author | David E. Box <david.e.box@linux.intel.com> | 2020-12-07 14:39:51 -0800 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2020-12-10 14:45:14 -0600 |
commit | a697f072f5da8d75467be81bec918eb479405615 (patch) | |
tree | 690494dc037a0f82fc5a56cadc763482714dd48e /drivers/pci/pci.c | |
parent | 39850ed51062f89cd46214a16aaafba5ca49fd6c (diff) |
PCI: Disable PTM during suspend to save power
There are systems (for example, Intel based mobile platforms since Coffee
Lake) where the power drawn while suspended can be significantly reduced by
disabling Precision Time Measurement (PTM) on PCIe root ports as this
allows the port to enter a lower-power PM state and the SoC to reach a
lower-power idle state. To save this power, disable the PTM feature on root
ports during pci_prepare_to_sleep() and pci_finish_runtime_suspend(). The
feature will be returned to its previous state during restore and error
recovery.
Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=209361
Link: https://lore.kernel.org/r/20201207223951.19667-2-david.e.box@linux.intel.com
Reported-by: Len Brown <len.brown@intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 12ba6351c05b..71dd5d7cbded 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2608,12 +2608,24 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; + /* + * There are systems (for example, Intel mobile chips since Coffee + * Lake) where the power drawn while suspended can be significantly + * reduced by disabling PTM on PCIe root ports as this allows the + * port to enter a lower-power PM state and the SoC to reach a + * lower-power idle state as a whole. + */ + if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) + pci_disable_ptm(dev); + pci_enable_wake(dev, target_state, wakeup); error = pci_set_power_state(dev, target_state); - if (error) + if (error) { pci_enable_wake(dev, target_state, false); + pci_restore_ptm_state(dev); + } return error; } @@ -2651,12 +2663,23 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) dev->runtime_d3cold = target_state == PCI_D3cold; + /* + * There are systems (for example, Intel mobile chips since Coffee + * Lake) where the power drawn while suspended can be significantly + * reduced by disabling PTM on PCIe root ports as this allows the + * port to enter a lower-power PM state and the SoC to reach a + * lower-power idle state as a whole. + */ + if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) + pci_disable_ptm(dev); + __pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); error = pci_set_power_state(dev, target_state); if (error) { pci_enable_wake(dev, target_state, false); + pci_restore_ptm_state(dev); dev->runtime_d3cold = false; } |