From 18cb1340f185150b9708257ba8024b6900706083 Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Wed, 1 Oct 2014 11:13:54 +0800 Subject: device/pciexp: Add support for PCIe CLK power management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-on: https://chromium-review.googlesource.com/220742 Reviewed-by: Duncan Laurie [Edit commit message.] Signed-off-by: Paul Menzel Reviewed-on: http://review.coreboot.org/8447 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki Reviewed-by: Stefan Reinauer --- src/device/Kconfig | 8 ++++++++ src/device/pciexp_device.c | 22 ++++++++++++++++++++++ src/include/device/pci_def.h | 2 ++ 3 files changed, 32 insertions(+) (limited to 'src') diff --git a/src/device/Kconfig b/src/device/Kconfig index 91da02a193..42a68d296a 100644 --- a/src/device/Kconfig +++ b/src/device/Kconfig @@ -251,6 +251,14 @@ config PCIEXP_ASPM 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 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); diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h index 00d68ad5dc..403978584d 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 */ -- cgit v1.2.3