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 <maulik.v.vaghela@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64089
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Frank Wu <frank_wu@compal.corp-partner.google.com>
Reviewed-by: Subrata Banik <subratabanik@google.com>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
This commit is contained in:
Maulik V Vaghela 2022-05-06 11:05:21 +05:30 committed by Werner Zeh
parent afe840957c
commit 38b8bf02d8
1 changed files with 33 additions and 0 deletions

View File

@ -66,6 +66,10 @@
((group) * sizeof(uint32_t))) ((group) * sizeof(uint32_t)))
#define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \ #define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \
((group) * sizeof(uint32_t))) ((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, static inline size_t relative_pad_in_comm(const struct pad_community *comm,
gpio_t gpio) 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); 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, static void gpi_enable_smi(const struct pad_config *cfg,
const struct pad_community *comm) const struct pad_community *comm)
{ {
@ -346,6 +378,7 @@ static void gpio_configure_pad(const struct pad_config *cfg)
gpio_configure_owner(cfg, comm); gpio_configure_owner(cfg, comm);
gpi_enable_smi(cfg, comm); gpi_enable_smi(cfg, comm);
gpi_enable_nmi(cfg, comm); gpi_enable_nmi(cfg, comm);
gpi_enable_gpe(cfg, comm);
if (cfg->lock_action) if (cfg->lock_action)
gpio_lock_pad(cfg->pad, cfg->lock_action); gpio_lock_pad(cfg->pad, cfg->lock_action);
} }