blob: ce1909163b8c5ab114030696444fe93cef08ee3c [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin76c37002012-10-30 09:03:43 -05002
3#include <arch/io.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpi.h>
Aaron Durbin76c37002012-10-30 09:03:43 -05005#include <device/device.h>
6#include <device/pci.h>
7#include <device/pci_ops.h>
8#include <stdint.h>
Aaron Durbin76c37002012-10-30 09:03:43 -05009#include <elog.h>
10#include "pch.h"
11
Duncan Lauried6040902013-03-08 17:16:37 -080012static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg)
13{
14 u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
15 u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
16
17 /* PME (TODO: determine wake device) */
Angel Pons35605d62021-04-24 11:54:01 +020018 if (gpe0_sts & PME_STS)
Duncan Lauried6040902013-03-08 17:16:37 -080019 elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
20
21 /* Internal PME (TODO: determine wake device) */
Angel Pons35605d62021-04-24 11:54:01 +020022 if (gpe0_sts & PME_B0_STS)
Duncan Lauried6040902013-03-08 17:16:37 -080023 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
24
25 /* SMBUS Wake */
Angel Pons35605d62021-04-24 11:54:01 +020026 if (gpe0_sts & SMB_WAK_STS)
Duncan Lauried6040902013-03-08 17:16:37 -080027 elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
28}
29
30static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start)
31{
32 /* GPE Bank 1 is GPIO 0-31 */
33 u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
34 u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
35 int i;
36
37 for (i = 0; i <= 31; i++) {
38 if (gpe0_sts & (1 << i))
Aaron Durbinaa902032020-08-17 09:37:13 -060039 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
Duncan Lauried6040902013-03-08 17:16:37 -080040 }
41}
42
43static void pch_log_gpe(void)
44{
45 int i;
46 u16 pmbase = get_pmbase();
47 u32 gpe0_sts, gpe0_en;
48 int gpe0_high_gpios[] = {
Angel Pons2aaf7c02020-09-24 18:03:18 +020049 [0] = 27,
Duncan Lauried6040902013-03-08 17:16:37 -080050 [24] = 17,
51 [25] = 19,
52 [26] = 21,
53 [27] = 22,
54 [28] = 43,
55 [29] = 56,
56 [30] = 57,
57 [31] = 60
58 };
59
60 pch_log_standard_gpe(GPE0_EN, GPE0_STS);
61
62 /* GPIO 0-15 */
Kyösti Mälkkiab368d92023-05-06 14:37:22 +030063 gpe0_en = inw(pmbase + GPE0_EN + sizeof(uint16_t));
64 gpe0_sts = inw(pmbase + GPE0_STS + sizeof(uint16_t)) & gpe0_en;
Duncan Lauried6040902013-03-08 17:16:37 -080065 for (i = 0; i <= 15; i++) {
66 if (gpe0_sts & (1 << i))
Aaron Durbinaa902032020-08-17 09:37:13 -060067 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i);
Duncan Lauried6040902013-03-08 17:16:37 -080068 }
69
70 /*
71 * Now check and log upper status bits
72 */
73
Kyösti Mälkkiab368d92023-05-06 14:37:22 +030074 gpe0_en = inl(pmbase + GPE0_EN + sizeof(uint32_t));
75 gpe0_sts = inl(pmbase + GPE0_STS + sizeof(uint32_t)) & gpe0_en;
Duncan Lauried6040902013-03-08 17:16:37 -080076
77 for (i = 0; i <= 31; i++) {
78 if (!gpe0_high_gpios[i])
79 continue;
80 if (gpe0_sts & (1 << i))
Aaron Durbinaa902032020-08-17 09:37:13 -060081 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE,
Duncan Lauried6040902013-03-08 17:16:37 -080082 gpe0_high_gpios[i]);
83 }
84}
85
86static void pch_lp_log_gpe(void)
87{
88 /* Standard GPE are in GPE set 4 */
89 pch_log_standard_gpe(LP_GPE0_STS_4, LP_GPE0_EN_4);
90
91 /* Log GPIO events in set 1-3 */
92 pch_log_gpio_gpe(LP_GPE0_STS_1, LP_GPE0_EN_1, 0);
93 pch_log_gpio_gpe(LP_GPE0_STS_2, LP_GPE0_EN_2, 32);
94 pch_log_gpio_gpe(LP_GPE0_STS_3, LP_GPE0_EN_3, 64);
95}
96
Aaron Durbin76c37002012-10-30 09:03:43 -050097void pch_log_state(void)
98{
99 u16 pm1_sts, gen_pmcon_3, tco2_sts;
Aaron Durbin76c37002012-10-30 09:03:43 -0500100 u8 gen_pmcon_2;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300101 struct device *lpc = pcidev_on_root(0x1f, 0);
Aaron Durbin76c37002012-10-30 09:03:43 -0500102 if (!lpc)
103 return;
104
Duncan Lauried6040902013-03-08 17:16:37 -0800105 pm1_sts = inw(get_pmbase() + PM1_STS);
106 tco2_sts = inw(get_pmbase() + TCO2_STS);
Aaron Durbin76c37002012-10-30 09:03:43 -0500107 gen_pmcon_2 = pci_read_config8(lpc, GEN_PMCON_2);
108 gen_pmcon_3 = pci_read_config16(lpc, GEN_PMCON_3);
109
110 /* PWR_FLR Power Failure */
Angel Pons35605d62021-04-24 11:54:01 +0200111 if (gen_pmcon_2 & PWROK_FLR)
Aaron Durbin76c37002012-10-30 09:03:43 -0500112 elog_add_event(ELOG_TYPE_POWER_FAIL);
113
114 /* SUS Well Power Failure */
Angel Pons35605d62021-04-24 11:54:01 +0200115 if (gen_pmcon_3 & SUS_PWR_FLR)
Aaron Durbin76c37002012-10-30 09:03:43 -0500116 elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
117
118 /* SYS_PWROK Failure */
Angel Pons35605d62021-04-24 11:54:01 +0200119 if (gen_pmcon_2 & SYSPWR_FLR)
Aaron Durbin76c37002012-10-30 09:03:43 -0500120 elog_add_event(ELOG_TYPE_SYS_PWROK_FAIL);
121
122 /* PWROK Failure */
Angel Pons35605d62021-04-24 11:54:01 +0200123 if (gen_pmcon_2 & PWROK_FLR)
Aaron Durbin76c37002012-10-30 09:03:43 -0500124 elog_add_event(ELOG_TYPE_PWROK_FAIL);
125
126 /* Second TCO Timeout */
Kyösti Mälkki307320c2022-11-21 17:27:07 +0200127 if (tco2_sts & TCO2_STS_SECOND_TO)
Aaron Durbin76c37002012-10-30 09:03:43 -0500128 elog_add_event(ELOG_TYPE_TCO_RESET);
129
130 /* Power Button Override */
Angel Pons35605d62021-04-24 11:54:01 +0200131 if (pm1_sts & PRBTNOR_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500132 elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
133
134 /* System Reset Status (reset button pushed) */
Angel Pons35605d62021-04-24 11:54:01 +0200135 if (gen_pmcon_2 & SYSTEM_RESET_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500136 elog_add_event(ELOG_TYPE_RESET_BUTTON);
137
138 /* General Reset Status */
Angel Pons35605d62021-04-24 11:54:01 +0200139 if (gen_pmcon_3 & GEN_RST_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500140 elog_add_event(ELOG_TYPE_SYSTEM_RESET);
141
142 /* ACPI Wake */
Angel Pons35605d62021-04-24 11:54:01 +0200143 if (pm1_sts & WAK_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500144 elog_add_event_byte(ELOG_TYPE_ACPI_WAKE,
Kyösti Mälkkic3ed8862014-06-19 19:50:51 +0300145 acpi_is_wakeup_s3() ? 3 : 5);
Aaron Durbin76c37002012-10-30 09:03:43 -0500146
147 /*
148 * Wake sources
149 */
150
Duncan Lauried6040902013-03-08 17:16:37 -0800151 /* Power Button */
Angel Pons35605d62021-04-24 11:54:01 +0200152 if (pm1_sts & PWRBTN_STS)
Duncan Lauried6040902013-03-08 17:16:37 -0800153 elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
154
Aaron Durbin76c37002012-10-30 09:03:43 -0500155 /* RTC */
Angel Pons35605d62021-04-24 11:54:01 +0200156 if (pm1_sts & RTC_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500157 elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
158
159 /* PCI Express (TODO: determine wake device) */
Angel Pons35605d62021-04-24 11:54:01 +0200160 if (pm1_sts & PCIEXPWAK_STS)
Aaron Durbin76c37002012-10-30 09:03:43 -0500161 elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
162
Duncan Lauried6040902013-03-08 17:16:37 -0800163 /* GPE */
164 if (pch_is_lp())
165 pch_lp_log_gpe();
166 else
167 pch_log_gpe();
Aaron Durbin76c37002012-10-30 09:03:43 -0500168}