Shaunak Saha (shaunak.saha@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15324
-gerrit
commit 854215e75ef14fff23b5bbc4fcc885e124e1bd26 Author: Shaunak Saha shaunak.saha@intel.com Date: Tue Jun 7 02:06:28 2016 -0700
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 shaunak.saha@intel.com --- src/soc/intel/apollolake/chip.c | 6 +- src/soc/intel/apollolake/chip.h | 6 ++ src/soc/intel/apollolake/gpio.c | 79 ++++++++++++++++++++++++ src/soc/intel/apollolake/include/soc/gpio.h | 13 ++++ src/soc/intel/apollolake/include/soc/gpio_defs.h | 21 +++++++ src/soc/intel/apollolake/include/soc/pm.h | 8 ++- 6 files changed, 130 insertions(+), 3 deletions(-)
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index af3310e..02875b0 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -33,6 +33,7 @@ #include <soc/pci_devs.h> #include <spi-generic.h> #include <soc/pm.h> +#include <soc/gpio.h>
#include "chip.h"
@@ -275,7 +276,6 @@ struct chip_operations soc_intel_apollolake_ops = {
static void fsp_notify_dummy(void *arg) { - enum fsp_notify_phase ph = (enum fsp_notify_phase) arg; enum fsp_status ret;
@@ -285,8 +285,10 @@ static void fsp_notify_dummy(void *arg) fsp_handle_reset(ret); } /* Call END_OF_FIRMWARE Notify after READY_TO_BOOT Notify */ - if (ph == READY_TO_BOOT) + if (ph == READY_TO_BOOT) { + pmc_gpe_init(); fsp_notify_dummy((void *)END_OF_FIRMWARE); + } }
BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT, fsp_notify_dummy, diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h index ef82c53..4446ac5 100644 --- a/src/soc/intel/apollolake/chip.h +++ b/src/soc/intel/apollolake/chip.h @@ -18,6 +18,8 @@ #ifndef _SOC_APOLLOLAKE_CHIP_H_ #define _SOC_APOLLOLAKE_CHIP_H_
+#include <soc/gpio_defs.h> + #define CLKREQ_DISABLED 0xf
/* Serial IRQ control. SERIRQ_QUIET is the default (0). */ @@ -79,6 +81,10 @@ struct soc_intel_apollolake_config {
/* Integrated Sensor Hub */ uint8_t integrated_sensor_hub_enable; + + uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */ + uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */ + uint8_t gpe0_dw3; /* GPE0_127_96 STS/EN */ };
#endif /* _SOC_APOLLOLAKE_CHIP_H_ */ diff --git a/src/soc/intel/apollolake/gpio.c b/src/soc/intel/apollolake/gpio.c index d0ef648..ce32592 100644 --- a/src/soc/intel/apollolake/gpio.c +++ b/src/soc/intel/apollolake/gpio.c @@ -19,6 +19,9 @@ #include <gpio.h> #include <soc/gpio.h> #include <soc/iosf.h> +#include <soc/pm.h> +#include <soc/pci_devs.h> +#include "chip.h"
/* This list must be in order, from highest pad numbers, to lowest pad numbers*/ static const struct pad_community { @@ -132,3 +135,79 @@ const char *gpio_acpi_path(gpio_t gpio_num)
return NULL; } + +#if ENV_RAMSTAGE + +void pmc_gpe_init(void) +{ + uint32_t gpio_cfg = 0; + uint32_t gpio_cfg_reg; + struct soc_intel_apollolake_config *config; + + struct device *dev = NB_DEV_ROOT; + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n"); + return; + } + config = dev->chip_info; + + uintptr_t pmc_bar = get_pmc_mmio_bar(); + + const uint32_t gpio_cfg_mask = + (GPE0_DWX_MASK << GPE0_DW1_SHIFT) | + (GPE0_DWX_MASK << GPE0_DW2_SHIFT) | + (GPE0_DWX_MASK << GPE0_DW3_SHIFT); + + /* Route the GPIOs to the GPE0 block. Determine that all values + * are different, and if they aren't use the reset values. + * DW0 is reserved/unused */ + if (config->gpe0_dw1 == config->gpe0_dw2 || + config->gpe0_dw2 == config->gpe0_dw3) { + printk(BIOS_INFO, "PMC: Using default GPE route.\n"); + gpio_cfg = read32((void *)pmc_bar + GPIO_GPE_CFG); + } else { + gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT; + gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT; + gpio_cfg |= (uint32_t)config->gpe0_dw3 << GPE0_DW3_SHIFT; + } + + gpio_cfg_reg = read32((void *)pmc_bar + GPIO_GPE_CFG) & ~gpio_cfg_mask; + gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask; + + write32((void *)pmc_bar + GPIO_GPE_CFG, gpio_cfg_reg); + + /* Set the routes in the GPIO communities as well. */ + gpio_route_gpe(); +} + +void gpio_route_gpe(void) +{ + int i; + uint32_t misccfg_mask; + uint32_t misccfg_value; + uint32_t misccfg_gpe0_dw0; /* ACPI GPE0[31:0] */ + uint32_t misccfg_gpe0_dw1; /* ACPI GPE0[63:32] */ + uint32_t misccfg_gpe0_dw2; /* ACPI GPE0[95:64] */ + + /* Set the group here for community specific MISCCFG register */ + misccfg_gpe0_dw0 = GPP_7; /* GPE0b */ + misccfg_gpe0_dw1 = GPP_0; /* GPE0c */ + misccfg_gpe0_dw2 = GPP_0; /* GPE0d */ + + /* Program GPIO_MISCCFG */ + misccfg_mask = (uint32_t) ~(MISCCFG_GPE0_DW2_MASK | + MISCCFG_GPE0_DW1_MASK | + MISCCFG_GPE0_DW0_MASK); + misccfg_value = (uint32_t)((misccfg_gpe0_dw2 << MISCCFG_GPE0_DW2_SHIFT) + | (misccfg_gpe0_dw1 << MISCCFG_GPE0_DW1_SHIFT) + | (misccfg_gpe0_dw0 << MISCCFG_GPE0_DW0_SHIFT)); + + for (i = 0; i < ARRAY_SIZE(gpio_communities); i++) { + const struct pad_community *comm = &gpio_communities[i]; + + iosf_write(comm->port, GPIO_MISCCFG, ((iosf_read(comm->port, + GPIO_MISCCFG) & misccfg_mask) | misccfg_value)); + } +} + +#endif diff --git a/src/soc/intel/apollolake/include/soc/gpio.h b/src/soc/intel/apollolake/include/soc/gpio.h index c9d32cc..487dd93 100644 --- a/src/soc/intel/apollolake/include/soc/gpio.h +++ b/src/soc/intel/apollolake/include/soc/gpio.h @@ -99,5 +99,18 @@ struct pad_config { void gpio_configure_pad(const struct pad_config *cfg); void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads);
+void pmc_gpe_init(void); + +/* + * Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted + * as the packed configuration for GPE0_DW[2:0]. This basically sets the + * MISCCFG register bits: + * dw0 = gpe0_route[11:8] + * dw1 = gpe0_route[15:12] + * dw2 = gpe0_route[19:16]. + */ +void gpio_route_gpe(void); + #endif /* __ACPI__ */ + #endif /* _SOC_APOLLOLAKE_GPIO_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/gpio_defs.h b/src/soc/intel/apollolake/include/soc/gpio_defs.h index 30c4bdb..d0372ea 100644 --- a/src/soc/intel/apollolake/include/soc/gpio_defs.h +++ b/src/soc/intel/apollolake/include/soc/gpio_defs.h @@ -23,6 +23,27 @@ #ifndef _SOC_APOLLOLAKE_GPIO_DEFS_H_ #define _SOC_APOLLOLAKE_GPIO_DEFS_H_
+/* + * There are 8 GPIO groups. GPP_0 -> GPP_8 (Group 3 is not present) + */ +#define GPP_0 0 /* SOUTHWEST GPIO # 0 ~ 31 belong to GROUP0 */ +#define GPP_1 1 /* SOUTHWEST GPIO # 32 ~ 42 belong to GROUP1 */ +#define GPP_2 2 /* WEST GPIO # 0 ~ 25 belong to GROUP2 */ +#define GPP_4 4 /* NORTHWEST GPIO # 0 ~ 17 belong to GROUP4 */ +#define GPP_5 5 /* NORTHWEST GPIO # 32 ~ 63 belong to GROUP5, except # 52 and 60 */ +#define GPP_6 6 /* NORTHWEST GPIO # 64 ~ 76 belong to GROUP6 */ +#define GPP_7 7 /* NORTH GPIO # 0 ~ 31 belong to GROUP7 */ +#define GPP_8 8 /* NORTH GPIO # 32 ~ 61 belong to GROUP8 */ + +#define GPIO_MISCCFG 0x10 /* Miscellaneous Configuration */ + +#define MISCCFG_GPE0_DW0_SHIFT 8 +#define MISCCFG_GPE0_DW0_MASK (0xf << MISCCFG_GPE0_DW0_SHIFT) +#define MISCCFG_GPE0_DW1_SHIFT 12 +#define MISCCFG_GPE0_DW1_MASK (0xf << MISCCFG_GPE0_DW1_SHIFT) +#define MISCCFG_GPE0_DW2_SHIFT 16 +#define MISCCFG_GPE0_DW2_MASK (0xf << MISCCFG_GPE0_DW2_SHIFT) + #define PAD_CFG0_TX_STATE (1 << 0) #define PAD_CFG0_RX_STATE (1 << 1) #define PAD_CFG0_TX_DISABLE (1 << 8) diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h index 3da7dd0..0f1e36a 100644 --- a/src/soc/intel/apollolake/include/soc/pm.h +++ b/src/soc/intel/apollolake/include/soc/pm.h @@ -129,10 +129,16 @@ # define RPS (1 << 2) #define GEN_PMCON3 0x1028 #define ETR 0x1048 +#define GPIO_GPE_CFG 0x1050 + +#define GPE0_DWX_MASK 0xf +#define GPE0_DW1_SHIFT 4 +#define GPE0_DW2_SHIFT 8 +#define GPE0_DW3_SHIFT 12 + # define CF9_LOCK (1 << 31) # define CF9_GLB_RST (1 << 20)
- /* Generic sleep state types */ #define SLEEP_STATE_S0 0 #define SLEEP_STATE_S3 3