summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/google/rambi/ec.h7
-rw-r--r--src/mainboard/google/rambi/mainboard_smi.c90
2 files changed, 93 insertions, 4 deletions
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 <ec/google/chromeec/ec_commands.h>
-/* 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 <arch/io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
+#include <elog.h>
+
+#include <ec/google/chromeec/ec.h>
+#include "ec.h"
+
#include <baytrail/nvs.h>
+#include <baytrail/pmc.h>
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;
}