diff options
author | Martin Roth <martin@se-eng.com> | 2012-12-05 16:22:54 -0700 |
---|---|---|
committer | Marc Jones <marcj303@gmail.com> | 2012-12-12 22:34:16 +0100 |
commit | 3316cf2ff80f379b609115f375f73ef4b9e7d8f4 (patch) | |
tree | 451e03092e92a06782e4b058004e123b51c69e58 /src/drivers | |
parent | cf5aaaf1d25429fa6270c7d91a3e072dcf989079 (diff) | |
download | coreboot-3316cf2ff80f379b609115f375f73ef4b9e7d8f4.tar.xz |
Claim the SPI bus before writes if the IMC ROM is present
The SB800 and Hudson now support adding the IMC ROM which runs from the same
chip as coreboot. When the IMC is running, write or erase commands sent to
the spi bus will fail, and the IMC will die. To fix this, we send a request
to the IMC to stop fetching from the SPI rom while we write to it. This
process (in one form or another) is required for writes to the SPI bus while
the IMC is running.
Because the IMC can take up to 500ms to respond every time we claim the
bus, this patch tries to keep the number of times we need to do that to a
minimum. We only need to claim the bus on writes, and using a counter for
the semaphore allows us to call in once to claim the bus at the beginning
of a number of transactions and it will stay claimed until we release it
at the end of the transactions.
Claim() - takes up to 500ms hit
claim() - no delay
erase()
release()
claim() - no delay
write()
release()
Release()
Change-Id: I4e003c5122a2ed47abce57ab8b92dee6aa4713ed
Signed-off-by: Martin Roth <martin@se-eng.com>
Reviewed-on: http://review.coreboot.org/1976
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/spi/eon.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/gigadevice.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/macronix.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/spansion.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/spi_flash.c | 3 | ||||
-rw-r--r-- | src/drivers/spi/sst.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/stmicro.c | 1 | ||||
-rw-r--r-- | src/drivers/spi/winbond.c | 1 |
8 files changed, 10 insertions, 0 deletions
diff --git a/src/drivers/spi/eon.c b/src/drivers/spi/eon.c index 2215a74d8a..21103ae221 100644 --- a/src/drivers/spi/eon.c +++ b/src/drivers/spi/eon.c @@ -70,6 +70,7 @@ static int eon_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c index ece6978c2b..5a8f82f053 100644 --- a/src/drivers/spi/gigadevice.c +++ b/src/drivers/spi/gigadevice.c @@ -131,6 +131,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset, page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c index 0a0d62bdac..910b874cd4 100644 --- a/src/drivers/spi/macronix.c +++ b/src/drivers/spi/macronix.c @@ -134,6 +134,7 @@ static int macronix_write(struct spi_flash *flash, page_size = min(mcx->params->page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/spansion.c b/src/drivers/spi/spansion.c index 328892ccb1..37bf5a859c 100644 --- a/src/drivers/spi/spansion.c +++ b/src/drivers/spi/spansion.c @@ -147,6 +147,7 @@ static int spansion_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 75a5c21619..6b658f894d 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -69,6 +69,7 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, struct spi_slave *spi = flash->spi; int ret; + spi->rw = SPI_READ_FLAG; spi_claim_bus(spi); ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); spi_release_bus(spi); @@ -148,6 +149,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u8 erase_cmd, return -1; } + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); @@ -258,6 +260,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, return NULL; } + spi->rw = SPI_READ_FLAG; ret = spi_claim_bus(spi); if (ret) { printk(BIOS_WARNING, "SF: Failed to claim SPI bus: %d\n", ret); diff --git a/src/drivers/spi/sst.c b/src/drivers/spi/sst.c index 2609591723..8cf3f964fd 100644 --- a/src/drivers/spi/sst.c +++ b/src/drivers/spi/sst.c @@ -153,6 +153,7 @@ sst_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf) int ret; u8 cmd[4]; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index d10429b2c4..b741d30feb 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -148,6 +148,7 @@ static int stmicro_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c index 28786756ae..c44afea832 100644 --- a/src/drivers/spi/winbond.c +++ b/src/drivers/spi/winbond.c @@ -117,6 +117,7 @@ static int winbond_write(struct spi_flash *flash, page_size = min(1 << stm->params->l2_page_size, CONTROLLER_PAGE_LIMIT); byte_addr = offset % page_size; + flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); |