diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2020-08-27 18:06:05 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-03 00:33:43 +0000 |
commit | d031c14214cb1e2a229a909e946b5b36ff91afee (patch) | |
tree | 30f888d7a23f280175bb10b8e4898d9566e8d991 /util | |
parent | 147803fd0f6785692c215e49d31b948ac871acb5 (diff) | |
download | chrome-ec-d031c14214cb1e2a229a909e946b5b36ff91afee.tar.gz |
iteflash: speed up flash read
To save time, this patch removes unnecessary i2c transactions
in reading (verifying) flash.
BUG=none
BRANCH=none
TEST=Read 512k bytes without/with this patch:
======without patch / with patch=============
servo v2 : 36s / 14s ( 22s reduced)
servo micro: 2m:13s / 1m:04s (1m:09s reduced)
c2d2 : 81s / 23s ( 58s reduced)
Change-Id: I9dc05e107eaf004c4c2017de9ffe9aa97a0d9c68
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2379368
Reviewed-by: Jett Rink <jettrink@chromium.org>
Commit-Queue: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/iteflash.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/util/iteflash.c b/util/iteflash.c index b2c4161f1f..36e45c2012 100644 --- a/util/iteflash.c +++ b/util/iteflash.c @@ -1135,13 +1135,34 @@ static void draw_spinner(uint32_t remaining, uint32_t size) windex %= sizeof(wheel); } +/* Note: this function must be called in follow mode */ +static int spi_send_cmd_fast_read(struct common_hnd *chnd, uint32_t addr) +{ + int ret = 0; + uint8_t cmd = 0x9; + + /* Fast Read command */ + ret = spi_flash_command_short(chnd, SPI_CMD_FAST_READ, "fast read"); + /* Send address */ + ret |= i2c_write_byte(chnd, 0x08, ((addr >> 16) & 0xff)); /* addr_h */ + ret |= i2c_write_byte(chnd, 0x08, ((addr >> 8) & 0xff)); /* addr_m */ + ret |= i2c_write_byte(chnd, 0x08, (addr & 0xff)); /* addr_l */ + /* fake byte */ + ret |= i2c_write_byte(chnd, 0x08, 0x00); + /* use i2c block read command */ + ret |= i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1); + if (ret < 0) + fprintf(stderr, "Send fast read command failed\n"); + + return ret; +} + static int command_read_pages(struct common_hnd *chnd, uint32_t address, uint32_t size, uint8_t *buffer) { int res = -EIO; uint32_t remaining = size; int cnt; - uint8_t addr_H, addr_M; if (address & 0xFF) { fprintf(stderr, "page read requested at non-page boundary: " @@ -1152,30 +1173,14 @@ static int command_read_pages(struct common_hnd *chnd, uint32_t address, if (spi_flash_follow_mode(chnd, "fast read") < 0) goto failed_read; - while (remaining) { - uint8_t cmd = 0x9; + if (spi_send_cmd_fast_read(chnd, address) < 0) + goto failed_read; + while (remaining) { cnt = (remaining > PAGE_SIZE) ? PAGE_SIZE : remaining; - addr_H = (address >> 16) & 0xFF; - addr_M = (address >> 8) & 0xFF; - draw_spinner(remaining, size); - /* Fast Read command */ - if (spi_flash_command_short(chnd, SPI_CMD_FAST_READ, - "fast read") < 0) - goto failed_read; - res = i2c_write_byte(chnd, 0x08, addr_H); - res += i2c_write_byte(chnd, 0x08, addr_M); - res += i2c_write_byte(chnd, 0x08, 0x00); /* addr_L */ - res += i2c_write_byte(chnd, 0x08, 0x00); - if (res < 0) { - fprintf(stderr, "page address set failed\n"); - goto failed_read; - } - /* read page data */ - res = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1); res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 0, cnt); if (res < 0) { fprintf(stderr, "page data read failed\n"); @@ -1185,6 +1190,12 @@ static int command_read_pages(struct common_hnd *chnd, uint32_t address, address += cnt; remaining -= cnt; buffer += cnt; + + /* We need to resend fast read command at 256KB boundary. */ + if (!(address % 0x40000) && remaining) { + if (spi_send_cmd_fast_read(chnd, address) < 0) + goto failed_read; + } } /* No error so far */ res = size; |