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