device/pciexp: Add support for PCIe CLK power management
Set PCIe "Enable Clock Power Management", if endpoint supports it.
BUG=chrome-os-partner:31424
BRANCH=none
TEST=build and boot on rambi, check Enable Clock Power Management
in link control register is set properly
Change-Id: Ie54110d1ef42184cfcf47c9fe4d735960aebe47f
Signed-off-by: Kane Chen <kane.chen@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/220742
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
[Edit commit message.]
Signed-off-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-on: http://review.coreboot.org/8447
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/src/device/Kconfig b/src/device/Kconfig
index 91da02a..42a68d2 100644
--- a/src/device/Kconfig
+++ b/src/device/Kconfig
@@ -251,6 +251,14 @@
help
Detect and enable ASPM on PCIe links.
+config PCIEXP_CLK_PM
+ prompt "Enable PCIe Clock Power Management"
+ bool
+ depends on PCIEXP_PLUGIN_SUPPORT
+ default n
+ help
+ Detect and enable Clock Power Management on PCIe.
+
config PCI_BUS_SEGN_BITS
int
default 0
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c
index 87aea67..edb103d 100644
--- a/src/device/pciexp_device.c
+++ b/src/device/pciexp_device.c
@@ -90,6 +90,23 @@
}
#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 @@
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);
diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h
index 00d68ad..4039785 100644
--- a/src/include/device/pci_def.h
+++ b/src/include/device/pci_def.h
@@ -375,9 +375,11 @@
#define PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */
#define PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */
#define PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */
+#define PCI_EXP_CLK_PM 0x40000 /* Clock Power Management */
#define PCI_EXP_LNKCTL 16 /* Link Control */
#define PCI_EXP_LNKCTL_RL 0x20 /* Retrain Link */
#define PCI_EXP_LNKCTL_CCC 0x40 /* Common Clock COnfiguration */
+#define PCI_EXP_EN_CLK_PM 0x100 /* Enable Clock Power Management */
#define PCI_EXP_LNKSTA 18 /* Link Status */
#define PCI_EXP_LNKSTA_LT 0x800 /* Link Training */
#define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */