Skip to content

Commit aa81822

Browse files
author
Myron Stowe
committed
PCI: vmd: Set devices to D0 before enabling PM L1 Substates
JIRA: https://issues.redhat.com/browse/RHEL-47438 Upstream Status: d660410 commit d660410 Author: Jian-Hong Pan <[email protected]> Date: Tue Oct 1 16:34:38 2024 +0800 PCI: vmd: Set devices to D0 before enabling PM L1 Substates The remapped PCIe Root Port and the child device have PM L1 Substates capability, but they are disabled originally. Here is a failed example on ASUS B1400CEAE: Capabilities: [900 v1] L1 PM Substates L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1- ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+ PortCommonModeRestoreTime=32us PortTPowerOnTime=10us L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2+ ASPM_L1.1- T_CommonMode=0us LTR1.2_Threshold=101376ns L1SubCtl2: T_PwrOn=50us Enable PCI-PM L1 PM Substates for devices below VMD while they are in D0 (see PCIe r6.0, sec 5.5.4). Link: https://lore.kernel.org/r/[email protected] Link: https://bugzilla.kernel.org/show_bug.cgi?id=218394 Signed-off-by: Jian-Hong Pan <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Kuppuswamy Sathyanarayanan <[email protected]> Signed-off-by: Myron Stowe <[email protected]>
1 parent 8633a37 commit aa81822

File tree

1 file changed

+9
-4
lines changed
  • drivers/pci/controller

1 file changed

+9
-4
lines changed

drivers/pci/controller/vmd.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -740,19 +740,17 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)
740740
if (!(features & VMD_FEAT_BIOS_PM_QUIRK))
741741
return 0;
742742

743-
pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
744-
745743
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR);
746744
if (!pos)
747-
return 0;
745+
goto out_state_change;
748746

749747
/*
750748
* Skip if the max snoop LTR is non-zero, indicating BIOS has set it
751749
* so the LTR quirk is not needed.
752750
*/
753751
pci_read_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, &ltr_reg);
754752
if (!!(ltr_reg & (PCI_LTR_VALUE_MASK | PCI_LTR_SCALE_MASK)))
755-
return 0;
753+
goto out_state_change;
756754

757755
/*
758756
* Set the default values to the maximum required by the platform to
@@ -764,6 +762,13 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)
764762
pci_write_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, ltr_reg);
765763
pci_info(pdev, "VMD: Default LTR value set by driver\n");
766764

765+
out_state_change:
766+
/*
767+
* Ensure devices are in D0 before enabling PCI-PM L1 PM Substates, per
768+
* PCIe r6.0, sec 5.5.4.
769+
*/
770+
pci_set_power_state_locked(pdev, PCI_D0);
771+
pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
767772
return 0;
768773
}
769774

0 commit comments

Comments
 (0)