1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_pm.h>
4 #include <device/pci_type.h>
6 #include <intelblocks/pmclib.h>
7 #include <intelblocks/xhci.h>
9 #include <soc/pci_devs.h>
10 #include <soc/smbus.h>
13 static void pch_log_gpio_gpe(u32 gpe0_sts
, u32 gpe0_en
, int start
)
19 for (i
= 0; i
<= 31; i
++) {
20 if (gpe0_sts
& (1 << i
))
21 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE
, i
+ start
);
25 static void pch_log_wake_source(const struct chipset_power_state
*ps
)
27 const struct xhci_wake_info xhci_wake_info
[] = {
28 { PCH_DEVFN_XHCI
, ELOG_WAKE_SOURCE_PME_XHCI
},
32 if (ps
->pm1_sts
& PWRBTN_STS
)
33 elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN
, 0);
36 if (ps
->pm1_sts
& RTC_STS
)
37 elog_add_event_wake(ELOG_WAKE_SOURCE_RTC
, 0);
39 /* PCI Express (TODO: determine wake device) */
40 if (ps
->pm1_sts
& PCIEXPWAK_STS
)
41 elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE
, 0);
44 if (ps
->gpe0_sts
[GPE0_A
] & CSE_PME_STS
)
45 elog_add_event_wake(ELOG_WAKE_SOURCE_PME
, 0);
48 if (ps
->gpe0_sts
[GPE0_A
] & XHCI_PME_STS
)
49 xhci_update_wake_event(xhci_wake_info
,
50 ARRAY_SIZE(xhci_wake_info
));
53 if (ps
->gpe0_sts
[GPE0_A
] & SMB_WAK_STS
)
54 elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS
, 0);
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
);
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);
67 static void pch_log_power_and_resets(const struct chipset_power_state
*ps
)
70 if (ps
->gen_pmcon1
& RPS
)
71 elog_add_event(ELOG_TYPE_RTC_RESET
);
74 if (ps
->gen_pmcon1
& WARM_RESET_STS
)
75 elog_add_event(ELOG_TYPE_SYSTEM_RESET
);
78 if (ps
->prev_sleep_state
!= ACPI_S3
&&
79 ps
->tco1_sts
& TCO1_STS_TIMEOUT
)
80 elog_add_event(ELOG_TYPE_TCO_RESET
);
82 /* Power Button Override */
83 if (ps
->pm1_sts
& PRBTNOR_STS
)
84 elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE
);
87 void pch_log_state(void)
89 const struct chipset_power_state
*ps
;
91 if (acpi_fetch_pm_state(&ps
, PS_CLAIMER_ELOG
) < 0)
95 pch_log_power_and_resets(ps
);
98 if (ps
->prev_sleep_state
> ACPI_S0
)
99 pch_log_wake_source(ps
);
102 void elog_gsmi_cb_platform_log_wake_source(void)
104 struct chipset_power_state ps
;
106 pmc_fill_pm_reg_info(&ps
);
107 pch_log_wake_source(&ps
);