blob: 4967fde00110b0ee514008ea1a37d8cb8a70d362 [file] [log] [blame]
Angel Pons32abdd62020-04-05 15:47:03 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Subrata Banik54893412019-04-29 13:28:11 +05302
3#include <bootstate.h>
Subrata Banik54893412019-04-29 13:28:11 +05304#include <console/console.h>
5#include <stdint.h>
6#include <elog.h>
7#include <intelblocks/pmclib.h>
8#include <soc/pci_devs.h>
9#include <soc/pm.h>
10
11static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
12{
13 int i;
14
15 gpe0_sts &= gpe0_en;
16
17 for (i = 0; i <= 31; i++) {
18 if (gpe0_sts & (1 << i))
Aaron Durbinaa902032020-08-17 09:37:13 -060019 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
Subrata Banik54893412019-04-29 13:28:11 +053020 }
21}
22
Kyösti Mälkki6b430552021-01-22 07:52:43 +020023static void pch_log_wake_source(const struct chipset_power_state *ps)
Subrata Banik54893412019-04-29 13:28:11 +053024{
25 /* Power Button */
26 if (ps->pm1_sts & PWRBTN_STS)
27 elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
28
29 /* RTC */
30 if (ps->pm1_sts & RTC_STS)
31 elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
32
33 /* PCI Express (TODO: determine wake device) */
34 if (ps->pm1_sts & PCIEXPWAK_STS)
35 elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
36
37 /* PME (TODO: determine wake device) */
38 if (ps->gpe0_sts[GPE_STD] & PME_STS)
39 elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
40
41 /* Internal PME (TODO: determine wake device) */
42 if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
43 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
44
45 /* SMBUS Wake */
46 if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
47 elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
48
49 /* Log GPIO events in set 1-3 */
50 pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
51 pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
52 pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
53 /* Treat the STD as an extension of GPIO to obtain visibility. */
54 pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
55}
56
Kyösti Mälkki6b430552021-01-22 07:52:43 +020057static void pch_log_power_and_resets(const struct chipset_power_state *ps)
Subrata Banik54893412019-04-29 13:28:11 +053058{
59 /* Thermal Trip */
60 if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
61 elog_add_event(ELOG_TYPE_THERM_TRIP);
62
63 /* PWR_FLR Power Failure */
64 if (ps->gen_pmcon_a & PWR_FLR)
65 elog_add_event(ELOG_TYPE_POWER_FAIL);
66
67 /* SUS Well Power Failure */
68 if (ps->gen_pmcon_a & SUS_PWR_FLR)
69 elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
70
71 /* TCO Timeout */
72 if (ps->prev_sleep_state != ACPI_S3 &&
73 ps->tco2_sts & TCO_STS_SECOND_TO)
74 elog_add_event(ELOG_TYPE_TCO_RESET);
75
76 /* Power Button Override */
77 if (ps->pm1_sts & PRBTNOR_STS)
78 elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
79
80 /* RTC reset */
81 if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
82 elog_add_event(ELOG_TYPE_RTC_RESET);
83
84 /* Host Reset Status */
85 if (ps->gen_pmcon_a & HOST_RST_STS)
86 elog_add_event(ELOG_TYPE_SYSTEM_RESET);
87
88 /* ACPI Wake Event */
89 if (ps->prev_sleep_state != ACPI_S0)
90 elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
91}
92
93static void pch_log_state(void *unused)
94{
95 struct chipset_power_state *ps = pmc_get_power_state();
96
97 if (!ps) {
98 printk(BIOS_ERR, "chipset_power_state not found!\n");
99 return;
100 }
101
102 /* Power and Reset */
103 pch_log_power_and_resets(ps);
104
105 /* Wake Sources */
106 if (ps->prev_sleep_state > ACPI_S0)
107 pch_log_wake_source(ps);
108}
109
110BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL);
111
112void elog_gsmi_cb_platform_log_wake_source(void)
113{
114 struct chipset_power_state ps;
115 pmc_fill_pm_reg_info(&ps);
116 pch_log_wake_source(&ps);
117}