summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2014-06-29 16:15:39 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-07-14 19:42:27 +0200
commit77d1280d0c866a9f85e62f74c43fe8d021a4ff39 (patch)
tree2c1902f07548406e6807b68645048a47616dc8ca /src
parent562db3bb3fa16abf6f758e97f9e5496f1c14d423 (diff)
downloadcoreboot-77d1280d0c866a9f85e62f74c43fe8d021a4ff39.tar.gz
coreboot-77d1280d0c866a9f85e62f74c43fe8d021a4ff39.tar.bz2
coreboot-77d1280d0c866a9f85e62f74c43fe8d021a4ff39.zip
SPI flash: Fix alignment checks in Page Program commands
There are two separate restrictions to take into account: Page Program command must not cross address boundaries defined by the flash part's page size. Total number of bytes for any command sent to flash part is restricted by the SPI controller capabilities. Consider CONTROLLER_PAGE_LIMIT=64, page_size=256, offset=62, len=4. This write would be split at offset 64 for no reason. Consider CONTROLLER_PAGE_LIMIT=40, page_size=256, offset=254, len=4. This write would not be split at page boundary as required. We do not really hit the second case. Nevertheless, CONTROLLER_PAGE_LIMIT is a misnomer for the maximum payload length supported by the SPI controller and is removed in a followup. Change-Id: I727f2e7de86a91b6a509460ff1f374acd006a0bc Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/6162 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/spi/adesto.c3
-rw-r--r--src/drivers/spi/amic.c3
-rw-r--r--src/drivers/spi/gigadevice.c3
-rw-r--r--src/drivers/spi/macronix.c3
-rw-r--r--src/drivers/spi/stmicro.c3
-rw-r--r--src/drivers/spi/winbond.c3
6 files changed, 12 insertions, 6 deletions
diff --git a/src/drivers/spi/adesto.c b/src/drivers/spi/adesto.c
index 83be8b899557..9dc8e145462c 100644
--- a/src/drivers/spi/adesto.c
+++ b/src/drivers/spi/adesto.c
@@ -88,7 +88,7 @@ static int adesto_write(struct spi_flash *flash,
int ret;
u8 cmd[4];
- page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = 1 << stm->params->l2_page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -100,6 +100,7 @@ static int adesto_write(struct spi_flash *flash,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
cmd[0] = CMD_AT25DF_PP;
cmd[1] = (offset >> 16) & 0xff;
diff --git a/src/drivers/spi/amic.c b/src/drivers/spi/amic.c
index fa17036e8537..4cccc71197f7 100644
--- a/src/drivers/spi/amic.c
+++ b/src/drivers/spi/amic.c
@@ -70,7 +70,7 @@ static int amic_write(struct spi_flash *flash,
int ret;
u8 cmd[4];
- page_size = min(1 << amic->params->l2_page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = 1 << amic->params->l2_page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -82,6 +82,7 @@ static int amic_write(struct spi_flash *flash,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
cmd[0] = CMD_A25_PP;
cmd[1] = (offset >> 16) & 0xff;
diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c
index 5a8f82f0537e..3fb89c7fc57d 100644
--- a/src/drivers/spi/gigadevice.c
+++ b/src/drivers/spi/gigadevice.c
@@ -128,7 +128,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset,
int ret;
u8 cmd[4];
- page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = 1 << stm->params->l2_page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -141,6 +141,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
ret = spi_flash_cmd(flash->spi, CMD_GD25_WREN, NULL, 0);
if (ret < 0) {
diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c
index bbc37046560e..36115990651d 100644
--- a/src/drivers/spi/macronix.c
+++ b/src/drivers/spi/macronix.c
@@ -131,7 +131,7 @@ static int macronix_write(struct spi_flash *flash,
int ret;
u8 cmd[4];
- page_size = min(mcx->params->page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = mcx->params->page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -144,6 +144,7 @@ static int macronix_write(struct spi_flash *flash,
ret = 0;
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
cmd[0] = CMD_MX25XX_PP;
cmd[1] = (offset >> 16) & 0xff;
diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c
index af2385328bde..c825bd083b2e 100644
--- a/src/drivers/spi/stmicro.c
+++ b/src/drivers/spi/stmicro.c
@@ -143,7 +143,7 @@ static int stmicro_write(struct spi_flash *flash,
int ret;
u8 cmd[4];
- page_size = min(stm->params->page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = stm->params->page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -155,6 +155,7 @@ static int stmicro_write(struct spi_flash *flash,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
cmd[0] = CMD_M25PXX_PP;
cmd[1] = (offset >> 16) & 0xff;
diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c
index 52c7b61245be..eb0868ec7a02 100644
--- a/src/drivers/spi/winbond.c
+++ b/src/drivers/spi/winbond.c
@@ -122,7 +122,7 @@ static int winbond_write(struct spi_flash *flash,
int ret;
u8 cmd[4];
- page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT);
+ page_size = 1 << stm->params->l2_page_size;
byte_addr = offset % page_size;
flash->spi->rw = SPI_WRITE_FLAG;
@@ -134,6 +134,7 @@ static int winbond_write(struct spi_flash *flash,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ chunk_len = min(chunk_len, CONTROLLER_PAGE_LIMIT);
cmd[0] = CMD_W25_PP;
cmd[1] = (offset >> 16) & 0xff;