From 8a99a6e210edfb037571bdc5019ca3b224012c03 Mon Sep 17 00:00:00 2001 From: Shiyu Sun Date: Wed, 7 Oct 2020 00:42:59 +1100 Subject: realtek_mst_i2c_spi.c: Update GPIO pin 88 toggle function Here we provide a helper function to allow indexing MCU configuration registers. The 0x9F port allows access to these MCU configuration registers followed by the high and then low bytes of the register address we wish to index written into 0xF5 or 0xF4 respectively, a read or write can then be made via 0xF5. For the configuration of GPIO pins on the chip, there are two relevant register address, 0x104F for pin direction (sink input or push-pull in-out) configuration and 0xFE3F for pin data values (1 to push-pull and 0 to sink). The reference design uses GPIO 88 to strap the write protection pin and so we provide a function that allows the call site to toggle this state and therefore de-assert hardware write protection of the external spi flash. BUG=b:152558985,b:148745673 BRANCH=none TEST=builds && verified the write protection get disabled. Change-Id: I1aed0086f917e31bebb51857ad5cce138158fe82 Signed-off-by: Shiyu Sun Reviewed-on: https://review.coreboot.org/c/flashrom/+/46089 Reviewed-by: Angel Pons Reviewed-by: Edward O'Callaghan Tested-by: build bot (Jenkins) --- realtek_mst_i2c_spi.c | 57 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'realtek_mst_i2c_spi.c') diff --git a/realtek_mst_i2c_spi.c b/realtek_mst_i2c_spi.c index d1f72273c..63ff510ce 100644 --- a/realtek_mst_i2c_spi.c +++ b/realtek_mst_i2c_spi.c @@ -46,6 +46,8 @@ #define OPCODE_READ 3 #define OPCODE_WRITE 2 +#define GPIO_CONFIG_ADDRESS 0x104F +#define GPIO_VALUE_ADDRESS 0xFE3F struct realtek_mst_i2c_spi_data { int fd; @@ -146,27 +148,54 @@ static int realtek_mst_i2c_spi_reset_mpu(int fd) return ret; } -static int realtek_mst_i2c_spi_disable_protection(int fd) +static int realtek_mst_i2c_spi_select_indexed_register(int fd, uint16_t address) { int ret = 0; - uint8_t val = 0; - // 0xAB[2:0] = b001 ret |= realtek_mst_i2c_spi_write_register(fd, 0xF4, 0x9F); - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF5, 0x10); - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF4, 0xAB); + ret |= realtek_mst_i2c_spi_write_register(fd, 0xF5, address >> 8); + ret |= realtek_mst_i2c_spi_write_register(fd, 0xF4, address & 0xFF); - ret |= realtek_mst_i2c_spi_read_register(fd, 0xF5, &val); + return ret; +} - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF4, 0x9F); - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF5, 0x10); - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF4, 0xAB); +static int realtek_mst_i2c_spi_write_indexed_register(int fd, uint16_t address, uint8_t val) +{ + int ret = 0; + + ret |= realtek_mst_i2c_spi_select_indexed_register(fd, address); + ret |= realtek_mst_i2c_spi_write_register(fd, 0xF5, val); + + return ret; +} + +static int realtek_mst_i2c_spi_read_indexed_register(int fd, uint16_t address, uint8_t *val) +{ + int ret = 0; + + ret |= realtek_mst_i2c_spi_select_indexed_register(fd, address); + ret |= realtek_mst_i2c_spi_read_register(fd, 0xF5, val); + + return ret; +} + + +/* Toggle the GPIO pin 88, this could be routed to different controls like write + * protection or a led. */ +static int realtek_mst_i2c_spi_toggle_gpio_88_strap(int fd, bool toggle) +{ + int ret = 0; + uint8_t val = 0; - ret |= realtek_mst_i2c_spi_write_register(fd, 0xF5, (val & 0xF8) | 0x01); + /* Read register 0x104F into val. */ + ret |= realtek_mst_i2c_spi_read_indexed_register(fd, GPIO_CONFIG_ADDRESS, &val); + /* Write 0x104F[3:0] = b0001 to enable the toggle of pin value. */ + ret |= realtek_mst_i2c_spi_write_indexed_register(fd, GPIO_CONFIG_ADDRESS, (val & 0xF0) | 0x01); - /* Set pin value to high, 0xFFD7[0] = 1. */ - ret |= realtek_mst_i2c_spi_read_register(fd, 0xD7, &val); - ret |= realtek_mst_i2c_spi_write_register(fd, 0xD7, (val & 0xFE) | 0x01); + /* Read register 0xFE3F into val. */ + ret |= realtek_mst_i2c_spi_read_indexed_register(fd, GPIO_VALUE_ADDRESS, &val); + /* Write 0xFE3F[0] = b|toggle| to toggle pin value to low/high. */ + ret |= realtek_mst_i2c_spi_write_indexed_register(fd, GPIO_VALUE_ADDRESS, (val & 0xFE) | toggle); return ret; } @@ -333,7 +362,7 @@ static int realtek_mst_i2c_spi_write_256(struct flashctx *flash, const uint8_t * if (fd < 0) return SPI_GENERIC_ERROR; - ret = realtek_mst_i2c_spi_disable_protection(fd); + ret = realtek_mst_i2c_spi_toggle_gpio_88_strap(fd, true); if (ret) return ret; -- cgit v1.2.3