diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2020-07-01 01:43:55 +0300 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-02-05 15:30:23 +0000 |
commit | ff730feaccd625045e2bf3e1622898ac850d7a18 (patch) | |
tree | 97f7f9e3e0c53260dc27c27098f16cd94e096078 | |
parent | 7aa5b5ece9c1800f18d7f4404b77a62ee9278b8f (diff) |
soc/amd/common: Separate single GPIO programming
Do this to reduce indentation a bit. Also it may be desireable
to group GPIO configuration such that some GPIOs are handled
outside program_gpios() call and would not be included in
gpio_list array.
Change-Id: I46cbe33f4d85cd9c7d70f96df82ee9b8ffe50a00
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42807
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r-- | src/soc/amd/common/block/gpio_banks/gpio.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/src/soc/amd/common/block/gpio_banks/gpio.c b/src/soc/amd/common/block/gpio_banks/gpio.c index 5b0111b28f..ebd74e055d 100644 --- a/src/soc/amd/common/block/gpio_banks/gpio.c +++ b/src/soc/amd/common/block/gpio_banks/gpio.c @@ -181,16 +181,62 @@ uint16_t gpio_acpi_pin(gpio_t gpio) __weak void soc_gpio_hook(uint8_t gpio, uint8_t mux) {} -void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) +static void set_single_gpio(const struct soc_amd_gpio *gpio_list_ptr, + struct sci_trigger_regs *sci_trigger_cfg) { uint32_t control, control_flags; - uint8_t mux, index, gpio; + uint8_t mux, gpio; + static const struct soc_amd_event *gev_tbl; + static size_t gev_items; int gevent_num; - const struct soc_amd_event *gev_tbl; + const bool can_set_smi_flags = !(CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && + ENV_SEPARATE_VERSTAGE); + + gpio = gpio_list_ptr->gpio; + mux = gpio_list_ptr->function; + control = gpio_list_ptr->control; + control_flags = gpio_list_ptr->flags; + + iomux_write8(gpio, mux & AMD_GPIO_MUX_MASK); + iomux_read8(gpio); /* Flush posted write */ + + soc_gpio_hook(gpio, mux); + + gpio_setbits32(gpio, PAD_CFG_MASK, control); + /* Clear interrupt and wake status (write 1-to-clear bits) */ + gpio_or32(gpio, GPIO_INT_STATUS | GPIO_WAKE_STATUS); + if (control_flags == 0) + return; + + /* Can't set SMI flags from PSP */ + if (!can_set_smi_flags) + return; + + if (gev_tbl == NULL) + soc_get_gpio_event_table(&gev_tbl, &gev_items); + + gevent_num = get_gpio_gevent(gpio, gev_tbl, gev_items); + if (gevent_num < 0) { + printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n", + gpio); + return; + } + + if (control_flags & GPIO_FLAG_SMI) { + program_smi(control_flags, gevent_num); + } else if (control_flags & GPIO_FLAG_SCI) { + fill_sci_trigger(control_flags, gevent_num, sci_trigger_cfg); + soc_route_sci(gevent_num); + } +} + +void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) +{ struct sci_trigger_regs sci_trigger_cfg = { 0 }; - size_t gev_items; const bool can_set_smi_flags = !(CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && ENV_SEPARATE_VERSTAGE); + size_t i; + if (!gpio_list_ptr || !size) return; @@ -206,44 +252,8 @@ void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) */ master_switch_clr(GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN); - if (can_set_smi_flags) - soc_get_gpio_event_table(&gev_tbl, &gev_items); - - for (index = 0; index < size; index++) { - gpio = gpio_list_ptr[index].gpio; - mux = gpio_list_ptr[index].function; - control = gpio_list_ptr[index].control; - control_flags = gpio_list_ptr[index].flags; - - iomux_write8(gpio, mux & AMD_GPIO_MUX_MASK); - iomux_read8(gpio); /* Flush posted write */ - - soc_gpio_hook(gpio, mux); - - gpio_setbits32(gpio, PAD_CFG_MASK, control); - /* Clear interrupt and wake status (write 1-to-clear bits) */ - gpio_or32(gpio, GPIO_INT_STATUS | GPIO_WAKE_STATUS); - if (control_flags == 0) - continue; - - /* Can't set SMI flags from PSP */ - if (!can_set_smi_flags) - continue; - - gevent_num = get_gpio_gevent(gpio, gev_tbl, gev_items); - if (gevent_num < 0) { - printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n", - gpio); - continue; - } - - if (control_flags & GPIO_FLAG_SMI) { - program_smi(control_flags, gevent_num); - } else if (control_flags & GPIO_FLAG_SCI) { - fill_sci_trigger(control_flags, gevent_num, &sci_trigger_cfg); - soc_route_sci(gevent_num); - } - } + for (i = 0; i < size; i++) + set_single_gpio(&gpio_list_ptr[i], &sci_trigger_cfg); /* * Re-enable interrupt status generation. |