From 063c87358880ac911764b5a8fe4cdf09003278e1 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Mon, 28 Oct 2013 11:24:53 -0500 Subject: rambi: add chromeos EC support As rambi has the ChromeOS EC on it the EC needs to be configured properly. Do this along with updating the ChromeOS support for passing on write protect state, recovery mode and developer mode. BUG=chrome-os-partner:23387 BRANCH=None TEST=Built and booted to depthcharge. EC software sync appears to work correctly. Additionaly, 'mainboard_ec_init' appears in the console output. Change-Id: I40c5c9410b4acaba662c2b18b261dd4514a7410a Signed-off-by: Aaron Durbin Reviewed-on: https://chromium-review.googlesource.com/174714 Reviewed-by: Duncan Laurie Reviewed-on: http://review.coreboot.org/4905 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Ronald G. Minnich --- src/mainboard/google/rambi/Kconfig | 3 ++ src/mainboard/google/rambi/Makefile.inc | 1 + src/mainboard/google/rambi/chromeos.c | 64 +++++++++++++++++++++++++------- src/mainboard/google/rambi/ec.c | 52 ++++++++++++++++++++++++++ src/mainboard/google/rambi/ec.h | 65 +++++++++++++++++++++++++++++++++ src/mainboard/google/rambi/mainboard.c | 7 ++++ 6 files changed, 178 insertions(+), 14 deletions(-) create mode 100644 src/mainboard/google/rambi/ec.c create mode 100644 src/mainboard/google/rambi/ec.h (limited to 'src/mainboard') diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index 3a31c92736..00af512571 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -4,6 +4,9 @@ config BOARD_SPECIFIC_OPTIONS def_bool y select ARCH_X86 select SOC_INTEL_BAYTRAIL + select EC_GOOGLE_CHROMEEC + select EC_SOFTWARE_SYNC + select VIRTUAL_DEV_SWITCH select ENABLE_BUILTIN_COM1 select BOARD_ROMSIZE_KB_8192 select HAVE_ACPI_TABLES diff --git a/src/mainboard/google/rambi/Makefile.inc b/src/mainboard/google/rambi/Makefile.inc index 98e566be5c..77b2f2cb73 100644 --- a/src/mainboard/google/rambi/Makefile.inc +++ b/src/mainboard/google/rambi/Makefile.inc @@ -22,5 +22,6 @@ subdirs-y += spd romstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_CHROMEOS) += gpio.c +ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c diff --git a/src/mainboard/google/rambi/chromeos.c b/src/mainboard/google/rambi/chromeos.c index 2681b3a495..f6f13edc24 100644 --- a/src/mainboard/google/rambi/chromeos.c +++ b/src/mainboard/google/rambi/chromeos.c @@ -22,10 +22,15 @@ #include #include #include +#include -/* Compile-time settings for developer and recovery mode. */ -#define DEV_MODE_SETTING 1 -#define REC_MODE_SETTING 0 +#if CONFIG_EC_GOOGLE_CHROMEEC +#include "ec.h" +#include +#endif + +/* The WP status pin lives on GPIO_SSUS_6 which is pad 36 in the SUS well. */ +#define WP_STATUS_PAD 36 #ifndef __PRE_RAM__ #include @@ -34,11 +39,23 @@ #define ACTIVE_LOW 0 #define ACTIVE_HIGH 1 -static void fill_lb_gpio(struct lb_gpio *gpio, int polarity, +static int get_lid_switch(void) +{ +#if CONFIG_EC_GOOGLE_CHROMEEC + u8 ec_switches = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES); + + return !!(ec_switches & EC_SWITCH_LID_OPEN); +#else + /* Default to force open. */ + return 1; +#endif +} + +static void fill_lb_gpio(struct lb_gpio *gpio, int port, int polarity, const char *name, int force) { memset(gpio, 0, sizeof(*gpio)); - gpio->port = -1; + gpio->port = port; gpio->polarity = polarity; if (force >= 0) gpio->value = force; @@ -53,27 +70,46 @@ void fill_lb_gpios(struct lb_gpios *gpios) gpios->count = GPIO_COUNT; gpio = gpios->gpios; - fill_lb_gpio(gpio++, ACTIVE_HIGH, "write protect", 0); - fill_lb_gpio(gpio++, ACTIVE_HIGH, "recovery", REC_MODE_SETTING); - fill_lb_gpio(gpio++, ACTIVE_HIGH, "developer", DEV_MODE_SETTING); - fill_lb_gpio(gpio++, ACTIVE_HIGH, "lid", 1); // force open - fill_lb_gpio(gpio++, ACTIVE_HIGH, "power", 0); - fill_lb_gpio(gpio++, ACTIVE_HIGH, "oprom", oprom_is_loaded); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "write protect", + get_write_protect_state()); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery", + get_recovery_mode_switch()); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer", + get_developer_mode_switch()); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "lid", get_lid_switch()); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "power", 0); + fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "oprom", oprom_is_loaded); } #endif int get_developer_mode_switch(void) { - return DEV_MODE_SETTING; + return 0; } int get_recovery_mode_switch(void) { - return REC_MODE_SETTING; +#if CONFIG_EC_GOOGLE_CHROMEEC + u8 ec_switches = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES); + u32 ec_events; + + /* If a switch is set, we don't need to look at events. */ + if (ec_switches & (EC_SWITCH_DEDICATED_RECOVERY)) + return 1; + + /* Else check if the EC has posted the keyboard recovery event. */ + ec_events = google_chromeec_get_events_b(); + + return !!(ec_events & + EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY)); +#else + return 0; +#endif } int get_write_protect_state(void) { - return 0; + /* WP is enabled when the pin is reading high. */ + return ssus_get_gpio(WP_STATUS_PAD); } diff --git a/src/mainboard/google/rambi/ec.c b/src/mainboard/google/rambi/ec.c new file mode 100644 index 0000000000..0919f0feec --- /dev/null +++ b/src/mainboard/google/rambi/ec.c @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "ec.h" + +void mainboard_ec_init(void) +{ + printk(BIOS_DEBUG, "mainboard_ec_init\n"); + post_code(0xf0); + + /* Restore SCI event mask on resume. */ + if (acpi_slp_type == 3) { + google_chromeec_log_events(MAINBOARD_EC_LOG_EVENTS | + MAINBOARD_EC_S3_WAKE_EVENTS); + + /* Disable SMI and wake events */ + google_chromeec_set_smi_mask(0); + + /* Clear pending events */ + while (google_chromeec_get_event() != 0); + google_chromeec_set_sci_mask(MAINBOARD_EC_SCI_EVENTS); + } else { + google_chromeec_log_events(MAINBOARD_EC_LOG_EVENTS | + MAINBOARD_EC_S5_WAKE_EVENTS); + } + + /* Clear wake events, these are enabled on entry to sleep */ + google_chromeec_set_wake_mask(0); + + post_code(0xf1); +} diff --git a/src/mainboard/google/rambi/ec.h b/src/mainboard/google/rambi/ec.h new file mode 100644 index 0000000000..c55a504564 --- /dev/null +++ b/src/mainboard/google/rambi/ec.h @@ -0,0 +1,65 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAINBOARD_EC_H +#define MAINBOARD_EC_H + +#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# */ + +#define MAINBOARD_EC_SCI_EVENTS \ + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_THRESHOLD) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_OVERLOAD) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_START) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_STOP) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_CHARGER)) + +#define MAINBOARD_EC_SMI_EVENTS \ + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED)) + +/* EC can wake from S5 with lid or power button */ +#define MAINBOARD_EC_S5_WAKE_EVENTS \ + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON)) + +/* EC can wake from S3 with lid or power button or key press */ +#define MAINBOARD_EC_S3_WAKE_EVENTS \ + (MAINBOARD_EC_S5_WAKE_EVENTS |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEY_PRESSED)) + +/* Log EC wake events plus EC shutdown events */ +#define MAINBOARD_EC_LOG_EVENTS \ + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_SHUTDOWN) |\ + EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_SHUTDOWN)) + +#ifndef __ACPI__ +extern void mainboard_ec_init(void); +#endif + +#endif diff --git a/src/mainboard/google/rambi/mainboard.c b/src/mainboard/google/rambi/mainboard.c index d2bfea3e66..8c5b66608b 100644 --- a/src/mainboard/google/rambi/mainboard.c +++ b/src/mainboard/google/rambi/mainboard.c @@ -33,6 +33,7 @@ #include #include #include +#include "ec.h" void mainboard_suspend_resume(void) { @@ -126,11 +127,17 @@ static int int15_handler(void) } #endif +static void mainboard_init(device_t dev) +{ + mainboard_ec_init(); +} + // mainboard_enable is executed as first thing after // enumerate_buses(). static void mainboard_enable(device_t dev) { + dev->ops->init = mainboard_init; #if CONFIG_VGA_ROM_RUN /* Install custom int15 handler for VGA OPROM */ mainboard_interrupt_handlers(0x15, &int15_handler); -- cgit v1.2.3