drivers/spi/spi_flash: honor spi controller fifo size for reads

The spi_flash_cmd_read_fast() and spi_flash_cmd_read_slow() were just
passing full size buffers to the spi controller ops. However, the
code wasn't honoring what the spi controller can actually perform.
This would cause failures to read on controllers when large requests
were sent in. Fix this by introducing a
spi_flash_cmd_read_array_wrapped() function that calls
spi_flash_cmd_read_array() in a loop once the maximum transfer size is
calculated based on the spi controller's settings.

BUG=b:65485690

Change-Id: I442d6e77a93fda411cb289b606189e490a4e464e
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/23444
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Justin TerAvest <teravest@chromium.org>
This commit is contained in:
Aaron Durbin 2018-01-25 17:30:45 -07:00
parent e98722856e
commit 3a649eec28
1 changed files with 30 additions and 2 deletions

View File

@ -113,6 +113,34 @@ static int spi_flash_cmd_read_array(const struct spi_slave *spi, u8 *cmd,
return spi_flash_cmd_read(spi, cmd, cmd_len, data, len);
}
/* Perform the read operation honoring spi controller fifo size, reissuing
* the read command until the full request completed. */
static int spi_flash_cmd_read_array_wrapped(const struct spi_slave *spi,
u8 *cmd, size_t cmd_len, u32 offset,
size_t len, void *buf)
{
int ret;
size_t xfer_len;
uint8_t *data = buf;
while (len) {
xfer_len = spi_crop_chunk(spi, cmd_len, len);
/* Perform the read. */
ret = spi_flash_cmd_read_array(spi, cmd, cmd_len,
offset, xfer_len, data);
if (ret)
return ret;
offset += xfer_len;
data += xfer_len;
len -= xfer_len;
}
return 0;
}
int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
size_t len, void *data)
{
@ -121,7 +149,7 @@ int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
cmd[0] = CMD_READ_ARRAY_FAST;
cmd[4] = 0x00;
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
return spi_flash_cmd_read_array_wrapped(&flash->spi, cmd, sizeof(cmd),
offset, len, data);
}
@ -131,7 +159,7 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset,
u8 cmd[4];
cmd[0] = CMD_READ_ARRAY_SLOW;
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
return spi_flash_cmd_read_array_wrapped(&flash->spi, cmd, sizeof(cmd),
offset, len, data);
}