soc/amd/common/block/gpio_banks: Rework GPIO pad configuration

Before this patch, gpio_configure_pads_with_override called
program_gpios once for each GPIO that needed to be configured which
resulted in base_num_pads - 1 unneeded master_switch_set/
master_switch_clr sequences for the gpio_configure_pads_with_override
call. Instead implement gpio_configure_pads_with_override as the more
generic function and program_gpios as a special case of that which
passes an empty override configuration and override pad number to
gpio_configure_pads_with_override.

TEST=GPIO configuration and multiplexer register values are the same for
all GPIOs on google/guybrush right before jumping to the payload before
and after the patch.

Change-Id: Ia8e47b2a278a1887db5406c1f863ddafa6a68675
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/43050
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
This commit is contained in:
Felix Held 2021-09-20 21:12:22 +02:00 committed by Felix Held
parent 67772d27a6
commit f7f1f1672f
1 changed files with 23 additions and 39 deletions

View File

@ -264,11 +264,15 @@ static void set_single_gpio(const struct soc_amd_gpio *g)
}
}
void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg,
size_t base_num_pads,
const struct soc_amd_gpio *override_cfg,
size_t override_num_pads)
{
size_t i;
const struct soc_amd_gpio *c;
size_t i, j;
if (!gpio_list_ptr || !size)
if (!base_cfg || !base_num_pads)
return;
/*
@ -283,8 +287,17 @@ void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
*/
master_switch_clr(GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);
for (i = 0; i < size; i++)
set_single_gpio(&gpio_list_ptr[i]);
for (i = 0; i < base_num_pads; i++) {
c = &base_cfg[i];
/* Check if override exist for GPIO from the base configuration */
for (j = 0; override_cfg && j < override_num_pads; j++) {
if (c->gpio == override_cfg[j].gpio) {
c = &override_cfg[j];
break;
}
}
set_single_gpio(c);
}
/*
* Re-enable interrupt status generation.
@ -296,6 +309,11 @@ void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
master_switch_set(GPIO_INTERRUPT_EN);
}
void program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
{
gpio_configure_pads_with_override(gpio_list_ptr, size, NULL, 0);
}
int gpio_interrupt_status(gpio_t gpio)
{
uint32_t reg = gpio_read32(gpio);
@ -310,40 +328,6 @@ int gpio_interrupt_status(gpio_t gpio)
return 0;
}
/*
* This function checks to see if there is an override config present for the
* provided pad_config. If no override config is present, then the input config
* is returned. Else, it returns the override config.
*/
static const struct soc_amd_gpio *gpio_get_config(const struct soc_amd_gpio *c,
const struct soc_amd_gpio *override_cfg_table,
size_t num)
{
size_t i;
if (override_cfg_table == NULL)
return c;
for (i = 0; i < num; i++) {
if (c->gpio == override_cfg_table[i].gpio)
return override_cfg_table + i;
}
return c;
}
void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg,
size_t base_num_pads,
const struct soc_amd_gpio *override_cfg,
size_t override_num_pads)
{
size_t i;
const struct soc_amd_gpio *c;
for (i = 0; i < base_num_pads; i++) {
c = gpio_get_config(base_cfg + i, override_cfg,
override_num_pads);
program_gpios(c, 1);
}
}
static void check_and_add_wake_gpio(gpio_t begin, gpio_t end, struct gpio_wake_state *state)
{
gpio_t i;