mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 17:11:02 +01:00
spi: dw: Convert the Tx done delay from SCK cycles to time
Currently the delay in dw_spi_dma_wait_tx_done() is expressed in SCK cycles, which requires passing a valid struct spi_transfer pointer. This does not work for enhanced SPI memory operations, which are not described by a spi_transfer. Compute the delay in ns or us based on an explicit bus speed instead, so that the helper can also be used for those transfers. Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com> Link: https://patch.msgid.link/20260930071535.7947-2-changhuang.liang@starfivetech.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
72d3fcf802
commit
5c99cb1516
|
|
@ -286,19 +286,27 @@ static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws)
|
|||
(DW_SPI_SR_BUSY | DW_SPI_SR_TF_EMPT)) != DW_SPI_SR_TF_EMPT;
|
||||
}
|
||||
|
||||
static int dw_spi_dma_wait_tx_done(struct dw_spi *dws,
|
||||
struct spi_transfer *xfer)
|
||||
static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, u32 speed_hz)
|
||||
{
|
||||
int retry = DW_SPI_WAIT_RETRIES;
|
||||
struct spi_delay delay;
|
||||
unsigned long ns, us;
|
||||
u32 nents;
|
||||
|
||||
nents = dw_readl(dws, DW_SPI_TXFLR);
|
||||
delay.unit = SPI_DELAY_UNIT_SCK;
|
||||
delay.value = nents * dws->n_bytes * BITS_PER_BYTE;
|
||||
ns = DIV_ROUND_UP(NSEC_PER_SEC, speed_hz) * nents *
|
||||
dws->n_bytes * BITS_PER_BYTE;
|
||||
if (ns <= NSEC_PER_USEC) {
|
||||
delay.unit = SPI_DELAY_UNIT_NSECS;
|
||||
delay.value = ns;
|
||||
} else {
|
||||
us = DIV_ROUND_UP(ns, NSEC_PER_USEC);
|
||||
delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
delay.value = clamp_val(us, 0, USHRT_MAX);
|
||||
}
|
||||
|
||||
while (dw_spi_dma_tx_busy(dws) && retry--)
|
||||
spi_delay_exec(&delay, xfer);
|
||||
spi_delay_exec(&delay, NULL);
|
||||
|
||||
if (retry < 0) {
|
||||
dev_err(&dws->ctlr->dev, "Tx hanged up\n");
|
||||
|
|
@ -659,7 +667,7 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer)
|
|||
return ret;
|
||||
|
||||
if (dws->ctlr->cur_msg->status == -EINPROGRESS) {
|
||||
ret = dw_spi_dma_wait_tx_done(dws, xfer);
|
||||
ret = dw_spi_dma_wait_tx_done(dws, xfer->effective_speed_hz);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user