Commit 549858ce authored by Andrew Bresticker's avatar Andrew Bresticker Committed by Mark Brown

spi: img-spfi: Select FIFO based on transfer length

Since the 32-bit FIFO is deeper (64 bytes) than the 8-bit FIFO (16 bytes),
use the 32-bit FIFO when there are at least 32 bits remaining to be
transferred in PIO mode or when the transfer length is 32-bit aligned
in DMA mode.
Signed-off-by: default avatarAndrew Bresticker <abrestic@chromium.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 76fe5e95
...@@ -160,16 +160,16 @@ static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, ...@@ -160,16 +160,16 @@ static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf,
unsigned int count = 0; unsigned int count = 0;
u32 status; u32 status;
while (count < max) { while (count < max / 4) {
spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR);
status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
if (status & SPFI_INTERRUPT_SDFUL) if (status & SPFI_INTERRUPT_SDFUL)
break; break;
spfi_writel(spfi, buf[count / 4], SPFI_TX_32BIT_VALID_DATA); spfi_writel(spfi, buf[count], SPFI_TX_32BIT_VALID_DATA);
count += 4; count++;
} }
return count; return count * 4;
} }
static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf,
...@@ -196,17 +196,17 @@ static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf, ...@@ -196,17 +196,17 @@ static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf,
unsigned int count = 0; unsigned int count = 0;
u32 status; u32 status;
while (count < max) { while (count < max / 4) {
spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT,
SPFI_INTERRUPT_CLEAR); SPFI_INTERRUPT_CLEAR);
status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
if (!(status & SPFI_INTERRUPT_GDEX32BIT)) if (!(status & SPFI_INTERRUPT_GDEX32BIT))
break; break;
buf[count / 4] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA); buf[count] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA);
count += 4; count++;
} }
return count; return count * 4;
} }
static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf,
...@@ -251,17 +251,15 @@ static int img_spfi_start_pio(struct spi_master *master, ...@@ -251,17 +251,15 @@ static int img_spfi_start_pio(struct spi_master *master,
time_before(jiffies, timeout)) { time_before(jiffies, timeout)) {
unsigned int tx_count, rx_count; unsigned int tx_count, rx_count;
switch (xfer->bits_per_word) { if (tx_bytes >= 4)
case 32:
tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes); tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes);
rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes); else
break;
case 8:
default:
tx_count = spfi_pio_write8(spfi, tx_buf, tx_bytes); tx_count = spfi_pio_write8(spfi, tx_buf, tx_bytes);
if (rx_bytes >= 4)
rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes);
else
rx_count = spfi_pio_read8(spfi, rx_buf, rx_bytes); rx_count = spfi_pio_read8(spfi, rx_buf, rx_bytes);
break;
}
tx_buf += tx_count; tx_buf += tx_count;
rx_buf += rx_count; rx_buf += rx_count;
...@@ -331,14 +329,11 @@ static int img_spfi_start_dma(struct spi_master *master, ...@@ -331,14 +329,11 @@ static int img_spfi_start_dma(struct spi_master *master,
if (xfer->rx_buf) { if (xfer->rx_buf) {
rxconf.direction = DMA_DEV_TO_MEM; rxconf.direction = DMA_DEV_TO_MEM;
switch (xfer->bits_per_word) { if (xfer->len % 4 == 0) {
case 32:
rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA;
rxconf.src_addr_width = 4; rxconf.src_addr_width = 4;
rxconf.src_maxburst = 4; rxconf.src_maxburst = 4;
break; } else {
case 8:
default:
rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA;
rxconf.src_addr_width = 1; rxconf.src_addr_width = 1;
rxconf.src_maxburst = 4; rxconf.src_maxburst = 4;
...@@ -358,18 +353,14 @@ static int img_spfi_start_dma(struct spi_master *master, ...@@ -358,18 +353,14 @@ static int img_spfi_start_dma(struct spi_master *master,
if (xfer->tx_buf) { if (xfer->tx_buf) {
txconf.direction = DMA_MEM_TO_DEV; txconf.direction = DMA_MEM_TO_DEV;
switch (xfer->bits_per_word) { if (xfer->len % 4 == 0) {
case 32:
txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA;
txconf.dst_addr_width = 4; txconf.dst_addr_width = 4;
txconf.dst_maxburst = 4; txconf.dst_maxburst = 4;
break; } else {
case 8:
default:
txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA;
txconf.dst_addr_width = 1; txconf.dst_addr_width = 1;
txconf.dst_maxburst = 4; txconf.dst_maxburst = 4;
break;
} }
dmaengine_slave_config(spfi->tx_ch, &txconf); dmaengine_slave_config(spfi->tx_ch, &txconf);
...@@ -508,9 +499,7 @@ static void img_spfi_set_cs(struct spi_device *spi, bool enable) ...@@ -508,9 +499,7 @@ static void img_spfi_set_cs(struct spi_device *spi, bool enable)
static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
if (xfer->bits_per_word == 8 && xfer->len > SPFI_8BIT_FIFO_SIZE) if (xfer->len > SPFI_32BIT_FIFO_SIZE)
return true;
if (xfer->bits_per_word == 32 && xfer->len > SPFI_32BIT_FIFO_SIZE)
return true; return true;
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment