[coreboot-gerrit] New patch to review for coreboot: 6cf6b9f SPI: Split writes using spi_crop_chunk()
Kyösti Mälkki (kyosti.malkki@gmail.com)
gerrit at coreboot.org
Mon Jun 30 10:21:37 CEST 2014
Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6163
-gerrit
commit 6cf6b9fbf20d407cf4284a2db5e602441bcfdbb0
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date: Sun Jun 29 16:17:33 2014 +0300
SPI: Split writes using spi_crop_chunk()
SPI controllers in Intel and AMD bridges have a slightly different
restriction on how long transactions they can handle.
Change-Id: I3d149d4b7e7e9633482a153d5e380a86c553d871
Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
src/drivers/spi/adesto.c | 4 ++--
src/drivers/spi/amic.c | 4 ++--
src/drivers/spi/gigadevice.c | 4 ++--
src/drivers/spi/macronix.c | 5 ++---
src/drivers/spi/stmicro.c | 4 ++--
src/drivers/spi/winbond.c | 4 ++--
src/include/spi-generic.h | 2 ++
src/include/spi_flash.h | 8 --------
src/soc/intel/baytrail/spi.c | 7 ++++++-
src/soc/intel/fsp_baytrail/spi.c | 7 ++++++-
src/southbridge/amd/agesa/hudson/spi.c | 8 ++++++++
src/southbridge/amd/cimx/sb800/spi.c | 8 ++++++++
src/southbridge/intel/common/spi.c | 7 ++++++-
13 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/src/drivers/spi/adesto.c b/src/drivers/spi/adesto.c
index 9dc8e14..50e5883 100644
--- a/src/drivers/spi/adesto.c
+++ b/src/drivers/spi/adesto.c
@@ -100,7 +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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
cmd[0] = CMD_AT25DF_PP;
cmd[1] = (offset >> 16) & 0xff;
@@ -118,7 +118,7 @@ static int adesto_write(struct spi_flash *flash,
goto out;
}
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING, "SF: adesto Page Program failed\n");
diff --git a/src/drivers/spi/amic.c b/src/drivers/spi/amic.c
index 4cccc71..63a68a5 100644
--- a/src/drivers/spi/amic.c
+++ b/src/drivers/spi/amic.c
@@ -82,7 +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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
cmd[0] = CMD_A25_PP;
cmd[1] = (offset >> 16) & 0xff;
@@ -100,7 +100,7 @@ static int amic_write(struct spi_flash *flash,
goto out;
}
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING, "SF: AMIC Page Program failed\n");
diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c
index 3fb89c7..783d321 100644
--- a/src/drivers/spi/gigadevice.c
+++ b/src/drivers/spi/gigadevice.c
@@ -141,7 +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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
ret = spi_flash_cmd(flash->spi, CMD_GD25_WREN, NULL, 0);
if (ret < 0) {
@@ -161,7 +161,7 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset,
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
#endif
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING,
diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c
index 3611599..6e910f6 100644
--- a/src/drivers/spi/macronix.c
+++ b/src/drivers/spi/macronix.c
@@ -144,13 +144,12 @@ 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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
cmd[0] = CMD_MX25XX_PP;
cmd[1] = (offset >> 16) & 0xff;
cmd[2] = (offset >> 8) & 0xff;
cmd[3] = offset & 0xff;
-
#if CONFIG_DEBUG_SPI_FLASH
printk(BIOS_SPEW, "PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x }"
" chunk_len = %zu\n",
@@ -163,7 +162,7 @@ static int macronix_write(struct spi_flash *flash,
break;
}
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING, "SF: Macronix Page Program failed\n");
diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c
index c825bd0..bc7969d 100644
--- a/src/drivers/spi/stmicro.c
+++ b/src/drivers/spi/stmicro.c
@@ -155,7 +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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
cmd[0] = CMD_M25PXX_PP;
cmd[1] = (offset >> 16) & 0xff;
@@ -173,7 +173,7 @@ static int stmicro_write(struct spi_flash *flash,
goto out;
}
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING, "SF: STMicro Page Program failed\n");
diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c
index eb0868e..7ddd312 100644
--- a/src/drivers/spi/winbond.c
+++ b/src/drivers/spi/winbond.c
@@ -134,7 +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);
+ chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
cmd[0] = CMD_W25_PP;
cmd[1] = (offset >> 16) & 0xff;
@@ -152,7 +152,7 @@ static int winbond_write(struct spi_flash *flash,
goto out;
}
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
buf + actual, chunk_len);
if (ret < 0) {
printk(BIOS_WARNING, "SF: Winbond Page Program failed\n");
diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h
index 6cdb87a..e92e56c 100644
--- a/src/include/spi-generic.h
+++ b/src/include/spi-generic.h
@@ -181,6 +181,8 @@ void spi_cs_deactivate(struct spi_slave *slave);
*/
void spi_set_speed(struct spi_slave *slave, uint32_t hz);
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len);
+
/*-----------------------------------------------------------------------
* Write 8 bits, then read 8 bits.
* slave: The SPI slave we're communicating with
diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h
index 8e51471..b424b4b 100644
--- a/src/include/spi_flash.h
+++ b/src/include/spi_flash.h
@@ -39,14 +39,6 @@
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
-#define CONFIG_ICH_SPI
-#ifdef CONFIG_ICH_SPI
-#define CONTROLLER_PAGE_LIMIT 64
-#else
-/* any number larger than 4K would do, actually */
-#define CONTROLLER_PAGE_LIMIT ((int)(~0U>>1))
-#endif
-
struct spi_flash {
struct spi_slave *spi;
diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c
index 5ac42c2..b66f6dc 100644
--- a/src/soc/intel/baytrail/spi.c
+++ b/src/soc/intel/baytrail/spi.c
@@ -500,6 +500,11 @@ static int ich_status_poll(u16 bitmask, int wait_til_set)
return -1;
}
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ return min(cntlr.databytes, buf_len);
+}
+
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
@@ -594,7 +599,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
*/
if (trans.bytesout > cntlr.databytes) {
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
- " CONTROLLER_PAGE_LIMIT?\n");
+ " spi_crop_chunk()?\n");
return -1;
}
diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c
index ddec2e0..c12dd52 100644
--- a/src/soc/intel/fsp_baytrail/spi.c
+++ b/src/soc/intel/fsp_baytrail/spi.c
@@ -498,6 +498,11 @@ static int ich_status_poll(u16 bitmask, int wait_til_set)
return -1;
}
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ return min(cntlr.databytes, buf_len);
+}
+
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
@@ -591,7 +596,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
*/
if (trans.bytesout > cntlr.databytes) {
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
- " CONTROLLER_PAGE_LIMIT?\n");
+ " spi_crop_chunk()?\n");
return -1;
}
diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c
index 573dd3d..cf03246 100644
--- a/src/southbridge/amd/agesa/hudson/spi.c
+++ b/src/southbridge/amd/agesa/hudson/spi.c
@@ -86,6 +86,14 @@ void spi_init(void)
spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
}
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ /* Command byte does not consume buffer space. */
+ if (cmd_len)
+ cmd_len--;
+ return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len);
+}
+
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c
index a1cdf55..027ca64 100644
--- a/src/southbridge/amd/cimx/sb800/spi.c
+++ b/src/southbridge/amd/cimx/sb800/spi.c
@@ -56,6 +56,14 @@ void spi_init()
spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
}
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ /* Command byte does not consume buffer space. */
+ if (cmd_len)
+ cmd_len--;
+ return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len);
+}
+
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c
index 51586cc..8db134a 100644
--- a/src/southbridge/intel/common/spi.c
+++ b/src/southbridge/intel/common/spi.c
@@ -551,6 +551,11 @@ static int spi_is_multichip (void)
return !!((cntlr.flmap0 >> 8) & 3);
}
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ return min(cntlr.databytes, buf_len);
+}
+
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
@@ -645,7 +650,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
*/
if (trans.bytesout > cntlr.databytes) {
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
- " CONTROLLER_PAGE_LIMIT?\n");
+ " spi_crop_chunk()?\n");
return -1;
}
More information about the coreboot-gerrit
mailing list