system76/common/power: Support for ESPI

This commit is contained in:
Jeremy Soller 2020-12-29 10:08:03 -07:00 committed by Jeremy Soller
parent c3fa2a27a7
commit c7827e4a7c
2 changed files with 52 additions and 7 deletions

View File

@ -14,6 +14,11 @@ enum PowerState {
extern enum PowerState power_state;
void power_on_ds5(void);
void power_on_s5(void);
void power_off_s5(void);
void power_cpu_reset(void);
void power_event(void);
#endif // _BOARD_POWER_H

View File

@ -15,6 +15,11 @@
#include <board/pnp.h>
#include <common/debug.h>
#include <ec/espi.h>
#if EC_ESPI
#include <board/espi.h>
#endif
#define GPIO_SET_DEBUG(G, V) { \
DEBUG("%s = %s\n", #G, V ? "true" : "false"); \
gpio_set(&G, V); \
@ -284,8 +289,21 @@ void power_on_s5(void) {
// Wait for SUSPWRDNACK validity
tPLT01;
// Extra wait - TODO remove
delay_ms(200);
for (int i = 0; i < 1000; i++) {
// If we reached S0, exit this loop
update_power_state();
if (power_state == POWER_STATE_S0) {
break;
}
// Check for VW changes
#if EC_ESPI
espi_event();
#endif // EC_ESPI
// Extra wait until SUSPWRDNACK is valid
delay_ms(1);
}
#endif // DEEP_SX
update_power_state();
@ -333,7 +351,7 @@ void power_off_s5(void) {
}
// This function is run when the CPU is reset
static void power_cpu_reset(void) {
void power_cpu_reset(void) {
// LPC was just reset, enable PNP devices
pnp_enable();
// Reset ACPI registers
@ -468,7 +486,11 @@ void power_event(void) {
#endif
if(rst_new && !rst_last) {
DEBUG("%02X: PLT_RST# de-asserted\n", main_cycle);
#if EC_ESPI
espi_reset();
#else // EC_ESPI
power_cpu_reset();
#endif // EC_ESPI
}
rst_last = rst_new;
@ -485,7 +507,9 @@ void power_event(void) {
#endif
#endif // HAVE_SLP_SUS_N
#if HAVE_SUSWARN_N
#if EC_ESPI
if (vw_get(&VW_SUS_PWRDN_ACK) == VWS_HIGH)
#elif HAVE_SUSWARN_N
// EC must keep VccPRIM powered if SUSPWRDNACK is de-asserted low or system
// state is S3
static bool ack_last = false;
@ -529,9 +553,25 @@ void power_event(void) {
static uint32_t last_time = 0;
uint32_t time = time_get();
if (power_state == POWER_STATE_S0) {
// CPU on, green light
gpio_set(&LED_PWR, true);
gpio_set(&LED_ACIN, false);
#if EC_ESPI
if (!gpio_get(&CPU_C10_GATE_N)) {
// Modern suspend, flashing green light
if (
(time < last_time) // overflow
||
(time >= (last_time + 1000)) // timeout
) {
gpio_set(&LED_PWR, !gpio_get(&LED_PWR));
last_time = time;
}
gpio_set(&LED_ACIN, false);
} else
#endif
{
// CPU on, green light
gpio_set(&LED_PWR, true);
gpio_set(&LED_ACIN, false);
}
} else if (power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3) {
// Suspended, flashing green light
if (