[coreboot-gerrit] Patch set updated for coreboot: 3a82651 SPI: Split writes using spi_crop_chunk()

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Tue Jul 1 09:43:24 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 3a8265160b7589c72e81a0e60973747edde53608
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 | 6 ++++++
 src/southbridge/amd/cimx/sb800/spi.c   | 7 +++++++
 src/southbridge/intel/common/spi.c     | 7 ++++++-
 13 files changed, 45 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..3f3543a 100644
--- a/src/southbridge/amd/agesa/hudson/spi.c
+++ b/src/southbridge/amd/agesa/hudson/spi.c
@@ -42,6 +42,7 @@ static int bus_claimed = 0;
 #define SPI_REG_CNTRL11		0xd
  #define CNTRL11_FIFOPTR_MASK	0x07
 
+#define AMD_SB_SPI_TX_LEN	64
 
 static u32 spibar;
 
@@ -86,6 +87,11 @@ void spi_init(void)
 	spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
 }
 
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_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..f8cea7e 100644
--- a/src/southbridge/amd/cimx/sb800/spi.c
+++ b/src/southbridge/amd/cimx/sb800/spi.c
@@ -32,6 +32,8 @@
 static int bus_claimed = 0;
 #endif
 
+#define AMD_SB_SPI_TX_LEN	8
+
 static u32 spibar;
 
 static void reset_internal_fifo_pointer(void)
@@ -56,6 +58,11 @@ void spi_init()
 	spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
 }
 
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_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