• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi_pm.h>
4 #include <bootstate.h>
5 #include <commonlib/helpers.h>
6 #include <device/mmio.h>
7 #include <device/pci_ops.h>
8 #include <stdint.h>
9 #include <elog.h>
10 #include <intelblocks/pmclib.h>
11 #include <intelblocks/xhci.h>
12 #include <soc/pci_devs.h>
13 #include <soc/pm.h>
14 #include <soc/smbus.h>
15 
pch_log_gpio_gpe(u32 gpe0_sts,u32 gpe0_en,int start)16 static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
17 {
18 	int i;
19 
20 	gpe0_sts &= gpe0_en;
21 
22 	for (i = 0; i <= 31; i++) {
23 		if (gpe0_sts & (1 << i))
24 			elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
25 	}
26 }
27 
28 struct pme_status_info {
29 	unsigned int devfn;
30 	uint8_t reg_offset;
31 	uint32_t elog_event;
32 };
33 
34 #define PME_STS_BIT		(1 << 15)
35 
pch_log_pme_internal_wake_source(void)36 static void pch_log_pme_internal_wake_source(void)
37 {
38 	size_t i;
39 	uint16_t val;
40 	bool dev_found = false;
41 
42 	const struct pme_status_info pme_status_info[] = {
43 		{ PCH_DEVFN_HDA, 0x54, ELOG_WAKE_SOURCE_PME_HDA },
44 		{ PCH_DEVFN_GBE, 0xcc, ELOG_WAKE_SOURCE_PME_GBE },
45 		{ PCH_DEVFN_SATA, 0x74, ELOG_WAKE_SOURCE_PME_SATA },
46 		{ PCH_DEVFN_CSE, 0x54, ELOG_WAKE_SOURCE_PME_CSE },
47 		{ PCH_DEVFN_USBOTG, 0x84, ELOG_WAKE_SOURCE_PME_XDCI },
48 	};
49 	const struct xhci_wake_info xhci_wake_info[] = {
50 		{ PCH_DEVFN_XHCI, ELOG_WAKE_SOURCE_PME_XHCI },
51 	};
52 
53 	for (i = 0; i < ARRAY_SIZE(pme_status_info); i++) {
54 		pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(pme_status_info[i].devfn),
55 					  PCI_FUNC(pme_status_info[i].devfn));
56 
57 		val = pci_s_read_config16(dev, pme_status_info[i].reg_offset);
58 
59 		if ((val == 0xFFFF) || !(val & PME_STS_BIT))
60 			continue;
61 
62 		elog_add_event_wake(pme_status_info[i].elog_event, 0);
63 		dev_found = true;
64 	}
65 
66 	/*
67 	 * Check the XHCI controllers' USB2 & USB3 ports for wake events. There
68 	 * are cases (GSMI logging for S0ix clears PME_STS_BIT) where the XHCI
69 	 * controller's PME_STS_BIT may have already been cleared, so the host
70 	 * controller wake wouldn't get logged here; therefore, the host
71 	 * controller wake event is logged before its corresponding port wake
72 	 * event is logged.
73 	 */
74 	dev_found |= xhci_update_wake_event(xhci_wake_info,
75 					    ARRAY_SIZE(xhci_wake_info));
76 
77 	if (!dev_found)
78 		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
79 }
80 
81 #define RP_PME_STS_BIT		(1 << 16)
pch_log_rp_wake_source(void)82 static void pch_log_rp_wake_source(void)
83 {
84 	size_t i, maxports;
85 	uint32_t val;
86 
87 	struct pme_status_info pme_status_info[] = {
88 		{ PCH_DEVFN_PCIE1, 0x60, ELOG_WAKE_SOURCE_PME_PCIE1 },
89 		{ PCH_DEVFN_PCIE2, 0x60, ELOG_WAKE_SOURCE_PME_PCIE2 },
90 		{ PCH_DEVFN_PCIE3, 0x60, ELOG_WAKE_SOURCE_PME_PCIE3 },
91 		{ PCH_DEVFN_PCIE4, 0x60, ELOG_WAKE_SOURCE_PME_PCIE4 },
92 		{ PCH_DEVFN_PCIE5, 0x60, ELOG_WAKE_SOURCE_PME_PCIE5 },
93 		{ PCH_DEVFN_PCIE6, 0x60, ELOG_WAKE_SOURCE_PME_PCIE6 },
94 		{ PCH_DEVFN_PCIE7, 0x60, ELOG_WAKE_SOURCE_PME_PCIE7 },
95 		{ PCH_DEVFN_PCIE8, 0x60, ELOG_WAKE_SOURCE_PME_PCIE8 },
96 		{ PCH_DEVFN_PCIE9, 0x60, ELOG_WAKE_SOURCE_PME_PCIE9 },
97 		{ PCH_DEVFN_PCIE10, 0x60, ELOG_WAKE_SOURCE_PME_PCIE10 },
98 		{ PCH_DEVFN_PCIE11, 0x60, ELOG_WAKE_SOURCE_PME_PCIE11 },
99 		{ PCH_DEVFN_PCIE12, 0x60, ELOG_WAKE_SOURCE_PME_PCIE12 },
100 		{ PCH_DEVFN_PCIE13, 0x60, ELOG_WAKE_SOURCE_PME_PCIE13 },
101 		{ PCH_DEVFN_PCIE14, 0x60, ELOG_WAKE_SOURCE_PME_PCIE14 },
102 		{ PCH_DEVFN_PCIE15, 0x60, ELOG_WAKE_SOURCE_PME_PCIE15 },
103 		{ PCH_DEVFN_PCIE16, 0x60, ELOG_WAKE_SOURCE_PME_PCIE16 },
104 		{ PCH_DEVFN_PCIE17, 0x60, ELOG_WAKE_SOURCE_PME_PCIE17 },
105 		{ PCH_DEVFN_PCIE18, 0x60, ELOG_WAKE_SOURCE_PME_PCIE18 },
106 		{ PCH_DEVFN_PCIE19, 0x60, ELOG_WAKE_SOURCE_PME_PCIE19 },
107 		{ PCH_DEVFN_PCIE20, 0x60, ELOG_WAKE_SOURCE_PME_PCIE20 },
108 		{ PCH_DEVFN_PCIE21, 0x60, ELOG_WAKE_SOURCE_PME_PCIE21 },
109 		{ PCH_DEVFN_PCIE22, 0x60, ELOG_WAKE_SOURCE_PME_PCIE22 },
110 		{ PCH_DEVFN_PCIE23, 0x60, ELOG_WAKE_SOURCE_PME_PCIE23 },
111 		{ PCH_DEVFN_PCIE24, 0x60, ELOG_WAKE_SOURCE_PME_PCIE24 },
112 	};
113 
114 	maxports = MIN(CONFIG_MAX_ROOT_PORTS, ARRAY_SIZE(pme_status_info));
115 
116 	for (i = 0; i < maxports; i++) {
117 		pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(pme_status_info[i].devfn),
118 					  PCI_FUNC(pme_status_info[i].devfn));
119 
120 		val = pci_s_read_config32(dev, pme_status_info[i].reg_offset);
121 
122 		if ((val == 0xFFFFFFFF) || !(val & RP_PME_STS_BIT))
123 			continue;
124 
125 		/*
126 		 * Linux kernel uses PME STS bit information. So do not clear
127 		 * this bit.
128 		 */
129 		elog_add_event_wake(pme_status_info[i].elog_event, 0);
130 	}
131 }
132 
pch_log_wake_source(const struct chipset_power_state * ps)133 static void pch_log_wake_source(const struct chipset_power_state *ps)
134 {
135 	/* Power Button */
136 	if (ps->pm1_sts & PWRBTN_STS)
137 		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
138 
139 	/* RTC */
140 	if (ps->pm1_sts & RTC_STS)
141 		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
142 
143 	/* PCI Express (TODO: determine wake device) */
144 	if (ps->pm1_sts & PCIEXPWAK_STS)
145 		elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
146 
147 	/*
148 	 * PCIE Root Port .
149 	 * This should be done when PCIEXPWAK_STS bit is set.
150 	 * In SPT, this bit isn't getting set due to known bug.
151 	 * So scan all PCIe RP for PME status bit.
152 	 */
153 	pch_log_rp_wake_source();
154 
155 	/* PME (TODO: determine wake device) */
156 	if (ps->gpe0_sts[GPE_STD] & PME_STS)
157 		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
158 
159 	/* Internal PME (TODO: determine wake device) */
160 	if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
161 		pch_log_pme_internal_wake_source();
162 
163 	/* SMBUS Wake */
164 	if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
165 		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
166 
167 	/* Log GPIO events in set 1-3 */
168 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
169 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
170 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
171 	/* Treat the STD as an extension of GPIO to obtain visibility. */
172 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
173 }
174 
pch_log_power_and_resets(const struct chipset_power_state * ps)175 static void pch_log_power_and_resets(const struct chipset_power_state *ps)
176 {
177 	bool deep_sx;
178 
179 	/*
180 	 * Platform entered deep Sx if:
181 	 * 1. Prev sleep state was Sx and deep_sx_enabled() is true
182 	 * 2. SUS well power was lost
183 	 */
184 	deep_sx = ((((ps->prev_sleep_state == ACPI_S3) && deep_s3_enabled()) ||
185 		   ((ps->prev_sleep_state == ACPI_S5) && deep_s5_enabled())) &&
186 		   (ps->gen_pmcon_b & SUS_PWR_FLR));
187 
188 	/* Thermal Trip */
189 	if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
190 		elog_add_event(ELOG_TYPE_THERM_TRIP);
191 
192 	/* PWR_FLR Power Failure */
193 	if (ps->gen_pmcon_b & PWR_FLR)
194 		elog_add_event(ELOG_TYPE_POWER_FAIL);
195 
196 	/* SUS Well Power Failure */
197 	if (ps->gen_pmcon_b & SUS_PWR_FLR) {
198 		/* Do not log SUS_PWR_FLR if waking from deep Sx */
199 		if (!deep_sx)
200 			elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
201 	}
202 
203 	/* TCO Timeout */
204 	if (ps->prev_sleep_state != ACPI_S3 &&
205 	    ps->tco2_sts & TCO2_STS_SECOND_TO)
206 		elog_add_event(ELOG_TYPE_TCO_RESET);
207 
208 	/* Power Button Override */
209 	if (ps->pm1_sts & PRBTNOR_STS)
210 		elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
211 
212 	/* RTC reset */
213 	if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
214 		elog_add_event(ELOG_TYPE_RTC_RESET);
215 
216 	/* Host Reset Status */
217 	if (ps->gen_pmcon_b & HOST_RST_STS)
218 		elog_add_event(ELOG_TYPE_SYSTEM_RESET);
219 
220 	/* ACPI Wake Event */
221 	if (ps->prev_sleep_state != ACPI_S0) {
222 		if (deep_sx)
223 			elog_add_event_byte(ELOG_TYPE_ACPI_DEEP_WAKE,
224 					    ps->prev_sleep_state);
225 		else
226 			elog_add_event_byte(ELOG_TYPE_ACPI_WAKE,
227 					    ps->prev_sleep_state);
228 	}
229 }
230 
pch_log_state(void * unused)231 static void pch_log_state(void *unused)
232 {
233 	const struct chipset_power_state *ps;
234 
235 	if (acpi_fetch_pm_state(&ps, PS_CLAIMER_ELOG) < 0)
236 		return;
237 
238 	/* Power and Reset */
239 	pch_log_power_and_resets(ps);
240 
241 	/* Wake Sources */
242 	if (ps->prev_sleep_state > 0)
243 		pch_log_wake_source(ps);
244 }
245 
246 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL);
247 
elog_gsmi_cb_platform_log_wake_source(void)248 void elog_gsmi_cb_platform_log_wake_source(void)
249 {
250 	struct chipset_power_state ps;
251 	pmc_fill_pm_reg_info(&ps);
252 	pch_log_wake_source(&ps);
253 }
254