Skip to content

Commit 07e7593

Browse files
marckleinebuddebroonie
authored andcommitted
spi: spi-imx: add PIO polling support
The driver supports several modes, one of them is PIO/IRQ "spi_imx_pio_transfer()". The data is exchanged with the IP core using PIO, an IRQ is setup to signal empty/full FIFOs and the end of the transfer. The IRQ and scheduling overhead for short transfers is significant. Using polling instead of IRQs can be beneficial to reduce the overall CPU load, especially on small transfer workloads. On an imx6 single core, a given RX workload of the mcp251xfd driver results in 40% CPU load. Using polling mode reduces the CPU load to 30%. This patch adds PIO polling support to the driver. For transfers with a duration of less than 30 µs the polling mode instead of IRQ based PIO mode is used. 30 µs seems to be a good compromise, which is used the by the SPI drivers for the raspberry Pi (spi-bcm2835, spi-bcm2835), too. Co-developed-by: David Jander <[email protected]> Signed-off-by: David Jander <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 307c897 commit 07e7593

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

drivers/spi/spi-imx.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ static bool use_dma = true;
3131
module_param(use_dma, bool, 0644);
3232
MODULE_PARM_DESC(use_dma, "Enable usage of DMA when available (default)");
3333

34+
/* define polling limits */
35+
static unsigned int polling_limit_us = 30;
36+
module_param(polling_limit_us, uint, 0664);
37+
MODULE_PARM_DESC(polling_limit_us,
38+
"time in us to run a transfer in polling mode\n");
39+
3440
#define MXC_RPM_TIMEOUT 2000 /* 2000ms */
3541

3642
#define MXC_CSPIRXDATA 0x00
@@ -1488,6 +1494,54 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
14881494
return 0;
14891495
}
14901496

1497+
static int spi_imx_poll_transfer(struct spi_device *spi,
1498+
struct spi_transfer *transfer)
1499+
{
1500+
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
1501+
unsigned long timeout;
1502+
1503+
spi_imx->tx_buf = transfer->tx_buf;
1504+
spi_imx->rx_buf = transfer->rx_buf;
1505+
spi_imx->count = transfer->len;
1506+
spi_imx->txfifo = 0;
1507+
spi_imx->remainder = 0;
1508+
1509+
/* fill in the fifo before timeout calculations if we are
1510+
* interrupted here, then the data is getting transferred by
1511+
* the HW while we are interrupted
1512+
*/
1513+
spi_imx_push(spi_imx);
1514+
1515+
timeout = spi_imx_calculate_timeout(spi_imx, transfer->len) + jiffies;
1516+
while (spi_imx->txfifo) {
1517+
/* RX */
1518+
while (spi_imx->txfifo &&
1519+
spi_imx->devtype_data->rx_available(spi_imx)) {
1520+
spi_imx->rx(spi_imx);
1521+
spi_imx->txfifo--;
1522+
}
1523+
1524+
/* TX */
1525+
if (spi_imx->count) {
1526+
spi_imx_push(spi_imx);
1527+
continue;
1528+
}
1529+
1530+
if (spi_imx->txfifo &&
1531+
time_after(jiffies, timeout)) {
1532+
1533+
dev_err_ratelimited(&spi->dev,
1534+
"timeout period reached: jiffies: %lu- falling back to interrupt mode\n",
1535+
jiffies - timeout);
1536+
1537+
/* fall back to interrupt mode */
1538+
return spi_imx_pio_transfer(spi, transfer);
1539+
}
1540+
}
1541+
1542+
return 0;
1543+
}
1544+
14911545
static int spi_imx_pio_transfer_slave(struct spi_device *spi,
14921546
struct spi_transfer *transfer)
14931547
{
@@ -1537,6 +1591,7 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
15371591
struct spi_transfer *transfer)
15381592
{
15391593
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
1594+
unsigned long hz_per_byte, byte_limit;
15401595

15411596
spi_imx_setupxfer(spi, transfer);
15421597
transfer->effective_speed_hz = spi_imx->spi_bus_clk;
@@ -1548,6 +1603,17 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
15481603
if (spi_imx->slave_mode)
15491604
return spi_imx_pio_transfer_slave(spi, transfer);
15501605

1606+
/*
1607+
* Calculate the estimated time in us the transfer runs. Find
1608+
* the number of Hz per byte per polling limit.
1609+
*/
1610+
hz_per_byte = polling_limit_us ? ((8 + 4) * USEC_PER_SEC) / polling_limit_us : 0;
1611+
byte_limit = hz_per_byte ? transfer->effective_speed_hz / hz_per_byte : 1;
1612+
1613+
/* run in polling mode for short transfers */
1614+
if (transfer->len < byte_limit)
1615+
return spi_imx_poll_transfer(spi, transfer);
1616+
15511617
if (spi_imx->usedma)
15521618
return spi_imx_dma_transfer(spi_imx, transfer);
15531619

0 commit comments

Comments
 (0)