diff --git a/src/soc/intel/broadwell/elog.c b/src/soc/intel/broadwell/elog.c index dfb9bbb1a7..a6a2813728 100644 --- a/src/soc/intel/broadwell/elog.c +++ b/src/soc/intel/broadwell/elog.c @@ -17,171 +17,122 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include +#include #include -#include -#include -#include #include -#include #include -#include "pch.h" +#include +#include -static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg) +static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start) { - u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg); - u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en; - - /* PME (TODO: determine wake device) */ - if (gpe0_sts & (1 << 11)) - elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0); - - /* Internal PME (TODO: determine wake device) */ - if (gpe0_sts & (1 << 13)) - elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); - - /* SMBUS Wake */ - if (gpe0_sts & (1 << 7)) - elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0); -} - -static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start) -{ - /* GPE Bank 1 is GPIO 0-31 */ - u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg); - u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en; int i; + gpe0_sts &= gpe0_en; + for (i = 0; i <= 31; i++) { if (gpe0_sts & (1 << i)) elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start); } } -static void pch_log_gpe(void) +static void pch_log_wake_source(struct chipset_power_state *ps) { - int i; - u16 pmbase = get_pmbase(); - u32 gpe0_sts, gpe0_en; - int gpe0_high_gpios[] = { - [0] = 27, - [24] = 17, - [25] = 19, - [26] = 21, - [27] = 22, - [28] = 43, - [29] = 56, - [30] = 57, - [31] = 60 - }; - - pch_log_standard_gpe(GPE0_EN, GPE0_STS); - - /* GPIO 0-15 */ - gpe0_en = inw(pmbase + GPE0_EN + 2); - gpe0_sts = inw(pmbase + GPE0_STS + 2) & gpe0_en; - for (i = 0; i <= 15; i++) { - if (gpe0_sts & (1 << i)) - elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i); - } - - /* - * Now check and log upper status bits - */ - - gpe0_en = inl(pmbase + GPE0_EN_2); - gpe0_sts = inl(pmbase + GPE0_STS_2) & gpe0_en; - - for (i = 0; i <= 31; i++) { - if (!gpe0_high_gpios[i]) - continue; - if (gpe0_sts & (1 << i)) - elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, - gpe0_high_gpios[i]); - } -} - -static void pch_lp_log_gpe(void) -{ - /* Standard GPE are in GPE set 4 */ - pch_log_standard_gpe(LP_GPE0_STS_4, LP_GPE0_EN_4); - - /* Log GPIO events in set 1-3 */ - pch_log_gpio_gpe(LP_GPE0_STS_1, LP_GPE0_EN_1, 0); - pch_log_gpio_gpe(LP_GPE0_STS_2, LP_GPE0_EN_2, 32); - pch_log_gpio_gpe(LP_GPE0_STS_3, LP_GPE0_EN_3, 64); -} - -void pch_log_state(void) -{ - u16 pm1_sts, gen_pmcon_3, tco2_sts; - u8 gen_pmcon_2; - struct device *lpc = dev_find_slot(0, PCI_DEVFN(0x1f, 0)); - if (!lpc) - return; - - pm1_sts = inw(get_pmbase() + PM1_STS); - tco2_sts = inw(get_pmbase() + TCO2_STS); - gen_pmcon_2 = pci_read_config8(lpc, GEN_PMCON_2); - gen_pmcon_3 = pci_read_config16(lpc, GEN_PMCON_3); - - /* PWR_FLR Power Failure */ - if (gen_pmcon_2 & (1 << 0)) - elog_add_event(ELOG_TYPE_POWER_FAIL); - - /* SUS Well Power Failure */ - if (gen_pmcon_3 & (1 << 14)) - elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); - - /* SYS_PWROK Failure */ - if (gen_pmcon_2 & (1 << 1)) - elog_add_event(ELOG_TYPE_SYS_PWROK_FAIL); - - /* PWROK Failure */ - if (gen_pmcon_2 & (1 << 0)) - elog_add_event(ELOG_TYPE_PWROK_FAIL); - - /* Second TCO Timeout */ - if (tco2_sts & (1 << 1)) - elog_add_event(ELOG_TYPE_TCO_RESET); - - /* Power Button Override */ - if (pm1_sts & (1 << 11)) - elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); - - /* System Reset Status (reset button pushed) */ - if (gen_pmcon_2 & (1 << 4)) - elog_add_event(ELOG_TYPE_RESET_BUTTON); - - /* General Reset Status */ - if (gen_pmcon_3 & (1 << 9)) - elog_add_event(ELOG_TYPE_SYSTEM_RESET); - - /* ACPI Wake */ - if (pm1_sts & (1 << 15)) - elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, - acpi_slp_type == 3 ? 3 : 5); - - /* - * Wake sources - */ - /* Power Button */ - if (pm1_sts & (1 << 8)) + if (ps->pm1_sts & PWRBTN_STS) elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0); /* RTC */ - if (pm1_sts & (1 << 10)) + if (ps->pm1_sts & RTC_STS) elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0); /* PCI Express (TODO: determine wake device) */ - if (pm1_sts & (1 << 14)) + if (ps->pm1_sts & PCIEXPWAK_STS) elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0); - /* GPE */ - if (pch_is_lp()) - pch_lp_log_gpe(); - else - pch_log_gpe(); + /* PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0); + + /* 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); + + /* SMBUS Wake */ + if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0); + + /* Log GPIO events in set 1-3 */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_94_64], ps->gpe0_en[GPE_94_64], 64); } + +static void pch_log_power_and_resets(struct chipset_power_state *ps) +{ + /* Thermal Trip Status */ + if (ps->gen_pmcon2 & THERMTRIP_STS) + elog_add_event(ELOG_TYPE_THERM_TRIP); + + /* PWR_FLR Power Failure */ + if (ps->gen_pmcon2 & PWROK_FLR) + elog_add_event(ELOG_TYPE_POWER_FAIL); + + /* SUS Well Power Failure */ + if (ps->gen_pmcon3 & SUS_PWR_FLR) + elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); + + /* SYS_PWROK Failure */ + if (ps->gen_pmcon2 & SYSPWR_FLR) + elog_add_event(ELOG_TYPE_SYS_PWROK_FAIL); + + /* PWROK Failure */ + if (ps->gen_pmcon2 & PWROK_FLR) + elog_add_event(ELOG_TYPE_PWROK_FAIL); + + /* Second TCO Timeout */ + if (ps->tco2_sts & TCO2_STS_SECOND_TO) + elog_add_event(ELOG_TYPE_TCO_RESET); + + /* Power Button Override */ + if (ps->pm1_sts & PRBTNOR_STS) + elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); + + /* RTC reset */ + if (ps->gen_pmcon3 & RTC_BATTERY_DEAD) + elog_add_event(ELOG_TYPE_RTC_RESET); + + /* System Reset Status (reset button pushed) */ + if (ps->gen_pmcon2 & SYSTEM_RESET_STS) + elog_add_event(ELOG_TYPE_RESET_BUTTON); + + /* General Reset Status */ + if (ps->gen_pmcon3 & GEN_RST_STS) + elog_add_event(ELOG_TYPE_SYSTEM_RESET); + + /* ACPI Wake Event */ + if (ps->prev_sleep_state != SLEEP_STATE_S0) + elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state); +} + +static void pch_log_state(void *unused) +{ + struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); + + if (ps == NULL) { + printk(BIOS_ERR, "Not logging power state information. " + "Power state not found in cbmem.\n"); + return; + } + + /* Power and Reset */ + pch_log_power_and_resets(ps); + + /* Wake Sources */ + pch_log_wake_source(ps); +} + +BOOT_STATE_INIT_ENTRIES(pch_log) = { + BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, pch_log_state, NULL) +}; diff --git a/src/soc/intel/broadwell/smi.c b/src/soc/intel/broadwell/smi.c index 01c9de9315..a7fe9dac7b 100644 --- a/src/soc/intel/broadwell/smi.c +++ b/src/soc/intel/broadwell/smi.c @@ -32,10 +32,6 @@ void southbridge_smm_clear_state(void) { u32 smi_en; -#if CONFIG_ELOG - /* Log events from chipset before clearing */ - pch_log_state(); -#endif printk(BIOS_DEBUG, "Initializing Southbridge SMI..."); printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", get_pmbase());