2014-12-16 21:05:51

by Andrew Bresticker

[permalink] [raw]
Subject: [PATCH 1/3] spi: img-spfi: Enable controller before starting TX DMA

It is recommended that the SPFI controller be enabled (i.e. setting
SPFI_EN in SPFI_CONTROL) before TX DMA begins.

Signed-off-by: Andrew Bresticker <[email protected]>
---
drivers/spi/spi-img-spfi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 43781c9..e7e79e6 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -390,14 +390,14 @@ static int img_spfi_start_dma(struct spi_master *master,
dma_async_issue_pending(spfi->rx_ch);
}

+ spfi_start(spfi);
+
if (xfer->tx_buf) {
spfi->tx_dma_busy = true;
dmaengine_submit(txdesc);
dma_async_issue_pending(spfi->tx_ch);
}

- spfi_start(spfi);
-
return 1;

stop_dma:
--
2.2.0.rc0.207.ga3a616c


2014-12-16 21:05:52

by Andrew Bresticker

[permalink] [raw]
Subject: [PATCH 2/3] 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: Andrew Bresticker <[email protected]>
---
drivers/spi/spi-img-spfi.c | 49 ++++++++++++++++++----------------------------
1 file changed, 19 insertions(+), 30 deletions(-)

diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index e7e79e6..2b29df0 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -160,16 +160,16 @@ static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf,
unsigned int count = 0;
u32 status;

- while (count < max) {
+ while (count < max / 4) {
spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR);
status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
if (status & SPFI_INTERRUPT_SDFUL)
break;
- spfi_writel(spfi, buf[count / 4], SPFI_TX_32BIT_VALID_DATA);
- count += 4;
+ spfi_writel(spfi, buf[count], SPFI_TX_32BIT_VALID_DATA);
+ count++;
}

- return count;
+ return count * 4;
}

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,
unsigned int count = 0;
u32 status;

- while (count < max) {
+ while (count < max / 4) {
spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT,
SPFI_INTERRUPT_CLEAR);
status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
if (!(status & SPFI_INTERRUPT_GDEX32BIT))
break;
- buf[count / 4] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA);
- count += 4;
+ buf[count] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA);
+ count++;
}

- return count;
+ return count * 4;
}

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,
time_before(jiffies, timeout)) {
unsigned int tx_count, rx_count;

- switch (xfer->bits_per_word) {
- case 32:
+ if (tx_bytes >= 4)
tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes);
- rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes);
- break;
- case 8:
- default:
+ else
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);
- break;
- }

tx_buf += tx_count;
rx_buf += rx_count;
@@ -331,14 +329,11 @@ static int img_spfi_start_dma(struct spi_master *master,

if (xfer->rx_buf) {
rxconf.direction = DMA_DEV_TO_MEM;
- switch (xfer->bits_per_word) {
- case 32:
+ if (xfer->len % 4 == 0) {
rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA;
rxconf.src_addr_width = 4;
rxconf.src_maxburst = 4;
- break;
- case 8:
- default:
+ } else {
rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA;
rxconf.src_addr_width = 1;
rxconf.src_maxburst = 1;
@@ -358,18 +353,14 @@ static int img_spfi_start_dma(struct spi_master *master,

if (xfer->tx_buf) {
txconf.direction = DMA_MEM_TO_DEV;
- switch (xfer->bits_per_word) {
- case 32:
+ if (xfer->len % 4 == 0) {
txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA;
txconf.dst_addr_width = 4;
txconf.dst_maxburst = 4;
- break;
- case 8:
- default:
+ } else {
txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA;
txconf.dst_addr_width = 1;
txconf.dst_maxburst = 1;
- break;
}
dmaengine_slave_config(spfi->tx_ch, &txconf);

@@ -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,
struct spi_transfer *xfer)
{
- if (xfer->bits_per_word == 8 && xfer->len > SPFI_8BIT_FIFO_SIZE)
- return true;
- if (xfer->bits_per_word == 32 && xfer->len > SPFI_32BIT_FIFO_SIZE)
+ if (xfer->len > SPFI_32BIT_FIFO_SIZE)
return true;
return false;
}
--
2.2.0.rc0.207.ga3a616c

2014-12-16 21:06:24

by Andrew Bresticker

[permalink] [raw]
Subject: [PATCH 3/3] spi: img-spfi: Increase DMA burst size

A 1-byte burst size is rather inefficient and has been shown to cause
TX issues during testing. Increase the DMA burst size to 4-bytes for
both RX and TX DMA when using the 8-bit FIFO.

Signed-off-by: Andrew Bresticker <[email protected]>
---
drivers/spi/spi-img-spfi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 2b29df0..29b97f8 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -336,7 +336,7 @@ static int img_spfi_start_dma(struct spi_master *master,
} else {
rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA;
rxconf.src_addr_width = 1;
- rxconf.src_maxburst = 1;
+ rxconf.src_maxburst = 4;
}
dmaengine_slave_config(spfi->rx_ch, &rxconf);

@@ -360,7 +360,7 @@ static int img_spfi_start_dma(struct spi_master *master,
} else {
txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA;
txconf.dst_addr_width = 1;
- txconf.dst_maxburst = 1;
+ txconf.dst_maxburst = 4;
}
dmaengine_slave_config(spfi->tx_ch, &txconf);

--
2.2.0.rc0.207.ga3a616c

2014-12-22 17:52:30

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 1/3] spi: img-spfi: Enable controller before starting TX DMA

On Tue, Dec 16, 2014 at 01:05:44PM -0800, Andrew Bresticker wrote:
> It is recommended that the SPFI controller be enabled (i.e. setting
> SPFI_EN in SPFI_CONTROL) before TX DMA begins.

Applied, thanks.


Attachments:
(No filename) (204.00 B)
signature.asc (473.00 B)
Digital signature
Download all attachments

2014-12-22 17:54:37

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 3/3] spi: img-spfi: Increase DMA burst size

On Tue, Dec 16, 2014 at 01:05:46PM -0800, Andrew Bresticker wrote:

> A 1-byte burst size is rather inefficient and has been shown to cause
> TX issues during testing. Increase the DMA burst size to 4-bytes for
> both RX and TX DMA when using the 8-bit FIFO.

This sounds like a fix for transmit issues so should go before patch 2
(which seems like it is a performance improvement rather than a bug fix)
but it depends on that patch - can you respin in the opposite order
please?


Attachments:
(No filename) (481.00 B)
signature.asc (473.00 B)
Digital signature
Download all attachments

2014-12-22 19:22:41

by Andrew Bresticker

[permalink] [raw]
Subject: Re: [PATCH 3/3] spi: img-spfi: Increase DMA burst size

On Mon, Dec 22, 2014 at 9:54 AM, Mark Brown <[email protected]> wrote:
>
> On Tue, Dec 16, 2014 at 01:05:46PM -0800, Andrew Bresticker wrote:
>
> > A 1-byte burst size is rather inefficient and has been shown to cause
> > TX issues during testing. Increase the DMA burst size to 4-bytes for
> > both RX and TX DMA when using the 8-bit FIFO.
>
> This sounds like a fix for transmit issues so should go before patch 2
> (which seems like it is a performance improvement rather than a bug fix)
> but it depends on that patch - can you respin in the opposite order
> please?

Yes, will do.