* [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode
@ 2014-05-04 6:32 Qipan Li
2014-05-05 19:23 ` Mark Brown
2014-05-20 22:24 ` Mark Brown
0 siblings, 2 replies; 4+ messages in thread
From: Qipan Li @ 2014-05-04 6:32 UTC (permalink / raw)
To: linux-arm-kernel
From: Qipan Li <Qipan.Li@csr.com>
current PIO tranfer method be described as follows:
1. fill as much as bytes but no more than 256 bytes(fifo size)
2. enable oflow/uflow/txfifo_empty interrupt
3. isr process 3 interrupt signal, do complete works.
4. after isr done, if there are left bytes go into 1 else go into 5
5. transfer end
by current PIO transfer method:
1. reduce interrupt counts in spi interrupt line.
2. reduce interrupt latency because no do data fill/fetch in isr.
Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
-v2
use do {} while statement to replace for(;;) statement pointed by Mark Brown
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
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode
2014-05-04 6:32 [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode Qipan Li
@ 2014-05-05 19:23 ` Mark Brown
2014-05-06 1:10 ` Barry Song
2014-05-20 22:24 ` Mark Brown
1 sibling, 1 reply; 4+ messages in thread
From: Mark Brown @ 2014-05-05 19:23 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, May 04, 2014 at 02:32:36PM +0800, Qipan Li wrote:
> From: Qipan Li <Qipan.Li@csr.com>
>
> current PIO tranfer method be described as follows:
I'm missing patch 1 here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140505/1f2bb0b3/attachment.sig>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode
2014-05-05 19:23 ` Mark Brown
@ 2014-05-06 1:10 ` Barry Song
0 siblings, 0 replies; 4+ messages in thread
From: Barry Song @ 2014-05-06 1:10 UTC (permalink / raw)
To: linux-arm-kernel
2014-05-06 3:23 GMT+08:00 Mark Brown <broonie@kernel.org>:
> On Sun, May 04, 2014 at 02:32:36PM +0800, Qipan Li wrote:
>> From: Qipan Li <Qipan.Li@csr.com>
>>
>> current PIO tranfer method be described as follows:
>
> I'm missing patch 1 here.
this is a follow of "[PATCH 2/2] spi: sirf: decrease the interrupt
count and latency of PIO mode", as you have applied 1/2 - [PATCH 1/2]
spi: sirf: refactor spi transfer functions, so there is no patch 1/2
here.
qipan made a typo , this should be directly a patch but not a 2/2. so
pls take it as a separate patch.
-barry
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode
2014-05-04 6:32 [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode Qipan Li
2014-05-05 19:23 ` Mark Brown
@ 2014-05-20 22:24 ` Mark Brown
1 sibling, 0 replies; 4+ messages in thread
From: Mark Brown @ 2014-05-20 22:24 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, May 04, 2014 at 02:32:36PM +0800, Qipan Li wrote:
> From: Qipan Li <Qipan.Li@csr.com>
>
> current PIO tranfer method be described as follows:
Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140520/1aa98c75/attachment-0001.sig>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-05-20 22:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-04 6:32 [PATCH v2 2/2] spi: sirf: decrease the interrupt count and latency of PIO mode Qipan Li
2014-05-05 19:23 ` Mark Brown
2014-05-06 1:10 ` Barry Song
2014-05-20 22:24 ` 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).