summaryrefslogtreecommitdiffstats
path: root/realtek_mst_i2c_spi.c
diff options
context:
space:
mode:
authorShiyu Sun <sshiyu@google.com>2020-10-07 00:42:59 +1100
committerEdward O'Callaghan <quasisec@chromium.org>2020-10-14 09:28:27 +0000
commit8a99a6e210edfb037571bdc5019ca3b224012c03 (patch)
treef2a42068e1dcff034e2780d1f7e2ffab617a3ce1 /realtek_mst_i2c_spi.c
parentd4d3657b4d64b8fa38eb05ab2a50fdea3e1b45a4 (diff)
downloadflashrom-8a99a6e210edfb037571bdc5019ca3b224012c03.tar.gz
flashrom-8a99a6e210edfb037571bdc5019ca3b224012c03.tar.bz2
flashrom-8a99a6e210edfb037571bdc5019ca3b224012c03.zip
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 <sshiyu@chromium.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/46089 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'realtek_mst_i2c_spi.c')
-rw-r--r--realtek_mst_i2c_spi.c57
1 files changed, 43 insertions, 14 deletions
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;