diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2021-08-02 19:48:40 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-09-08 00:14:35 +0000 |
commit | 96c4882d257c611bb1a3d18ad2f1b60041582022 (patch) | |
tree | 7ff7b02c9b322c5b6c5215da894bc639e34c0518 /src/soc/amd | |
parent | 916cd50edc90bc9edd134d6a37911174cc0ff944 (diff) |
soc/amd/common/block/i2c: use common GPIO API in drive_scl
No need to do raw GPIO MMIO accesses when basically the same
functionality can be achieved by using existing APIs. Using the existing
GPIO API instead of raw GPIO MMIO register accesses allows containing
all direct GPIO MMIO accesses inside the common AMD GPIO code which will
be done in subsequent patches. Since the value parameter of gpio_set is
int, change the type of the val parameter of drive_scl to int as well
even though I'm not sure why a signed integer was used for this in the
common GPIO API. Since program_gpios already configures the SCL GPIOs as
outputs, gpio_set can be used in drive_scl which only sets the output
value, but doesn't configure the direction.
TEST=The waveform on the SCL pin of I2C3 on a barla/careena Chromebook
looks similar to the same as before during the reset_i2c_peripherals
call, but due to the additional overhead of the read-modify-write to the
GPIO register instead of just a write, the pulse width gets about 50%
longer. Since the udelay call in drive_scl still has an open TODO to
make this configurable and the pulses being longer is in the safe side,
this side-effect can be addressed in a follow-up patch.
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: Ic323cebc1c83ecd6f0e1fbab419c69489d77face
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56777
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Diffstat (limited to 'src/soc/amd')
-rw-r--r-- | src/soc/amd/common/block/i2c/i2c.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/src/soc/amd/common/block/i2c/i2c.c b/src/soc/amd/common/block/i2c/i2c.c index f2773235a6..8a9a663383 100644 --- a/src/soc/amd/common/block/i2c/i2c.c +++ b/src/soc/amd/common/block/i2c/i2c.c @@ -12,6 +12,7 @@ #include <device/i2c.h> #include <device/mmio.h> #include <drivers/i2c/designware/dw_i2c.h> +#include <gpio.h> #include <types.h> #define MAX_PIN_COUNT 4 @@ -148,16 +149,16 @@ static void restore_i2c_pin_registers(uint8_t gpio, struct soc_amd_gpio_register gpio_read32(gpio); } -static void drive_scl(const struct soc_i2c_peripheral_reset_info *reset_info, uint32_t val) +static void drive_scl(const struct soc_i2c_peripheral_reset_info *reset_info, int val) { size_t j; for (j = 0; j < reset_info->num_pins; j++) { if (reset_info->i2c_scl_reset_mask & reset_info->i2c_scl[j].pin_mask) - gpio_write32(reset_info->i2c_scl[j].pin.gpio, val); + gpio_set(reset_info->i2c_scl[j].pin.gpio, val); } - gpio_read32(0); /* Flush posted write */ + gpio_get(0); /* Flush posted write */ /* * TODO(b/183010197): 4usec gets 85KHz for 1 pin, 70KHz for 4 pins. Ensure this delay * works fine for all SoCs and make this delay configurable if required. @@ -179,6 +180,7 @@ void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_ /* Save and reprogram I2C SCL pins */ for (i = 0; i < reset_info->num_pins; i++) { save_i2c_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]); + /* Program SCL GPIO as output driven high */ program_gpios(&reset_info->i2c_scl[i].pin, 1); } @@ -187,8 +189,8 @@ void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_ * needed after the writes to force the posted write to complete. */ for (i = 0; i < 9; i++) { - drive_scl(reset_info, GPIO_OUTPUT_OUT_HIGH); - drive_scl(reset_info, GPIO_OUTPUT_OUT_LOW); + drive_scl(reset_info, 1); + drive_scl(reset_info, 0); } /* Restore I2C pins. */ |