diff --git a/src/mainboard/google/rambi/ec.h b/src/mainboard/google/rambi/ec.h index c55a504564..bd98b2acbc 100644 --- a/src/mainboard/google/rambi/ec.h +++ b/src/mainboard/google/rambi/ec.h @@ -22,9 +22,10 @@ #include -/* TODO(adurbin): Need to figure out how to handle 2 sets of GPIO banks. */ -#define EC_SCI_GPI 0 /* GPIO_SC_0 is EC_SCI# */ -#define EC_SMI_GPI 7 /* GPIO_SSUS_7 is EC_SMI# */ +/* GPIO_S0_000 is EC_SCI#, but it is bit 24 in GPE_STS */ +#define EC_SCI_GPI 24 +/* GPIO_S5_07 is EC_SMI#, but it is bit 23 in GPE_STS and ALT_GPIO_SMI. */ +#define EC_SMI_GPI 23 #define MAINBOARD_EC_SCI_EVENTS \ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |\ diff --git a/src/mainboard/google/rambi/mainboard_smi.c b/src/mainboard/google/rambi/mainboard_smi.c index 0571baf32f..ac5c841030 100644 --- a/src/mainboard/google/rambi/mainboard_smi.c +++ b/src/mainboard/google/rambi/mainboard_smi.c @@ -20,7 +20,13 @@ #include #include #include +#include + +#include +#include "ec.h" + #include +#include int mainboard_io_trap_handler(int smif) { @@ -43,11 +49,81 @@ int mainboard_io_trap_handler(int smif) return 1; } +static uint8_t mainboard_smi_ec(void) +{ + uint8_t cmd = google_chromeec_get_event(); + uint16_t pmbase = get_pmbase(); + uint32_t pm1_cnt; + +#if CONFIG_ELOG_GSMI + /* Log this event */ + if (cmd) + elog_add_event_byte(ELOG_TYPE_EC_EVENT, cmd); +#endif + + switch (cmd) { + case EC_HOST_EVENT_LID_CLOSED: + printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n"); + + /* Go to S5 */ + pm1_cnt = inl(pmbase + PM1_CNT); + pm1_cnt |= SLP_TYP | (SLP_TYP_S5 << SLP_TYP_SHIFT); + outl(pm1_cnt, pmbase + PM1_CNT); + break; + } + + return cmd; +} + +void mainboard_smi_gpi(uint32_t gpi_sts) +{ + if (gpi_sts & (1 << EC_SMI_GPI)) { + /* Process all pending events */ + while (mainboard_smi_ec() != 0); + } +} + +void mainboard_smi_sleep(uint8_t slp_typ) +{ + /* Disable USB charging if required */ + switch (slp_typ) { + case 3: + if (smm_get_gnvs()->s3u0 == 0) + google_chromeec_set_usb_charge_mode( + 0, USB_CHARGE_MODE_DISABLED); + if (smm_get_gnvs()->s3u1 == 0) + google_chromeec_set_usb_charge_mode( + 1, USB_CHARGE_MODE_DISABLED); + + /* Enable wake events */ + google_chromeec_set_wake_mask(MAINBOARD_EC_S3_WAKE_EVENTS); + break; + case 5: + if (smm_get_gnvs()->s5u0 == 0) + google_chromeec_set_usb_charge_mode( + 0, USB_CHARGE_MODE_DISABLED); + if (smm_get_gnvs()->s5u1 == 0) + google_chromeec_set_usb_charge_mode( + 1, USB_CHARGE_MODE_DISABLED); + + /* Enable wake events */ + google_chromeec_set_wake_mask(MAINBOARD_EC_S5_WAKE_EVENTS); + break; + } + + /* Disable SCI and SMI events */ + google_chromeec_set_smi_mask(0); + google_chromeec_set_sci_mask(0); + + /* Clear pending events that may trigger immediate wake */ + while (google_chromeec_get_event() != 0); +} + #define APMC_FINALIZE 0xcb static int mainboard_finalized = 0; -int mainboard_smi_apmc(u8 apmc) +int mainboard_smi_apmc(uint8_t apmc) { switch (apmc) { case APMC_FINALIZE: @@ -58,6 +134,18 @@ int mainboard_smi_apmc(u8 apmc) mainboard_finalized = 1; break; + case APM_CNT_ACPI_ENABLE: + google_chromeec_set_smi_mask(0); + /* Clear all pending events */ + while (google_chromeec_get_event() != 0); + google_chromeec_set_sci_mask(MAINBOARD_EC_SCI_EVENTS); + break; + case APM_CNT_ACPI_DISABLE: + google_chromeec_set_sci_mask(0); + /* Clear all pending events */ + while (google_chromeec_get_event() != 0); + google_chromeec_set_smi_mask(MAINBOARD_EC_SMI_EVENTS);; + break; } return 0; }