1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <commonlib/bsd/helpers.h>
6 #include <console/console.h>
7 #include <device/pci_def.h>
8 #include <device/pci_ops.h>
9 #include <device/pci_type.h>
11 #include <intelblocks/pmclib.h>
12 #include <intelblocks/xhci.h>
13 #include <soc/pci_devs.h>
19 unsigned int wake_source
;
22 static void pch_log_gpio_gpe(u32 gpe0_sts
, u32 gpe0_en
, int start
)
28 for (i
= 0; i
<= 31; i
++) {
29 if (gpe0_sts
& (1 << i
))
30 elog_add_event_wake(ELOG_WAKE_SOURCE_GPE
, i
+ start
);
34 static void pch_log_rp_wake_source(void)
38 const struct pme_map pme_map
[] = {
39 { PCH_DEVFN_PCIE1
, ELOG_WAKE_SOURCE_PME_PCIE1
},
40 { PCH_DEVFN_PCIE2
, ELOG_WAKE_SOURCE_PME_PCIE2
},
41 { PCH_DEVFN_PCIE3
, ELOG_WAKE_SOURCE_PME_PCIE3
},
42 { PCH_DEVFN_PCIE4
, ELOG_WAKE_SOURCE_PME_PCIE4
},
43 { PCH_DEVFN_PCIE5
, ELOG_WAKE_SOURCE_PME_PCIE5
},
44 { PCH_DEVFN_PCIE6
, ELOG_WAKE_SOURCE_PME_PCIE6
},
45 { PCH_DEVFN_PCIE7
, ELOG_WAKE_SOURCE_PME_PCIE7
},
46 { PCH_DEVFN_PCIE8
, ELOG_WAKE_SOURCE_PME_PCIE8
},
47 { PCH_DEVFN_PCIE9
, ELOG_WAKE_SOURCE_PME_PCIE9
},
48 { PCH_DEVFN_PCIE10
, ELOG_WAKE_SOURCE_PME_PCIE10
},
49 { PCH_DEVFN_PCIE11
, ELOG_WAKE_SOURCE_PME_PCIE11
},
50 { PCH_DEVFN_PCIE12
, ELOG_WAKE_SOURCE_PME_PCIE12
},
53 for (i
= 0; i
< MIN(CONFIG_MAX_ROOT_PORTS
, ARRAY_SIZE(pme_map
)); ++i
) {
54 if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(pme_map
[i
].devfn
),
55 PCI_FUNC(pme_map
[i
].devfn
))))
56 elog_add_event_wake(pme_map
[i
].wake_source
, 0);
60 static void pch_log_pme_internal_wake_source(void)
62 const struct pme_map ipme_map
[] = {
63 { PCH_DEVFN_HDA
, ELOG_WAKE_SOURCE_PME_HDA
},
64 { PCH_DEVFN_GBE
, ELOG_WAKE_SOURCE_PME_GBE
},
65 { PCH_DEVFN_SATA
, ELOG_WAKE_SOURCE_PME_SATA
},
66 { PCH_DEVFN_CSE
, ELOG_WAKE_SOURCE_PME_CSE
},
67 { PCH_DEVFN_USBOTG
, ELOG_WAKE_SOURCE_PME_XDCI
},
68 { PCH_DEVFN_CNVI_WIFI
, ELOG_WAKE_SOURCE_PME_WIFI
},
69 { SA_DEVFN_TCSS_XDCI
, ELOG_WAKE_SOURCE_PME_TCSS_XDCI
},
71 const struct xhci_wake_info xhci_wake_info
[] = {
72 { PCH_DEVFN_XHCI
, ELOG_WAKE_SOURCE_PME_XHCI
},
73 { SA_DEVFN_TCSS_XHCI
, ELOG_WAKE_SOURCE_PME_TCSS_XHCI
},
75 bool dev_found
= false;
78 for (i
= 0; i
< ARRAY_SIZE(ipme_map
); i
++) {
79 if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(ipme_map
[i
].devfn
),
80 PCI_FUNC(ipme_map
[i
].devfn
)))) {
81 elog_add_event_wake(ipme_map
[i
].wake_source
, 0);
86 /* Check Thunderbolt ports */
87 for (i
= 0; i
< NUM_TBT_FUNCTIONS
; i
++) {
88 const unsigned int devfn
= SA_DEVFN_TBT(i
);
89 if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(devfn
), PCI_FUNC(devfn
)))) {
90 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_TBT
, i
);
95 /* Check DMA devices */
96 for (i
= 0; i
< NUM_TCSS_DMA_FUNCTIONS
; i
++) {
97 const unsigned int devfn
= SA_DEVFN_TCSS_DMA(i
);
98 if (pci_dev_is_wake_source(PCI_DEV(0, PCI_SLOT(devfn
), PCI_FUNC(devfn
)))) {
99 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_TCSS_DMA
, i
);
105 * Check the XHCI controllers' USB2 & USB3 ports for wake events. There
106 * are cases (GSMI logging for S0ix clears PME_STS_BIT) where the XHCI
107 * controller's PME_STS_BIT may have already been cleared, so the host
108 * controller wake wouldn't get logged here; therefore, the host
109 * controller wake event is logged before its corresponding port wake
112 dev_found
|= xhci_update_wake_event(xhci_wake_info
,
113 ARRAY_SIZE(xhci_wake_info
));
116 elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL
, 0);
119 static void pch_log_wake_source(const struct chipset_power_state
*ps
)
122 if (ps
->pm1_sts
& PWRBTN_STS
)
123 elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN
, 0);
126 if (ps
->pm1_sts
& RTC_STS
)
127 elog_add_event_wake(ELOG_WAKE_SOURCE_RTC
, 0);
129 /* PCI Express (TODO: determine wake device) */
130 if (ps
->pm1_sts
& PCIEXPWAK_STS
)
131 pch_log_rp_wake_source();
133 /* PME (TODO: determine wake device) */
134 if (ps
->gpe0_sts
[GPE_STD
] & PME_STS
)
135 elog_add_event_wake(ELOG_WAKE_SOURCE_PME
, 0);
138 if (ps
->gpe0_sts
[GPE_STD
] & PME_B0_STS
)
139 pch_log_pme_internal_wake_source();
142 if (ps
->gpe0_sts
[GPE_STD
] & SMB_WAK_STS
)
143 elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS
, 0);
145 /* Log GPIO events in set 1-3 */
146 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE_31_0
], ps
->gpe0_en
[GPE_31_0
], 0);
147 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE_63_32
], ps
->gpe0_en
[GPE_63_32
], 32);
148 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE_95_64
], ps
->gpe0_en
[GPE_95_64
], 64);
149 /* Treat the STD as an extension of GPIO to obtain visibility. */
150 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE_STD
], ps
->gpe0_en
[GPE_STD
], 96);
153 static void pch_log_power_and_resets(const struct chipset_power_state
*ps
)
156 if (ps
->gblrst_cause
[0] & GBLRST_CAUSE0_THERMTRIP
)
157 elog_add_event(ELOG_TYPE_THERM_TRIP
);
159 /* CSME-Initiated Host Reset with power down */
160 if (ps
->hpr_cause0
& HPR_CAUSE0_MI_HRPD
)
161 elog_add_event(ELOG_TYPE_MI_HRPD
);
163 /* CSME-Initiated Host Reset with power cycle */
164 if (ps
->hpr_cause0
& HPR_CAUSE0_MI_HRPC
)
165 elog_add_event(ELOG_TYPE_MI_HRPC
);
167 /* CSME-Initiated Host Reset without power cycle */
168 if (ps
->hpr_cause0
& HPR_CAUSE0_MI_HR
)
169 elog_add_event(ELOG_TYPE_MI_HR
);
171 /* PWR_FLR Power Failure */
172 if (ps
->gen_pmcon_a
& PWR_FLR
)
173 elog_add_event(ELOG_TYPE_POWER_FAIL
);
175 /* SUS Well Power Failure */
176 if (ps
->gen_pmcon_a
& SUS_PWR_FLR
)
177 elog_add_event(ELOG_TYPE_SUS_POWER_FAIL
);
180 if (ps
->prev_sleep_state
!= ACPI_S3
&&
181 ps
->tco2_sts
& TCO2_STS_SECOND_TO
)
182 elog_add_event(ELOG_TYPE_TCO_RESET
);
184 /* Power Button Override */
185 if (ps
->pm1_sts
& PRBTNOR_STS
)
186 elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE
);
189 if (ps
->gen_pmcon_b
& RTC_BATTERY_DEAD
)
190 elog_add_event(ELOG_TYPE_RTC_RESET
);
192 /* Host Reset Status */
193 if (ps
->gen_pmcon_a
& HOST_RST_STS
)
194 elog_add_event(ELOG_TYPE_SYSTEM_RESET
);
196 /* ACPI Wake Event */
197 if (ps
->prev_sleep_state
!= ACPI_S0
)
198 elog_add_event_byte(ELOG_TYPE_ACPI_WAKE
, ps
->prev_sleep_state
);
201 static void pch_log_state(void *unused
)
203 struct chipset_power_state
*ps
= pmc_get_power_state();
206 printk(BIOS_ERR
, "chipset_power_state not found!\n");
210 /* Power and Reset */
211 pch_log_power_and_resets(ps
);
214 if (ps
->prev_sleep_state
> ACPI_S0
)
215 pch_log_wake_source(ps
);
218 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT
, BS_ON_EXIT
, pch_log_state
, NULL
);
220 void elog_gsmi_cb_platform_log_wake_source(void)
222 struct chipset_power_state ps
;
223 pmc_fill_pm_reg_info(&ps
);
224 pch_log_wake_source(&ps
);