Commit 3373e900 authored by Amelie Delaunay's avatar Amelie Delaunay Committed by Mark Brown

spi: stm32: fix fifo threshold level in case of short transfer

When transfer is shorter than half of the fifo, set the data packet size
up to transfer size instead of up to half of the fifo.
Check also that threshold is set at least to 1 data frame.
Signed-off-by: default avatarAmelie Delaunay <amelie.delaunay@st.com>
Signed-off-by: default avatarAlain Volmat <alain.volmat@st.com>
Link: https://lore.kernel.org/r/1597043558-29668-3-git-send-email-alain.volmat@st.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 135dd873
...@@ -467,20 +467,27 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, ...@@ -467,20 +467,27 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
/** /**
* stm32h7_spi_prepare_fthlv - Determine FIFO threshold level * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
* @spi: pointer to the spi controller data structure * @spi: pointer to the spi controller data structure
* @xfer_len: length of the message to be transferred
*/ */
static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi) static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
{ {
u32 fthlv, half_fifo; u32 fthlv, half_fifo, packet;
/* data packet should not exceed 1/2 of fifo space */ /* data packet should not exceed 1/2 of fifo space */
half_fifo = (spi->fifo_size / 2); half_fifo = (spi->fifo_size / 2);
/* data_packet should not exceed transfer length */
if (half_fifo > xfer_len)
packet = xfer_len;
else
packet = half_fifo;
if (spi->cur_bpw <= 8) if (spi->cur_bpw <= 8)
fthlv = half_fifo; fthlv = packet;
else if (spi->cur_bpw <= 16) else if (spi->cur_bpw <= 16)
fthlv = half_fifo / 2; fthlv = packet / 2;
else else
fthlv = half_fifo / 4; fthlv = packet / 4;
/* align packet size with data registers access */ /* align packet size with data registers access */
if (spi->cur_bpw > 8) if (spi->cur_bpw > 8)
...@@ -488,6 +495,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi) ...@@ -488,6 +495,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
else else
fthlv -= (fthlv % 4); /* multiple of 4 */ fthlv -= (fthlv % 4); /* multiple of 4 */
if (!fthlv)
fthlv = 1;
return fthlv; return fthlv;
} }
...@@ -1393,7 +1403,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi) ...@@ -1393,7 +1403,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) & cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
STM32H7_SPI_CFG1_DSIZE; STM32H7_SPI_CFG1_DSIZE;
spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi); spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen);
fthlv = spi->cur_fthlv - 1; fthlv = spi->cur_fthlv - 1;
cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV; cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
...@@ -1588,6 +1598,8 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, ...@@ -1588,6 +1598,8 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
spin_lock_irqsave(&spi->lock, flags); spin_lock_irqsave(&spi->lock, flags);
spi->cur_xferlen = transfer->len;
if (spi->cur_bpw != transfer->bits_per_word) { if (spi->cur_bpw != transfer->bits_per_word) {
spi->cur_bpw = transfer->bits_per_word; spi->cur_bpw = transfer->bits_per_word;
spi->cfg->set_bpw(spi); spi->cfg->set_bpw(spi);
...@@ -1635,8 +1647,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, ...@@ -1635,8 +1647,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
goto out; goto out;
} }
spi->cur_xferlen = transfer->len;
dev_dbg(spi->dev, "transfer communication mode set to %d\n", dev_dbg(spi->dev, "transfer communication mode set to %d\n",
spi->cur_comm); spi->cur_comm);
dev_dbg(spi->dev, dev_dbg(spi->dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment