From f0ba2259b84c1f5083dab14925351ddf8b245e11 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Tue, 25 Oct 2016 20:03:56 -0700 Subject: skylake: Prepare GPE for use in bootblock Export the pmc_gpe_init() function from pmc.c to pmutil.c so it can be used in bootblock, and then call it from there to initialize any GPEs for use in firmware. BUG=chrome-os-partner:58666 TEST=test working GPE as TPM interrupt on skylake board Change-Id: I6b4f7d0aa689db42dc455075f84ab5694e8c9661 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/17135 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Paul Menzel --- src/soc/intel/skylake/bootblock/pch.c | 3 ++ src/soc/intel/skylake/include/soc/pci_devs.h | 2 +- src/soc/intel/skylake/include/soc/pm.h | 3 ++ src/soc/intel/skylake/pmc.c | 39 +--------------------- src/soc/intel/skylake/pmutil.c | 48 ++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 39 deletions(-) (limited to 'src/soc/intel/skylake') diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c index 57b5fedb24..371dd63685 100644 --- a/src/soc/intel/skylake/bootblock/pch.c +++ b/src/soc/intel/skylake/bootblock/pch.c @@ -301,6 +301,9 @@ void pch_early_init(void) /* Program SMBUS_BASE_ADDRESS and Enable it */ enable_smbus(); + /* Set up GPE configuration */ + pmc_gpe_init(); + soc_config_rtc(); enable_heci(); diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 476e2c6a56..974f1d8e19 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -23,7 +23,7 @@ #define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0) #define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func) -#if ENV_RAMSTAGE +#if ENV_RAMSTAGE && !defined(__SIMPLE_DEVICE__) #include #include #define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot)) diff --git a/src/soc/intel/skylake/include/soc/pm.h b/src/soc/intel/skylake/include/soc/pm.h index 235ad898e0..ede3efb982 100644 --- a/src/soc/intel/skylake/include/soc/pm.h +++ b/src/soc/intel/skylake/include/soc/pm.h @@ -186,6 +186,9 @@ uint16_t smbus_tco_regs(void); /* Set the DISB after DRAM init */ void pmc_set_disb(void); +/* Initialize GPEs */ +void pmc_gpe_init(void); + static inline int deep_s3_enabled(void) { uint32_t deep_s3_pol; diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c index fd04287f37..23a289b2bd 100644 --- a/src/soc/intel/skylake/pmc.c +++ b/src/soc/intel/skylake/pmc.c @@ -129,42 +129,6 @@ static void pch_rtc_init(void) cmos_init(rtc_failed); } -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; @@ -172,7 +136,6 @@ static void pch_power_options(void) /*PMC Controller Device 0x1F, Func 02*/ device_t dev = PCH_DEV_PMC; /* Get the chip configuration */ - config_t *config = dev->chip_info; int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; /* @@ -207,7 +170,7 @@ static void pch_power_options(void) printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up GPE configuration. */ - pmc_gpe_init(config); + pmc_gpe_init(); } static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable) diff --git a/src/soc/intel/skylake/pmutil.c b/src/soc/intel/skylake/pmutil.c index 904be5c2a0..7d83e9f240 100644 --- a/src/soc/intel/skylake/pmutil.c +++ b/src/soc/intel/skylake/pmutil.c @@ -19,6 +19,8 @@ * and the differences between PCH variants. */ +#define __SIMPLE_DEVICE__ + #include #include #include @@ -27,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +37,7 @@ #include #include #include +#include "chip.h" /* Print status bits with descriptive names */ static void print_status_bits(u32 status, const char *bit_names[]) @@ -465,3 +469,47 @@ void poweroff(void) if (!ENV_SMM) halt(); } + +void pmc_gpe_init(void) +{ + ROMSTAGE_CONST struct soc_intel_skylake_config *config; + ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC); + 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); + + /* Look up the device in devicetree */ + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n"); + return; + } + config = dev->chip_info; + pmc_regs = pmc_mmio_regs(); + + /* Route the GPIOs to the GPE0 block. Determine that all values + * are different, and if they aren't use the reset values. */ + gpio_cfg = 0; + 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); +} -- cgit v1.2.3