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:
parent
afe840957c
commit
38b8bf02d8
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue