spi: dw: Save bandwidth with the TMOD_TO feature

TMOD_TO is the transmit-only mode that doesn't put data into the receive
FIFO. Using TMOD_TO when the user doesn't want the received data saves
CPU time and memory bandwidth.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
This commit is contained in:
Phil Elwell
2024-07-01 15:49:14 +01:00
committed by Phil Elwell
parent 31b9871b88
commit 6014649de7

View File

@@ -225,12 +225,17 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
* final stage of the transfer. By doing so we'll get the next IRQ * final stage of the transfer. By doing so we'll get the next IRQ
* right when the leftover incoming data is received. * right when the leftover incoming data is received.
*/ */
dw_reader(dws); if (dws->rx_len) {
if (!dws->rx_len) { dw_reader(dws);
dw_spi_mask_intr(dws, 0xff); if (!dws->rx_len) {
dw_spi_mask_intr(dws, 0xff);
spi_finalize_current_transfer(dws->host);
} else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
}
} else if (!dws->tx_len) {
dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
spi_finalize_current_transfer(dws->host); spi_finalize_current_transfer(dws->host);
} else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
} }
/* /*
@@ -239,12 +244,9 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
* have the TXE IRQ flood at the final stage of the transfer. * have the TXE IRQ flood at the final stage of the transfer.
*/ */
if (irq_status & DW_SPI_INT_TXEI) { if (irq_status & DW_SPI_INT_TXEI) {
dw_writer(dws); if (!dws->tx_len)
if (!dws->tx_len) {
dw_spi_mask_intr(dws, DW_SPI_INT_TXEI); dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
if (!dws->rx_len) dw_writer(dws);
spi_finalize_current_transfer(dws->host);
}
} }
return IRQ_HANDLED; return IRQ_HANDLED;
@@ -437,6 +439,11 @@ static int dw_spi_transfer_one(struct spi_controller *host,
dws->rx = transfer->rx_buf; dws->rx = transfer->rx_buf;
dws->rx_len = dws->tx_len; dws->rx_len = dws->tx_len;
if (!dws->rx) {
dws->rx_len = 0;
cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
}
/* Ensure the data above is visible for all CPUs */ /* Ensure the data above is visible for all CPUs */
smp_mb(); smp_mb();