Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4957
-gerrit
commit e887be80be3a3cb14361e5932bbf1a7ad25fe4ba Author: Aaron Durbin adurbin@chromium.org Date: Mon Nov 11 12:09:28 2013 -0600
baytrail: add support for routing gpio pins to smi/sci
In order for gpio pins to trigger an smi/sci the GPIO_ROUT register needs to be set accordingly. For SMI, the ALT_GPIO_SMI register needs to be enabled for each gpio as well.
The first 8 gpios from the suspend and core well are the only gpios that can trigger an SMI or SCI. The settings for the GPIO_ROUT and ALT_GPIO_SMI register are not commited until the SMM settings are enabled in the southcluster.
BUG=chrome-os-partner:23505 BRANCH=None TEST=Built and booted. Manually triggered SCI by changing GPE0a_EN and toggling PCH_WAKE_L on the EC console.
Change-Id: Id79b70084edc39fc047475e984494c224bd75d6d Signed-off-by: Aaron Durbin adurbin@chromium.org Reviewed-on: https://chromium-review.googlesource.com/176390 Reviewed-by: Duncan Laurie dlaurie@chromium.org --- src/soc/intel/baytrail/baytrail/gpio.h | 20 +++++++++++++++++ src/soc/intel/baytrail/baytrail/pmc.h | 5 +++++ src/soc/intel/baytrail/baytrail/smm.h | 2 ++ src/soc/intel/baytrail/gpio.c | 28 +++++++++++++++++++++++- src/soc/intel/baytrail/smm.c | 39 ++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/src/soc/intel/baytrail/baytrail/gpio.h b/src/soc/intel/baytrail/baytrail/gpio.h index 8d7925b..8c90c89 100644 --- a/src/soc/intel/baytrail/baytrail/gpio.h +++ b/src/soc/intel/baytrail/baytrail/gpio.h @@ -204,6 +204,25 @@ #define GPIO_FUNC5 GPIO_FUNC(5, PULL_DISABLE, 10K) #define GPIO_FUNC6 GPIO_FUNC(6, PULL_DISABLE, 10K)
+/* ACPI GPIO routing. Assume everything is externally pulled and negative edge + * triggered. */ +#define GPIO_ACPI_SCI \ + { .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT | PAD_FUNC0, \ + .pad_conf1 = PAD_CONFIG1_DEFAULT, \ + .pad_val = PAD_VAL_INPUT_ENABLE, \ + .use_sel = GPIO_USE_LEGACY, \ + .io_sel = GPIO_DIR_INPUT, \ + .tne = 1, \ + .wake_en = 1, } +#define GPIO_ACPI_SMI \ + { .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT | PAD_FUNC0, \ + .pad_conf1 = PAD_CONFIG1_DEFAULT, \ + .pad_val = PAD_VAL_INPUT_ENABLE, \ + .use_sel = GPIO_USE_LEGACY, \ + .io_sel = GPIO_DIR_INPUT, \ + .tne = 1, \ + .smi = 1} + /* End marker */ #define GPIO_LIST_END 0xffffffff
@@ -227,6 +246,7 @@ struct soc_gpio_map { u8 tpe : 1; u8 tne : 1; u8 wake_en : 1; + u8 smi : 1; } __attribute__ ((packed));
struct soc_gpio_config { diff --git a/src/soc/intel/baytrail/baytrail/pmc.h b/src/soc/intel/baytrail/baytrail/pmc.h index 1a7588c..f314d1d 100644 --- a/src/soc/intel/baytrail/baytrail/pmc.h +++ b/src/soc/intel/baytrail/baytrail/pmc.h @@ -68,6 +68,11 @@ # define USH_SS_PHY_DIS (1 << 2) # define OTG_SS_PHY_DIS (1 << 1) # define SMBUS_DIS (1 << 0) +#define GPIO_ROUT 0x58 +# define ROUTE_MASK 3 +# define ROUTE_NONE 0 +# define ROUTE_SMI 1 +# define ROUTE_SCI 2
/* IO Mapped registers behind ACPI_BASE_ADDRESS */ #define PM1_STS 0x00 diff --git a/src/soc/intel/baytrail/baytrail/smm.h b/src/soc/intel/baytrail/baytrail/smm.h index 19a0695..e00944d 100644 --- a/src/soc/intel/baytrail/baytrail/smm.h +++ b/src/soc/intel/baytrail/baytrail/smm.h @@ -34,8 +34,10 @@ static inline int smm_region_size(void) void *smm_region_start(void);
#if !defined(__PRE_RAM__) && !defined(__SMM___) +#include <stdint.h> void southcluster_smm_clear_state(void); void southcluster_smm_enable_smi(void); +void southcluster_smm_save_gpio_route(uint32_t route); #endif
#endif /* _BAYTRAIL_SMM_H_ */ diff --git a/src/soc/intel/baytrail/gpio.c b/src/soc/intel/baytrail/gpio.c index 2916c99..824ed65 100644 --- a/src/soc/intel/baytrail/gpio.c +++ b/src/soc/intel/baytrail/gpio.c @@ -17,9 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#include <baytrail/gpio.h> #include <device/pci.h> #include <console/console.h> +#include <baytrail/gpio.h> +#include <baytrail/pmc.h> +#include <baytrail/smm.h>
/* GPIO-to-Pad LUTs */ static const u8 gpncore_gpio_to_pad[GPNCORE_COUNT] = @@ -154,12 +156,36 @@ static void setup_gpios(const struct soc_gpio_map *gpios, } }
+static void setup_gpio_route(const struct soc_gpio_map *sus, + const struct soc_gpio_map *core) +{ + uint32_t route_reg = 0; + int i; + + for (i = 0; i < 8; i++) { + /* SMI takes precedence and wake_en implies SCI. */ + if (sus[i].smi) { + route_reg |= ROUTE_SMI << (2 * i); + } else if (sus[i].wake_en) { + route_reg |= ROUTE_SCI << (2 * i); + } + + if (core[i].smi) { + route_reg |= ROUTE_SMI << (2 * (i + 8)); + } else if (core[i].wake_en) { + route_reg |= ROUTE_SCI << (2 * (i + 8)); + } + } + southcluster_smm_save_gpio_route(route_reg); +} + void setup_soc_gpios(struct soc_gpio_config *config) { if (config) { setup_gpios(config->ncore, &gpncore_bank); setup_gpios(config->score, &gpscore_bank); setup_gpios(config->ssus, &gpssus_bank); + setup_gpio_route(config->ssus, config->score); } }
diff --git a/src/soc/intel/baytrail/smm.c b/src/soc/intel/baytrail/smm.c index 124f93b..1ba6246 100644 --- a/src/soc/intel/baytrail/smm.c +++ b/src/soc/intel/baytrail/smm.c @@ -27,9 +27,19 @@ #include <cpu/x86/smm.h> #include <string.h>
+#include <baytrail/iomap.h> #include <baytrail/pmc.h> #include <baytrail/smm.h>
+/* Save the gpio route register. The settings are committed from + * southcluster_smm_enable_smi(). */ +static uint32_t gpio_route; + +void southcluster_smm_save_gpio_route(uint32_t route) +{ + gpio_route = route; +} + void southcluster_smm_clear_state(void) { uint32_t smi_en; @@ -53,13 +63,42 @@ void southcluster_smm_clear_state(void) clear_gpe_status(); }
+static void southcluster_smm_route_gpios(void) +{ + const unsigned long gpio_rout = PMC_BASE_ADDRESS + GPIO_ROUT; + const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI; + uint32_t alt_gpio_reg = 0; + uint32_t route_reg = gpio_route; + int i; + + printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg); + + /* Start the routing for the specific gpios. */ + write32(gpio_rout, route_reg); + + /* Enable SMIs for the gpios that are set to trigger the SMI. */ + for (i = 0; i < 16; i++) { + if ((route_reg & ROUTE_MASK) == ROUTE_SMI) { + alt_gpio_reg |= (1 << i); + } + route_reg >>= 2; + } + printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg); + + outl(alt_gpio_reg, alt_gpio_smi); +} + void southcluster_smm_enable_smi(void) { + printk(BIOS_DEBUG, "Enabling SMIs.\n"); /* Configure events */ enable_pm1(PWRBTN_EN | GBL_EN); disable_gpe(PME_B0_EN);
+ /* Set up the GPIO route. */ + southcluster_smm_route_gpios(); + /* Enable SMI generation: * - on TCO events * - on APMC writes (io 0xb2)