soc/amd/common/block/i2c: move raw GPIO access functions to gpio_banks

The I2C code should use some GPIO API to access the GPIO registers
instead of accessing the GPIO MMIO regions itself.

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: I84dff381ad86e0c7f879f0f079186aec9cafc604
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56779
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Felix Held 2021-08-03 02:55:34 +02:00
parent 96c4882d25
commit 35cee38c71
3 changed files with 20 additions and 21 deletions

View File

@ -166,6 +166,19 @@ static void set_gpio_mux(gpio_t gpio, uint8_t function)
iomux_read8(gpio); /* Flush posted write */ iomux_read8(gpio); /* Flush posted write */
} }
void gpio_save_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
{
save->mux_value = iomux_read8(gpio);
save->control_value = gpio_read32(gpio);
}
void gpio_restore_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
{
set_gpio_mux(gpio, save->mux_value);
gpio_write32(gpio, save->control_value);
gpio_read32(gpio); /* Flush posted write */
}
static void set_single_gpio(const struct soc_amd_gpio *g) static void set_single_gpio(const struct soc_amd_gpio *g)
{ {
static const struct soc_amd_event *gev_tbl; static const struct soc_amd_event *gev_tbl;

View File

@ -130,25 +130,6 @@ struct device_operations soc_amd_i2c_mmio_ops = {
.acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt, .acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt,
}; };
/*
* To program I2C pins without destroying their programming, the registers
* that will be changed need to be saved first.
*/
static void save_i2c_pin_registers(uint8_t gpio, struct soc_amd_gpio_register_save *save_table)
{
save_table->mux_value = iomux_read8(gpio);
save_table->control_value = gpio_read32(gpio);
}
static void restore_i2c_pin_registers(uint8_t gpio, struct soc_amd_gpio_register_save *save_table)
{
/* Write and flush posted writes. */
iomux_write8(gpio, save_table->mux_value);
iomux_read8(gpio);
gpio_write32(gpio, save_table->control_value);
gpio_read32(gpio);
}
static void drive_scl(const struct soc_i2c_peripheral_reset_info *reset_info, int val) static void drive_scl(const struct soc_i2c_peripheral_reset_info *reset_info, int val)
{ {
size_t j; size_t j;
@ -179,7 +160,9 @@ void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_
/* Save and reprogram I2C SCL pins */ /* Save and reprogram I2C SCL pins */
for (i = 0; i < reset_info->num_pins; i++) { for (i = 0; i < reset_info->num_pins; i++) {
save_i2c_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]); /* To program I2C pins without destroying their programming, the registers
that will be changed need to be saved first */
gpio_save_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]);
/* Program SCL GPIO as output driven high */ /* Program SCL GPIO as output driven high */
program_gpios(&reset_info->i2c_scl[i].pin, 1); program_gpios(&reset_info->i2c_scl[i].pin, 1);
} }
@ -195,5 +178,5 @@ void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_
/* Restore I2C pins. */ /* Restore I2C pins. */
for (i = 0; i < reset_info->num_pins; i++) for (i = 0; i < reset_info->num_pins; i++)
restore_i2c_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]); gpio_restore_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]);
} }

View File

@ -91,4 +91,7 @@ int gpio_interrupt_status(gpio_t gpio);
/* Implemented by soc, provides table of available GPIO mapping to Gevents */ /* Implemented by soc, provides table of available GPIO mapping to Gevents */
void soc_get_gpio_event_table(const struct soc_amd_event **table, size_t *items); void soc_get_gpio_event_table(const struct soc_amd_event **table, size_t *items);
void gpio_save_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save);
void gpio_restore_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save);
#endif /* AMD_BLOCK_GPIO_BANKS_H */ #endif /* AMD_BLOCK_GPIO_BANKS_H */