Furquan Shaikh has uploaded a new change for review. ( https://review.coreboot.org/19925 )
Change subject: soc/intel/skylake: Add detailed information about PME wake sources ......................................................................
soc/intel/skylake: Add detailed information about PME wake sources
Add more fine-grained details about what device caused the PME wake event. This requires checking the PME status bit (bit 15) in PCI PM control and status register for the PCI device.
BUG=b:37088992 TEST=Verifed that XHCI wake source was identified correctly: 135 | 2017-05-25 15:28:17 | ACPI Enter | S3 136 | 2017-05-25 15:28:26 | ACPI Wake | S3 137 | 2017-05-25 15:28:26 | Wake Source | PME - XHCI | 0
Change-Id: I6fc6284cd04db311f1f86b8a86d0bb708392e5d5 Signed-off-by: Furquan Shaikh furquan@chromium.org --- M src/soc/intel/skylake/elog.c 1 file changed, 58 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/25/19925/1
diff --git a/src/soc/intel/skylake/elog.c b/src/soc/intel/skylake/elog.c index 6db15f5..213b81a 100644 --- a/src/soc/intel/skylake/elog.c +++ b/src/soc/intel/skylake/elog.c @@ -17,8 +17,10 @@ #include <bootstate.h> #include <cbmem.h> #include <console/console.h> +#include <device/pci_ops.h> #include <stdint.h> #include <elog.h> +#include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/smbus.h>
@@ -32,6 +34,61 @@ if (gpe0_sts & (1 << i)) elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start); } +} + +struct pme_status_info { + device_t dev; + uint8_t reg_offset; + uint32_t elog_event; +}; + +#define PME_STS_BIT (1 << 15) + +static void pch_log_pme_internal_wake_source(void) +{ + size_t i; + device_t dev; + uint16_t val; + bool dev_found = false; + + struct pme_status_info pme_status_info[] = { + {PCH_DEV_HDA, 0x54, ELOG_WAKE_SOURCE_PME_HDA}, + {PCH_DEV_GBE, 0xcc, ELOG_WAKE_SOURCE_PME_GBE}, + {PCH_DEV_EMMC, 0x84, ELOG_WAKE_SOURCE_PME_EMMC}, + {PCH_DEV_SDCARD, 0x84, ELOG_WAKE_SOURCE_PME_SDCARD}, + {PCH_DEV_PCIE1, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE1}, + {PCH_DEV_PCIE2, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE2}, + {PCH_DEV_PCIE3, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE3}, + {PCH_DEV_PCIE4, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE4}, + {PCH_DEV_PCIE5, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE5}, + {PCH_DEV_PCIE6, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE6}, + {PCH_DEV_PCIE7, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE7}, + {PCH_DEV_PCIE8, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE8}, + {PCH_DEV_PCIE9, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE9}, + {PCH_DEV_PCIE10, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE10}, + {PCH_DEV_PCIE11, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE11}, + {PCH_DEV_PCIE12, 0xa4, ELOG_WAKE_SOURCE_PME_PCIE12}, + {PCH_DEV_SATA, 0x74, ELOG_WAKE_SOURCE_PME_SATA}, + {PCH_DEV_CSE, 0x54, ELOG_WAKE_SOURCE_PME_CSE}, + {PCH_DEV_CSE_2, 0x54, ELOG_WAKE_SOURCE_PME_CSE2}, + {PCH_DEV_CSE_3, 0x54, ELOG_WAKE_SOURCE_PME_CSE3}, + {PCH_DEV_XHCI, 0x74, ELOG_WAKE_SOURCE_PME_XHCI}, + {PCH_DEV_USBOTG, 0x84, ELOG_WAKE_SOURCE_PME_XDCI}, + }; + + for (i = 0; i < ARRAY_SIZE(pme_status_info); i++) { + dev = pme_status_info[i].dev; + val = pci_read_config16(dev, pme_status_info[i].reg_offset); + + if ((val == 0xFFFF) || !(val & PME_STS_BIT)) + continue; + + elog_add_event_wake(pme_status_info[i].elog_event, 0); + dev_found = true; + } + + if (!dev_found) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); }
static void pch_log_wake_source(struct chipset_power_state *ps) @@ -54,7 +111,7 @@
/* Internal PME (TODO: determine wake device) */ if (ps->gpe0_sts[GPE_STD] & PME_B0_STS) - elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); + pch_log_pme_internal_wake_source();
/* SMBUS Wake */ if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)