aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorDavid E. Box <david.e.box@linux.intel.com>2020-12-07 14:39:51 -0800
committerBjorn Helgaas <bhelgaas@google.com>2020-12-10 14:45:14 -0600
commita697f072f5da8d75467be81bec918eb479405615 (patch)
tree690494dc037a0f82fc5a56cadc763482714dd48e /drivers/pci/pcie
parentPCI/PTM: Save/restore Precision Time Measurement Capability for suspend/resume (diff)
downloadlinux-dev-a697f072f5da8d75467be81bec918eb479405615.tar.xz
linux-dev-a697f072f5da8d75467be81bec918eb479405615.zip
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/pcie')
-rw-r--r--drivers/pci/pcie/ptm.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
index 6b24a1c9327a..95d4eef2c9e8 100644
--- a/drivers/pci/pcie/ptm.c
+++ b/drivers/pci/pcie/ptm.c
@@ -29,6 +29,23 @@ static void pci_ptm_info(struct pci_dev *dev)
dev->ptm_root ? " (root)" : "", clock_desc);
}
+void pci_disable_ptm(struct pci_dev *dev)
+{
+ int ptm;
+ u16 ctrl;
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM);
+ if (!ptm)
+ return;
+
+ pci_read_config_word(dev, ptm + PCI_PTM_CTRL, &ctrl);
+ ctrl &= ~(PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT);
+ pci_write_config_word(dev, ptm + PCI_PTM_CTRL, ctrl);
+}
+
void pci_save_ptm_state(struct pci_dev *dev)
{
int ptm;