From 5b6c5a500ed416f033a22eed1d8174063ebaf143 Mon Sep 17 00:00:00 2001 From: Shaunak Saha Date: Tue, 7 Jun 2016 02:06:28 -0700 Subject: soc/intel/apollolake: Add GPE routing code This patch adds the basic framework for SCI to GPE routing code. BUG = chrome-os-partner:53438 TEST = Toogle pch_sci_l from ec console using gpioset command and see that the sci counter increases in /sys/firmware/acpi/interrupt and also 9 in /proc/interrupts. Change-Id: I3b3198276530bf6513d94e9bea02ab9751212adf Signed-off-by: Shaunak Saha Reviewed-on: https://review.coreboot.org/15324 Reviewed-by: Aaron Durbin Tested-by: build bot (Jenkins) --- src/soc/intel/apollolake/gpio.c | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'src/soc/intel/apollolake/gpio.c') diff --git a/src/soc/intel/apollolake/gpio.c b/src/soc/intel/apollolake/gpio.c index ac0d83b810..525c972b5c 100644 --- a/src/soc/intel/apollolake/gpio.c +++ b/src/soc/intel/apollolake/gpio.c @@ -19,6 +19,7 @@ #include #include #include +#include /* This list must be in order, from highest pad numbers, to lowest pad numbers*/ static const struct pad_community { @@ -150,3 +151,70 @@ uint16_t gpio_acpi_pin(gpio_t gpio_num) return gpio_num; } + +/* Helper function to map PMC register groups to tier1 sci groups */ +static int pmc_gpe_route_to_gpio(int route) +{ + switch(route) { + case PMC_GPE_SW_31_0: + return GPIO_GPE_SW_31_0; + case PMC_GPE_SW_63_32: + return GPIO_GPE_SW_63_32; + case PMC_GPE_NW_31_0: + return GPIO_GPE_NW_31_0; + case PMC_GPE_NW_63_32: + return GPIO_GPE_NW_63_32; + case PMC_GPE_NW_95_64: + return GPIO_GPE_NW_95_64; + case PMC_GPE_N_31_0: + return GPIO_GPE_N_31_0; + case PMC_GPE_N_63_32: + return GPIO_GPE_N_63_32; + case PMC_GPE_W_31_0: + return GPIO_GPE_W_31_0; + default: + return -1; + } +} + +void gpio_route_gpe(uint8_t gpe0b, uint8_t gpe0c, uint8_t gpe0d) +{ + int i; + uint32_t misccfg_mask; + uint32_t misccfg_value; + uint32_t value; + + /* Get the group here for community specific MISCCFG register. + * If any of these returns -1 then there is some error in devicetree + * where the group is probably hardcoded and does not comply with the + * PMC group defines. So we return from here and MISCFG is set to + * default. + */ + gpe0b = pmc_gpe_route_to_gpio(gpe0b); + if(gpe0b == -1) + return; + gpe0c = pmc_gpe_route_to_gpio(gpe0c); + if(gpe0c == -1) + return; + gpe0d = pmc_gpe_route_to_gpio(gpe0d); + if(gpe0d == -1) + return; + + misccfg_value = gpe0b << MISCCFG_GPE0_DW0_SHIFT; + misccfg_value |= gpe0c << MISCCFG_GPE0_DW1_SHIFT; + misccfg_value |= gpe0d << MISCCFG_GPE0_DW2_SHIFT; + + /* Program GPIO_MISCCFG */ + misccfg_mask = ~(MISCCFG_GPE0_DW2_MASK | + MISCCFG_GPE0_DW1_MASK | + MISCCFG_GPE0_DW0_MASK); + + for (i = 0; i < ARRAY_SIZE(gpio_communities); i++) { + const struct pad_community *comm = &gpio_communities[i]; + + value = iosf_read(comm->port, GPIO_MISCCFG); + value &= misccfg_mask; + value |= misccfg_value; + iosf_write(comm->port, GPIO_MISCCFG, value); + } +} -- cgit v1.2.3