• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi_pm.h>
4 #include <device/pci_type.h>
5 #include <elog.h>
6 #include <intelblocks/pmclib.h>
7 #include <intelblocks/xhci.h>
8 #include <soc/pm.h>
9 #include <soc/pci_devs.h>
10 #include <soc/smbus.h>
11 #include <stdint.h>
12 
pch_log_gpio_gpe(u32 gpe0_sts,u32 gpe0_en,int start)13 static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
14 {
15 	int i;
16 
17 	gpe0_sts &= gpe0_en;
18 
19 	for (i = 0; i <= 31; i++) {
20 		if (gpe0_sts & (1 << i))
21 			elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
22 	}
23 }
24 
pch_log_wake_source(const struct chipset_power_state * ps)25 static void pch_log_wake_source(const struct chipset_power_state *ps)
26 {
27 	const struct xhci_wake_info xhci_wake_info[] = {
28 		{ PCH_DEVFN_XHCI, ELOG_WAKE_SOURCE_PME_XHCI },
29 	};
30 
31 	/* Power Button */
32 	if (ps->pm1_sts & PWRBTN_STS)
33 		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
34 
35 	/* RTC */
36 	if (ps->pm1_sts & RTC_STS)
37 		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
38 
39 	/* PCI Express (TODO: determine wake device) */
40 	if (ps->pm1_sts & PCIEXPWAK_STS)
41 		elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
42 
43 	/* PME */
44 	if (ps->gpe0_sts[GPE0_A] & CSE_PME_STS)
45 		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
46 
47 	/* XHCI */
48 	if (ps->gpe0_sts[GPE0_A] & XHCI_PME_STS)
49 		xhci_update_wake_event(xhci_wake_info,
50 				       ARRAY_SIZE(xhci_wake_info));
51 
52 	/* SMBUS Wake */
53 	if (ps->gpe0_sts[GPE0_A] & SMB_WAK_STS)
54 		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
55 
56 	/* ACPI Wake Event - Log prev sleep state only if it was not S0. */
57 	if (ps->prev_sleep_state != ACPI_S0)
58 		elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
59 
60 	/* Log GPIO events in set A-D */
61 	pch_log_gpio_gpe(ps->gpe0_sts[GPE0_A], ps->gpe0_en[GPE0_A], 0);
62 	pch_log_gpio_gpe(ps->gpe0_sts[GPE0_B], ps->gpe0_en[GPE0_B], 32);
63 	pch_log_gpio_gpe(ps->gpe0_sts[GPE0_C], ps->gpe0_en[GPE0_C], 64);
64 	pch_log_gpio_gpe(ps->gpe0_sts[GPE0_D], ps->gpe0_en[GPE0_D], 96);
65 }
66 
pch_log_power_and_resets(const struct chipset_power_state * ps)67 static void pch_log_power_and_resets(const struct chipset_power_state *ps)
68 {
69 	/* RTC Reset */
70 	if (ps->gen_pmcon1 & RPS)
71 		elog_add_event(ELOG_TYPE_RTC_RESET);
72 
73 	/* System Reset */
74 	if (ps->gen_pmcon1 & WARM_RESET_STS)
75 		elog_add_event(ELOG_TYPE_SYSTEM_RESET);
76 
77 	/* TCO Timeout */
78 	if (ps->prev_sleep_state != ACPI_S3 &&
79 	    ps->tco1_sts & TCO1_STS_TIMEOUT)
80 		elog_add_event(ELOG_TYPE_TCO_RESET);
81 
82 	/* Power Button Override */
83 	if (ps->pm1_sts & PRBTNOR_STS)
84 		elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
85 }
86 
pch_log_state(void)87 void pch_log_state(void)
88 {
89 	const struct chipset_power_state *ps;
90 
91 	if (acpi_fetch_pm_state(&ps, PS_CLAIMER_ELOG) < 0)
92 		return;
93 
94 	/* Power and Reset */
95 	pch_log_power_and_resets(ps);
96 
97 	/* Wake Sources */
98 	if (ps->prev_sleep_state > ACPI_S0)
99 		pch_log_wake_source(ps);
100 }
101 
elog_gsmi_cb_platform_log_wake_source(void)102 void elog_gsmi_cb_platform_log_wake_source(void)
103 {
104 	struct chipset_power_state ps;
105 
106 	pmc_fill_pm_reg_info(&ps);
107 	pch_log_wake_source(&ps);
108 }
109