diff options
Diffstat (limited to 'src/soc/intel/skylake/pmc.c')
-rw-r--r-- | src/soc/intel/skylake/pmc.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c index 2c794cabea..b6c35ebb4f 100644 --- a/src/soc/intel/skylake/pmc.c +++ b/src/soc/intel/skylake/pmc.c @@ -27,6 +27,7 @@ #include <pc80/mc146818rtc.h> #include <reg_script.h> #include <string.h> +#include <soc/gpio.h> #include <soc/iomap.h> #include <soc/pci_devs.h> #include <soc/pmc.h> @@ -147,6 +148,42 @@ static void pch_rtc_init(void) #endif } +static void pmc_gpe_init(config_t *config) +{ + uint8_t *pmc_regs; + uint32_t gpio_cfg; + uint32_t gpio_cfg_reg; + const uint32_t gpio_cfg_mask = + (GPE0_DWX_MASK << GPE0_DW0_SHIFT) | + (GPE0_DWX_MASK << GPE0_DW1_SHIFT) | + (GPE0_DWX_MASK << GPE0_DW2_SHIFT); + + pmc_regs = pmc_mmio_regs(); + gpio_cfg = 0; + + /* Route the GPIOs to the GPE0 block. Determine that all values + * are different, and if they aren't use the reset values. */ + if (config->gpe0_dw0 == config->gpe0_dw1 || + config->gpe0_dw1 == config->gpe0_dw2) { + printk(BIOS_INFO, "PMC: Using default GPE route.\n"); + gpio_cfg = read32(pmc_regs + GPIO_CFG); + } else { + gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT; + gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT; + gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT; + } + gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask; + gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask; + write32(pmc_regs + GPIO_CFG, gpio_cfg_reg); + + /* Set the routes in the GPIO communities as well. */ + gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT); + + /* Set GPE enables based on devictree. */ + enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, + config->gpe0_en_3, config->gpe0_en_4); +} + static void pch_power_options(void) { u16 reg16; @@ -187,9 +224,9 @@ static void pch_power_options(void) } pci_write_config16(dev, GEN_PMCON_B, reg16); printk(BIOS_INFO, "Set power %s after power failure.\n", state); - /* GPE setup based on device tree configuration */ - enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, - config->gpe0_en_3, config->gpe0_en_4); + + /* Set up GPE configuration. */ + pmc_gpe_init(config); /* SMI setup based on device tree configuration */ enable_alt_smi(config->ec_smi_gpio, config->alt_gp_smi_en); |