From 38b8bf02d82031be53b08c677f06d174d3bdbc84 Mon Sep 17 00:00:00 2001 From: Maulik V Vaghela Date: Fri, 6 May 2022 11:05:21 +0530 Subject: [PATCH] intelblocks: Add function to program GPE_EN before GPIO locking Since coreboot locks GPIO registers after GPIO configuration, OS is not able to program GPE_EN register to program wake events. This causes the issue of event not getting logged into event log (since GPE_EN bit is not set). GPE_EN register programming is required for the GPIO pins which are capable of generating SCI for the system wake. Elog mechanism relies on GPE_EN and GPE_STS bit to log correct wake signal. This patch add supports to program GPE_EN register before coreboot locks the GPIO registers. Note that coreboot will only program GPE_EN bits for GPIO capable of generating SCI. This will help resolve issue where we don't see wake event GPIO in event log. BUG=b:222375516 BRANCH=firmware-brya-14505.B TEST=Compile code for Brya and see GPE_EN bits set from the kernel console Change-Id: I27e525f50c374c2cc9675e77eaa7774683a6e7c2 Signed-off-by: Maulik V Vaghela Reviewed-on: https://review.coreboot.org/c/coreboot/+/64089 Tested-by: build bot (Jenkins) Reviewed-by: Frank Wu Reviewed-by: Subrata Banik Reviewed-by: Eric Lai --- src/soc/intel/common/block/gpio/gpio.c | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 3c5d3f371c..fa4aefdba3 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -66,6 +66,10 @@ ((group) * sizeof(uint32_t))) #define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \ ((group) * sizeof(uint32_t))) +#define GPI_GPE_STS_OFFSET(comm, group) ((comm)->gpi_gpe_sts_reg_0 + \ + ((group) * sizeof(uint32_t))) +#define GPI_GPE_EN_OFFSET(comm, group) ((comm)->gpi_gpe_en_reg_0 + \ + ((group) * sizeof(uint32_t))) static inline size_t relative_pad_in_comm(const struct pad_community *comm, gpio_t gpio) @@ -165,6 +169,34 @@ static void gpio_configure_owner(const struct pad_config *cfg, pcr_write32(comm->port, hostsw_own_offset, hostsw_own); } +static void gpi_enable_gpe(const struct pad_config *cfg, + const struct pad_community *comm) +{ + uint16_t en_reg; + uint32_t en_value; + int group; + int pin; + + /* Do not configure GPE_EN if PAD is not configured for SCI/wake */ + if (((cfg->pad_config[0]) & PAD_CFG0_ROUTE_SCI) != PAD_CFG0_ROUTE_SCI) + return; + + /* Get comm offset and bit mask to be set as per pin */ + pin = relative_pad_in_comm(comm, cfg->pad); + group = gpio_group_index(comm, pin); + en_reg = GPI_GPE_EN_OFFSET(comm, group); + en_value = gpio_bitmask_within_group(comm, pin); + + /* Set enable bits */ + pcr_or32(comm->port, en_reg, en_value); + + if (CONFIG(DEBUG_GPIO)) { + printk(BIOS_DEBUG, "GPE_EN[0x%02x, %02zd]: Reg: 0x%x, Value = 0x%x \n",\ + comm->port, relative_pad_in_comm(comm, cfg->pad), en_reg,\ + pcr_read32(comm->port, en_reg)); + } +} + static void gpi_enable_smi(const struct pad_config *cfg, const struct pad_community *comm) { @@ -346,6 +378,7 @@ static void gpio_configure_pad(const struct pad_config *cfg) gpio_configure_owner(cfg, comm); gpi_enable_smi(cfg, comm); gpi_enable_nmi(cfg, comm); + gpi_enable_gpe(cfg, comm); if (cfg->lock_action) gpio_lock_pad(cfg->pad, cfg->lock_action); }