aboutsummaryrefslogtreecommitdiff
path: root/src/device/pciexp_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/device/pciexp_device.c')
-rw-r--r--src/device/pciexp_device.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c
index 87aea672db..edb103d861 100644
--- a/src/device/pciexp_device.c
+++ b/src/device/pciexp_device.c
@@ -90,6 +90,23 @@ static void pciexp_enable_common_clock(device_t root, unsigned root_cap,
}
#endif /* CONFIG_PCIEXP_COMMON_CLOCK */
+#if CONFIG_PCIEXP_CLK_PM
+static void pciexp_enable_clock_power_pm(device_t endp, unsigned endp_cap)
+{
+ /* check if per port clk req is supported in device */
+ u32 endp_ca;
+ u16 lnkctl;
+ endp_ca = pci_read_config32(endp, endp_cap + PCI_EXP_LNKCAP);
+ if ((endp_ca & PCI_EXP_CLK_PM) == 0) {
+ printk(BIOS_INFO, "PCIE CLK PM is not supported by endpoint");
+ return;
+ }
+ lnkctl = pci_read_config16(endp, endp_cap + PCI_EXP_LNKCTL);
+ lnkctl = lnkctl | PCI_EXP_EN_CLK_PM;
+ pci_write_config16(endp, endp_cap + PCI_EXP_LNKCTL, lnkctl);
+}
+#endif /* CONFIG_PCIEXP_CLK_PM */
+
#if CONFIG_PCIEXP_ASPM
/*
* Determine the ASPM L0s or L1 exit latency for a link
@@ -200,6 +217,11 @@ static void pciexp_tune_dev(device_t dev)
pciexp_enable_common_clock(root, root_cap, dev, cap);
#endif
+#if CONFIG_PCIEXP_CLK_PM
+ /* Check if per port CLK req is supported by endpoint*/
+ pciexp_enable_clock_power_pm(dev, cap);
+#endif
+
#if CONFIG_PCIEXP_ASPM
/* Check for and enable ASPM */
enum aspm_type apmc = pciexp_enable_aspm(root, root_cap, dev, cap);