• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <bootstate.h>
4 #include <console/console.h>
5 #include <device/pci_ops.h>
6 #include <elog.h>
7 #include <intelblocks/pmclib.h>
8 #include <intelblocks/xhci.h>
9 #include <soc/pci_devs.h>
10 #include <soc/pm.h>
11 #include <soc/soc_info.h>
12 #include <types.h>
13 
14 struct pme_map {
15 	unsigned int devfn;
16 	unsigned int wake_source;
17 };
18 
pch_log_gpio_gpe(u32 gpe0_sts,u32 gpe0_en,int start)19 static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
20 {
21 	int i;
22 
23 	gpe0_sts &= gpe0_en;
24 
25 	for (i = 0; i <= 31; i++) {
26 		if (gpe0_sts & (1 << i))
27 			elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
28 	}
29 }
30 
pch_log_rp_wake_source(void)31 static void pch_log_rp_wake_source(void)
32 {
33 	size_t i;
34 	uint8_t max_port = get_max_pcie_port();
35 
36 	const struct pme_map pme_map[] = {
37 		{ PCI_DEVFN_PCIE1,	ELOG_WAKE_SOURCE_PME_PCIE1 },
38 		{ PCI_DEVFN_PCIE2,	ELOG_WAKE_SOURCE_PME_PCIE2 },
39 		{ PCI_DEVFN_PCIE3,	ELOG_WAKE_SOURCE_PME_PCIE3 },
40 		{ PCI_DEVFN_PCIE4,	ELOG_WAKE_SOURCE_PME_PCIE4 },
41 		{ PCI_DEVFN_PCIE5,	ELOG_WAKE_SOURCE_PME_PCIE5 },
42 		{ PCI_DEVFN_PCIE6,	ELOG_WAKE_SOURCE_PME_PCIE6 },
43 		{ PCI_DEVFN_PCIE7,	ELOG_WAKE_SOURCE_PME_PCIE7 },
44 		{ PCI_DEVFN_PCIE8,	ELOG_WAKE_SOURCE_PME_PCIE8 },
45 		{ PCI_DEVFN_PCIE9,	ELOG_WAKE_SOURCE_PME_PCIE9 },
46 		{ PCI_DEVFN_PCIE10,	ELOG_WAKE_SOURCE_PME_PCIE10 },
47 		{ PCI_DEVFN_PCIE11,	ELOG_WAKE_SOURCE_PME_PCIE11 },
48 		{ PCI_DEVFN_PCIE12,	ELOG_WAKE_SOURCE_PME_PCIE12 },
49 	};
50 
51 	for (i = 0; i < MIN(max_port, ARRAY_SIZE(pme_map)); ++i) {
52 		if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(pme_map[i].devfn),
53 						   PCI_FUNC(pme_map[i].devfn))))
54 			elog_add_event_wake(pme_map[i].wake_source, 0);
55 	}
56 }
57 
pch_log_pme_internal_wake_source(void)58 static void pch_log_pme_internal_wake_source(void)
59 {
60 	const struct pme_map ipme_map[] = {
61 		{ PCI_DEVFN_HDA,	ELOG_WAKE_SOURCE_PME_HDA },
62 		{ PCI_DEVFN_GBE,	ELOG_WAKE_SOURCE_PME_GBE },
63 		{ PCI_DEVFN_SATA,	ELOG_WAKE_SOURCE_PME_SATA },
64 		{ PCI_DEVFN_CSE,	ELOG_WAKE_SOURCE_PME_CSE },
65 		{ PCI_DEVFN_XHCI,	ELOG_WAKE_SOURCE_PME_XHCI },
66 		{ PCI_DEVFN_USBOTG,	ELOG_WAKE_SOURCE_PME_XDCI },
67 		{ PCI_DEVFN_CNVI_WIFI,	ELOG_WAKE_SOURCE_PME_WIFI },
68 		{ PCI_DEVFN_TCSS_XDCI,	ELOG_WAKE_SOURCE_PME_TCSS_XDCI },
69 	};
70 	const struct xhci_wake_info xhci_wake_info[] = {
71 		{ PCI_DEVFN_XHCI,	ELOG_WAKE_SOURCE_PME_XHCI },
72 		{ PCI_DEVFN_TCSS_XHCI,	ELOG_WAKE_SOURCE_PME_TCSS_XHCI },
73 	};
74 	bool dev_found = false;
75 	size_t i;
76 
77 	for (i = 0; i < ARRAY_SIZE(ipme_map); i++) {
78 		unsigned int devfn = ipme_map[i].devfn;
79 		if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)))) {
80 			elog_add_event_wake(ipme_map[i].wake_source, 0);
81 			dev_found = true;
82 		}
83 	}
84 
85 	/* Check Thunderbolt ports */
86 	for (i = 0; i < NUM_TBT_FUNCTIONS; i++) {
87 		unsigned int devfn = PCI_DEVFN_TBT(i);
88 		if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)))) {
89 			elog_add_event_wake(ELOG_WAKE_SOURCE_PME_TBT, i);
90 			dev_found = true;
91 		}
92 	}
93 
94 	/* Check DMA devices */
95 	for (i = 0; i < NUM_TCSS_DMA_FUNCTIONS; i++) {
96 		unsigned int devfn = PCI_DEVFN_TCSS_DMA(i);
97 		if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)))) {
98 			elog_add_event_wake(ELOG_WAKE_SOURCE_PME_TCSS_DMA, i);
99 			dev_found = true;
100 		}
101 	}
102 
103 	/*
104 	 * Probe the XHCI controllers and their USB2 and USB3 ports to determine
105 	 * if any of them were wake sources.
106 	 */
107 	dev_found |= xhci_update_wake_event(xhci_wake_info, ARRAY_SIZE(xhci_wake_info));
108 
109 	if (!dev_found)
110 		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
111 }
112 
pch_log_wake_source(struct chipset_power_state * ps)113 static void pch_log_wake_source(struct chipset_power_state *ps)
114 {
115 	/* Power Button */
116 	if (ps->pm1_sts & PWRBTN_STS)
117 		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
118 
119 	/* RTC */
120 	if (ps->pm1_sts & RTC_STS)
121 		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
122 
123 	/* PCI Express */
124 	if (ps->pm1_sts & PCIEXPWAK_STS)
125 		pch_log_rp_wake_source();
126 
127 	/* PME (TODO: determine wake device) */
128 	if (ps->gpe0_sts[GPE_STD] & PME_STS)
129 		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
130 
131 	/* Internal PME */
132 	if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
133 		pch_log_pme_internal_wake_source();
134 
135 	/* SMBUS Wake */
136 	if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
137 		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
138 
139 	/* Log GPIO events in set 1-3 */
140 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
141 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
142 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
143 	/* Treat the STD as an extension of GPIO to obtain visibility. */
144 	pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
145 }
146 
pch_log_power_and_resets(const struct chipset_power_state * ps)147 static void pch_log_power_and_resets(const struct chipset_power_state *ps)
148 {
149 	/* Thermal Trip */
150 	if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
151 		elog_add_event(ELOG_TYPE_THERM_TRIP);
152 
153 	/* CSME-Initiated Host Reset with power down */
154 	if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPD)
155 		elog_add_event(ELOG_TYPE_MI_HRPD);
156 
157 	/* CSME-Initiated Host Reset with power cycle */
158 	if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPC)
159 		elog_add_event(ELOG_TYPE_MI_HRPC);
160 
161 	/* CSME-Initiated Host Reset without power cycle */
162 	if (ps->hpr_cause0 & HPR_CAUSE0_MI_HR)
163 		elog_add_event(ELOG_TYPE_MI_HR);
164 
165 	/* PWR_FLR Power Failure */
166 	if (ps->gen_pmcon_a & PWR_FLR)
167 		elog_add_event(ELOG_TYPE_POWER_FAIL);
168 
169 	/* SUS Well Power Failure */
170 	if (ps->gen_pmcon_a & SUS_PWR_FLR)
171 		elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
172 
173 	/* TCO Timeout */
174 	if (ps->prev_sleep_state != ACPI_S3 &&
175 	    ps->tco2_sts & TCO2_STS_SECOND_TO)
176 		elog_add_event(ELOG_TYPE_TCO_RESET);
177 
178 	/* Power Button Override */
179 	if (ps->pm1_sts & PRBTNOR_STS)
180 		elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
181 
182 	/* RTC reset */
183 	if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
184 		elog_add_event(ELOG_TYPE_RTC_RESET);
185 
186 	/* Host Reset Status */
187 	if (ps->gen_pmcon_a & HOST_RST_STS)
188 		elog_add_event(ELOG_TYPE_SYSTEM_RESET);
189 
190 	/* ACPI Wake Event */
191 	if (ps->prev_sleep_state != ACPI_S0)
192 		elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
193 }
194 
pch_log_state(void * unused)195 static void pch_log_state(void *unused)
196 {
197 	struct chipset_power_state *ps = pmc_get_power_state();
198 
199 	if (!ps) {
200 		printk(BIOS_ERR, "chipset_power_state not found!\n");
201 		return;
202 	}
203 
204 	/* Power and Reset */
205 	pch_log_power_and_resets(ps);
206 
207 	/* Wake Sources */
208 	if (ps->prev_sleep_state > ACPI_S0)
209 		pch_log_wake_source(ps);
210 }
211 
212 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL);
213 
elog_gsmi_cb_platform_log_wake_source(void)214 void elog_gsmi_cb_platform_log_wake_source(void)
215 {
216 	struct chipset_power_state ps;
217 	pmc_fill_pm_reg_info(&ps);
218 	pch_log_wake_source(&ps);
219 }
220