2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <bootstate.h>
17 #include <console/console.h>
19 #include <intelblocks/pmclib.h>
20 #include <intelblocks/xhci.h>
22 #include <soc/pci_devs.h>
23 #include <soc/smbus.h>
26 static void pch_log_gpio_gpe(u32 gpe0_sts
, u32 gpe0_en
, int start
)
32 for (i
= 0; i
<= 31; i
++) {
33 if (gpe0_sts
& (1 << i
))
34 elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO
, i
+ start
);
38 static void pch_log_wake_source(struct chipset_power_state
*ps
)
41 if (ps
->pm1_sts
& PWRBTN_STS
)
42 elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN
, 0);
45 if (ps
->pm1_sts
& RTC_STS
)
46 elog_add_event_wake(ELOG_WAKE_SOURCE_RTC
, 0);
48 /* PCI Express (TODO: determine wake device) */
49 if (ps
->pm1_sts
& PCIEXPWAK_STS
)
50 elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE
, 0);
53 if (ps
->gpe0_sts
[GPE0_A
] & CSE_PME_STS
)
54 elog_add_event_wake(ELOG_WAKE_SOURCE_PME
, 0);
57 if (ps
->gpe0_sts
[GPE0_A
] & XHCI_PME_STS
)
58 pch_xhci_update_wake_event(soc_get_xhci_usb_info());
61 if (ps
->gpe0_sts
[GPE0_A
] & SMB_WAK_STS
)
62 elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS
, 0);
64 /* ACPI Wake Event - Log prev sleep state only if it was not S0. */
65 if (ps
->prev_sleep_state
!= ACPI_S0
)
66 elog_add_event_byte(ELOG_TYPE_ACPI_WAKE
, ps
->prev_sleep_state
);
68 /* Log GPIO events in set A-D */
69 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE0_A
], ps
->gpe0_en
[GPE0_A
], 0);
70 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE0_B
], ps
->gpe0_en
[GPE0_B
], 32);
71 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE0_C
], ps
->gpe0_en
[GPE0_C
], 64);
72 pch_log_gpio_gpe(ps
->gpe0_sts
[GPE0_D
], ps
->gpe0_en
[GPE0_D
], 96);
75 static void pch_log_power_and_resets(struct chipset_power_state
*ps
)
78 if (ps
->gen_pmcon1
& RPS
)
79 elog_add_event(ELOG_TYPE_RTC_RESET
);
82 if (ps
->gen_pmcon1
& WARM_RESET_STS
)
83 elog_add_event(ELOG_TYPE_SYSTEM_RESET
);
86 if (ps
->prev_sleep_state
!= ACPI_S3
&&
87 ps
->tco1_sts
& TCO_TIMEOUT
)
88 elog_add_event(ELOG_TYPE_TCO_RESET
);
90 /* Power Button Override */
91 if (ps
->pm1_sts
& PRBTNOR_STS
)
92 elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE
);
96 void pch_log_state(void)
98 struct chipset_power_state
*ps
= cbmem_find(CBMEM_ID_POWER_STATE
);
102 "Not logging power state information. "
103 "Power state not found in cbmem.\n");
107 /* Power and Reset */
108 pch_log_power_and_resets(ps
);
111 if (ps
->prev_sleep_state
> ACPI_S0
)
112 pch_log_wake_source(ps
);
115 void elog_gsmi_cb_platform_log_wake_source(void)
117 struct chipset_power_state ps
;
119 pmc_fill_pm_reg_info(&ps
);
120 pch_log_wake_source(&ps
);