* [PATCH] spi: sirf: send more words at the TX initial phase
@ 2014-05-20 6:07 Barry Song
[not found] ` <1400566068-2781-1-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Barry Song @ 2014-05-20 6:07 UTC (permalink / raw)
To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA
Cc: workgroup.linux-kQvG35nSl+M, Qipan Li, Barry Song
From: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
The old codes use the below flow to do TX: send one word at first, after
this word is finished and TX empty interrupt is generated, send more
words. This causes redundant interrupt overhead at least for the 1st
word.
This patch moves to send as many as possible words at the beginning and
handle TX empty interrupt to send another bundle of words. so interrupt
overhead is decreased.
Signed-off-by: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
Signed-off-by: Barry Song <Baohua.Song-kQvG35nSl+M@public.gmane.org>
---
drivers/spi/spi-sirf.c | 101 ++++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 47 deletions(-)
diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c
index 2d23899..95ac276 100644
--- a/drivers/spi/spi-sirf.c
+++ b/drivers/spi/spi-sirf.c
@@ -86,6 +86,7 @@
#define SIRFSOC_SPI_TX_DONE BIT(1)
#define SIRFSOC_SPI_RX_OFLOW BIT(2)
#define SIRFSOC_SPI_TX_UFLOW BIT(3)
+#define SIRFSOC_SPI_RX_IO_DMA BIT(4)
#define SIRFSOC_SPI_RX_FIFO_FULL BIT(6)
#define SIRFSOC_SPI_TXFIFO_EMPTY BIT(7)
#define SIRFSOC_SPI_RXFIFO_THD_REACH BIT(8)
@@ -265,41 +266,34 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
{
struct sirfsoc_spi *sspi = dev_id;
u32 spi_stat = readl(sspi->base + SIRFSOC_SPI_INT_STATUS);
-
- writel(spi_stat, sspi->base + SIRFSOC_SPI_INT_STATUS);
-
if (sspi->tx_by_cmd && (spi_stat & SIRFSOC_SPI_FRM_END)) {
complete(&sspi->tx_done);
writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
+ writel(SIRFSOC_SPI_INT_MASK_ALL,
+ sspi->base + SIRFSOC_SPI_INT_STATUS);
return IRQ_HANDLED;
}
/* Error Conditions */
if (spi_stat & SIRFSOC_SPI_RX_OFLOW ||
spi_stat & SIRFSOC_SPI_TX_UFLOW) {
+ complete(&sspi->tx_done);
complete(&sspi->rx_done);
writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
+ writel(SIRFSOC_SPI_INT_MASK_ALL,
+ sspi->base + SIRFSOC_SPI_INT_STATUS);
+ return IRQ_HANDLED;
}
+ if (spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY)
+ complete(&sspi->tx_done);
+ while (!(readl(sspi->base + SIRFSOC_SPI_INT_STATUS) &
+ SIRFSOC_SPI_RX_IO_DMA))
+ cpu_relax();
+ complete(&sspi->rx_done);
+ writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
+ writel(SIRFSOC_SPI_INT_MASK_ALL,
+ sspi->base + SIRFSOC_SPI_INT_STATUS);
- if (spi_stat & (SIRFSOC_SPI_FRM_END
- | SIRFSOC_SPI_RXFIFO_THD_REACH))
- while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
- & SIRFSOC_SPI_FIFO_EMPTY)) &&
- sspi->left_rx_word)
- sspi->rx_word(sspi);
-
- if (spi_stat & (SIRFSOC_SPI_TXFIFO_EMPTY |
- SIRFSOC_SPI_TXFIFO_THD_REACH))
- while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
- & SIRFSOC_SPI_FIFO_FULL)) &&
- sspi->left_tx_word)
- sspi->tx_word(sspi);
-
- /* Received all words */
- if ((sspi->left_rx_word == 0) && (sspi->left_tx_word == 0)) {
- complete(&sspi->rx_done);
- writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
- }
return IRQ_HANDLED;
}
@@ -420,32 +414,45 @@ static void spi_sirfsoc_pio_transfer(struct spi_device *spi,
int timeout = t->len * 10;
sspi = spi_master_get_devdata(spi->master);
- writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
- writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
- writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
- writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
- writel(0, sspi->base + SIRFSOC_SPI_INT_EN);
- writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS);
- writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | SIRFSOC_SPI_MUL_DAT_MODE |
- SIRFSOC_SPI_ENA_AUTO_CLR, sspi->base + SIRFSOC_SPI_CTRL);
- writel(sspi->left_tx_word - 1,
- sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN);
- writel(sspi->left_rx_word - 1,
- sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN);
- sspi->tx_word(sspi);
- writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN | SIRFSOC_SPI_TX_UFLOW_INT_EN |
- SIRFSOC_SPI_RX_OFLOW_INT_EN | SIRFSOC_SPI_RXFIFO_THD_INT_EN |
- SIRFSOC_SPI_TXFIFO_THD_INT_EN | SIRFSOC_SPI_FRM_END_INT_EN|
- SIRFSOC_SPI_RXFIFO_FULL_INT_EN,
- sspi->base + SIRFSOC_SPI_INT_EN);
- writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN,
+ do {
+ writel(SIRFSOC_SPI_FIFO_RESET,
+ sspi->base + SIRFSOC_SPI_RXFIFO_OP);
+ writel(SIRFSOC_SPI_FIFO_RESET,
+ sspi->base + SIRFSOC_SPI_TXFIFO_OP);
+ writel(SIRFSOC_SPI_FIFO_START,
+ sspi->base + SIRFSOC_SPI_RXFIFO_OP);
+ writel(SIRFSOC_SPI_FIFO_START,
+ sspi->base + SIRFSOC_SPI_TXFIFO_OP);
+ writel(0, sspi->base + SIRFSOC_SPI_INT_EN);
+ writel(SIRFSOC_SPI_INT_MASK_ALL,
+ sspi->base + SIRFSOC_SPI_INT_STATUS);
+ writel(readl(sspi->base + SIRFSOC_SPI_CTRL) |
+ SIRFSOC_SPI_MUL_DAT_MODE | SIRFSOC_SPI_ENA_AUTO_CLR,
+ sspi->base + SIRFSOC_SPI_CTRL);
+ writel(min(sspi->left_tx_word, (u32)(256 / sspi->word_width))
+ - 1, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN);
+ writel(min(sspi->left_rx_word, (u32)(256 / sspi->word_width))
+ - 1, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN);
+ while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
+ & SIRFSOC_SPI_FIFO_FULL)) && sspi->left_tx_word)
+ sspi->tx_word(sspi);
+ writel(SIRFSOC_SPI_TXFIFO_EMPTY_INT_EN |
+ SIRFSOC_SPI_TX_UFLOW_INT_EN |
+ SIRFSOC_SPI_RX_OFLOW_INT_EN,
+ sspi->base + SIRFSOC_SPI_INT_EN);
+ writel(SIRFSOC_SPI_RX_EN | SIRFSOC_SPI_TX_EN,
sspi->base + SIRFSOC_SPI_TX_RX_EN);
- if (wait_for_completion_timeout(&sspi->rx_done, timeout) == 0)
- dev_err(&spi->dev, "transfer timeout\n");
- writel(0, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
- writel(0, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
- writel(0, sspi->base + SIRFSOC_SPI_TX_RX_EN);
- writel(0, sspi->base + SIRFSOC_SPI_INT_EN);
+ if (!wait_for_completion_timeout(&sspi->tx_done, timeout) ||
+ !wait_for_completion_timeout(&sspi->rx_done, timeout)) {
+ dev_err(&spi->dev, "transfer timeout\n");
+ break;
+ }
+ while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
+ & SIRFSOC_SPI_FIFO_EMPTY)) && sspi->left_rx_word)
+ sspi->rx_word(sspi);
+ writel(0, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
+ writel(0, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
+ } while (sspi->left_tx_word != 0 || sspi->left_rx_word != 0);
}
static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: sirf: send more words at the TX initial phase
[not found] ` <1400566068-2781-1-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-05-20 22:26 ` Mark Brown
[not found] ` <20140520222615.GM12304-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Mark Brown @ 2014-05-20 22:26 UTC (permalink / raw)
To: Barry Song
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, workgroup.linux-kQvG35nSl+M,
Qipan Li, Barry Song
[-- Attachment #1: Type: text/plain, Size: 501 bytes --]
On Tue, May 20, 2014 at 02:07:48PM +0800, Barry Song wrote:
> From: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
>
> The old codes use the below flow to do TX: send one word at first, after
> this word is finished and TX empty interrupt is generated, send more
> words. This causes redundant interrupt overhead at least for the 1st
> word.
This looks very like the patch I just applied before I looked at this
one... is there any difference between the two other than the
changelog?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: sirf: send more words at the TX initial phase
[not found] ` <20140520222615.GM12304-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
@ 2014-05-20 23:26 ` Barry Song
[not found] ` <CAGsJ_4x=+CMWub37Rxk+H+9r0rmO2wpc02cW1nmwzE4cYiakyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Barry Song @ 2014-05-20 23:26 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, DL-SHA-WorkGroupLinux, Qipan Li,
Barry Song
2014-05-21 6:26 GMT+08:00 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> On Tue, May 20, 2014 at 02:07:48PM +0800, Barry Song wrote:
>> From: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
>>
>> The old codes use the below flow to do TX: send one word at first, after
>> this word is finished and TX empty interrupt is generated, send more
>> words. This causes redundant interrupt overhead at least for the 1st
>> word.
>
> This looks very like the patch I just applied before I looked at this
> one... is there any difference between the two other than the
> changelog?
nothing different except commit log.
-barry
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: sirf: send more words at the TX initial phase
[not found] ` <CAGsJ_4x=+CMWub37Rxk+H+9r0rmO2wpc02cW1nmwzE4cYiakyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2014-05-21 11:07 ` Mark Brown
0 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2014-05-21 11:07 UTC (permalink / raw)
To: Barry Song
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, DL-SHA-WorkGroupLinux, Qipan Li,
Barry Song
[-- Attachment #1: Type: text/plain, Size: 402 bytes --]
On Wed, May 21, 2014 at 07:26:41AM +0800, Barry Song wrote:
> 2014-05-21 6:26 GMT+08:00 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> > This looks very like the patch I just applied before I looked at this
> > one... is there any difference between the two other than the
> > changelog?
> nothing different except commit log.
OK, I'll just leave things as they are then - thanks!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-05-21 11:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-20 6:07 [PATCH] spi: sirf: send more words at the TX initial phase Barry Song
[not found] ` <1400566068-2781-1-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-05-20 22:26 ` Mark Brown
[not found] ` <20140520222615.GM12304-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-05-20 23:26 ` Barry Song
[not found] ` <CAGsJ_4x=+CMWub37Rxk+H+9r0rmO2wpc02cW1nmwzE4cYiakyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-05-21 11:07 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).