amd/stoneyridge: Disable GPIO MASK STATUS
MASK_STATUS disables interrupt status generation for the entire GPIO controller when any debounce register is configured. This causes problems when the kernel is loading drivers because we could lose interrupts for previously loaded devices. sb_program_gpios is also not setup to wait when configuring PAD_DEBOUNCE, so there is a potential that we could lose the interrupt status enable bit for other registers. By disabling MASK_STATUS we avoid that problem. BUG=b:113880780 BRANCH=none TEST=Ran a reboot stress test that concluded that we are no longer losing TPM interrupts while booting. Change-Id: Ife1db3b1449f205092509595cbc3eca511bff57a Signed-off-by: Raul E Rangel <rrangel@chromium.org> Reviewed-on: https://review.coreboot.org/c/31082 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Daniel Kurtz <djkurtz@google.com>
This commit is contained in:
parent
595202c304
commit
df3064227f
|
@ -222,15 +222,30 @@ uint16_t gpio_acpi_pin(gpio_t gpio)
|
||||||
void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
|
void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
|
||||||
{
|
{
|
||||||
uint8_t *mux_ptr;
|
uint8_t *mux_ptr;
|
||||||
uint32_t *gpio_ptr;
|
uint32_t *gpio_ptr, *inter_master;
|
||||||
uint32_t control, control_flags, edge_level, direction;
|
uint32_t control, control_flags, edge_level, direction;
|
||||||
uint32_t mask, bit_edge, bit_level;
|
uint32_t mask, bit_edge, bit_level;
|
||||||
uint8_t mux, index, gpio;
|
uint8_t mux, index, gpio;
|
||||||
int gevent_num;
|
int gevent_num;
|
||||||
|
|
||||||
|
inter_master = (uint32_t *)(uintptr_t)(GPIO_CONTROL_MMIO_BASE
|
||||||
|
+ GPIO_MASTER_SWITCH);
|
||||||
direction = 0;
|
direction = 0;
|
||||||
edge_level = 0;
|
edge_level = 0;
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable blocking wake/interrupt status generation while updating
|
||||||
|
* debounce registers. Otherwise when a debounce register is updated
|
||||||
|
* the whole GPIO controller will zero out all interrupt enable status
|
||||||
|
* bits while the delay happens. This could cause us to drop the bits
|
||||||
|
* due to the read-modify-write that happens on each register.
|
||||||
|
*
|
||||||
|
* Additionally disable interrupt generation so we don't get any
|
||||||
|
* spurious interrupts while updating the registers.
|
||||||
|
*/
|
||||||
|
mem_read_write32(inter_master, 0, GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);
|
||||||
|
|
||||||
for (index = 0; index < size; index++) {
|
for (index = 0; index < size; index++) {
|
||||||
gpio = gpio_list_ptr[index].gpio;
|
gpio = gpio_list_ptr[index].gpio;
|
||||||
mux = gpio_list_ptr[index].function;
|
mux = gpio_list_ptr[index].function;
|
||||||
|
@ -290,6 +305,16 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
|
||||||
AMD_GPIO_CONTROL_MASK);
|
AMD_GPIO_CONTROL_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-enable interrupt status generation.
|
||||||
|
*
|
||||||
|
* We leave MASK_STATUS disabled because the kernel may reconfigure the
|
||||||
|
* debounce registers while the drivers load. This will cause interrupts
|
||||||
|
* to be missed during boot.
|
||||||
|
*/
|
||||||
|
mem_read_write32(inter_master, GPIO_INTERRUPT_EN, GPIO_INTERRUPT_EN);
|
||||||
|
|
||||||
/* Set all SCI trigger direction (high/low) */
|
/* Set all SCI trigger direction (high/low) */
|
||||||
mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_TRIG),
|
mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_TRIG),
|
||||||
direction, mask);
|
direction, mask);
|
||||||
|
|
|
@ -41,6 +41,10 @@ struct soc_amd_i2c_save {
|
||||||
uint8_t mux_value;
|
uint8_t mux_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GPIO_MASTER_SWITCH 0xFC
|
||||||
|
#define GPIO_MASK_STS_EN BIT(28)
|
||||||
|
#define GPIO_INTERRUPT_EN BIT(30)
|
||||||
|
|
||||||
#define GPIO_I2C0_SCL BIT(0)
|
#define GPIO_I2C0_SCL BIT(0)
|
||||||
#define GPIO_I2C1_SCL BIT(1)
|
#define GPIO_I2C1_SCL BIT(1)
|
||||||
#define GPIO_I2C2_SCL BIT(2)
|
#define GPIO_I2C2_SCL BIT(2)
|
||||||
|
|
Loading…
Reference in New Issue