summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/spi/spi_flash.c21
-rw-r--r--src/include/spi-generic.h5
-rw-r--r--src/soc/imgtec/pistachio/spi.c57
3 files changed, 46 insertions, 37 deletions
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 7ca6822ba1..baa1f1aeab 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -123,25 +123,8 @@ static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd,
size_t cmd_len, u32 offset,
size_t len, void *data)
{
- while (len) {
- size_t transfer_size;
-
- if (spi->max_transfer_size)
- transfer_size = min(len, spi->max_transfer_size);
- else
- transfer_size = len;
-
- spi_flash_addr(offset, cmd);
-
- if (spi_flash_cmd_read(spi, cmd, cmd_len, data, transfer_size))
- break;
-
- offset += transfer_size;
- data = (void *)((uintptr_t)data + transfer_size);
- len -= transfer_size;
- }
-
- return len != 0;
+ spi_flash_addr(offset, cmd);
+ return spi_flash_cmd_read(spi, cmd, cmd_len, data, len);
}
int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h
index ee02394096..eacb092d1c 100644
--- a/src/include/spi-generic.h
+++ b/src/include/spi-generic.h
@@ -31,15 +31,10 @@
*
* bus: ID of the bus that the slave is attached to.
* cs: ID of the chip select connected to the slave.
- * max_transfer_size: maximum amount of bytes which can be sent in a single
- * read or write transaction, usually this is a controller
- * property, kept in the slave structure for convenience. Zero in
- * this field means 'unlimited'.
*/
struct spi_slave {
unsigned int bus;
unsigned int cs;
- unsigned int max_transfer_size;
int force_programmer_specific;
struct spi_flash * (*programmer_specific_probe) (struct spi_slave *spi);
};
diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c
index 87dd66fd59..2b4b01c3a7 100644
--- a/src/soc/imgtec/pistachio/spi.c
+++ b/src/soc/imgtec/pistachio/spi.c
@@ -445,7 +445,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
img_slave->base = base;
slave->bus = bus;
slave->cs = cs;
- slave->max_transfer_size = IMGTEC_SPI_MAX_TRANSFER_SIZE;
device_parameters->bitrate = 64;
device_parameters->cs_setup = 0;
@@ -509,22 +508,12 @@ void spi_release_bus(struct spi_slave *slave)
}
/* SPI transfer */
-int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout,
- void *din, unsigned int bytesin)
+static int do_spi_xfer(struct spi_slave *slave, const void *dout,
+ unsigned int bytesout, void *din, unsigned int bytesin)
{
struct spim_buffer buff_0;
struct spim_buffer buff_1;
- if (!slave) {
- printk(BIOS_ERR, "%s: Error: slave was not set up.\n",
- __func__);
- return -SPIM_API_NOT_INITIALISED;
- }
- if (!dout && !din) {
- printk(BIOS_ERR, "%s: Error: both buffers are NULL.\n",
- __func__);
- return -SPIM_INVALID_TRANSFER_DESC;
- }
/* If we only have a read or a write operation
* the parameters for it will be put in the first buffer
*/
@@ -543,6 +532,48 @@ int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout,
return spim_io(slave, &buff_0, (dout && din) ? &buff_1 : NULL);
}
+int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout,
+ void *din, unsigned int bytesin)
+{
+ unsigned int in_sz, out_sz;
+ int ret;
+
+ if (!slave) {
+ printk(BIOS_ERR, "%s: Error: slave was not set up.\n",
+ __func__);
+ return -SPIM_API_NOT_INITIALISED;
+ }
+ if (!dout && !din) {
+ printk(BIOS_ERR, "%s: Error: both buffers are NULL.\n",
+ __func__);
+ return -SPIM_INVALID_TRANSFER_DESC;
+ }
+
+ while (bytesin || bytesout) {
+ in_sz = min(IMGTEC_SPI_MAX_TRANSFER_SIZE, bytesin);
+ out_sz = min(IMGTEC_SPI_MAX_TRANSFER_SIZE, bytesout);
+
+ ret = do_spi_xfer(slave, dout, out_sz, din, in_sz);
+ if (ret)
+ return ret;
+
+ bytesin -= in_sz;
+ bytesout -= out_sz;
+
+ if (bytesin)
+ din += in_sz;
+ else
+ din = NULL;
+
+ if (bytesout)
+ dout += out_sz;
+ else
+ dout = NULL;
+ }
+
+ return SPIM_OK;
+}
+
unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
{
return min(IMGTEC_SPI_MAX_TRANSFER_SIZE, buf_len);