Skip to content

Commit

Permalink
spi: stm32: fix fifo threshold level in case of short transfer
Browse files Browse the repository at this point in the history
[ Upstream commit 3373e90 ]

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: Amelie Delaunay <amelie.delaunay@st.com>
Signed-off-by: Alain Volmat <alain.volmat@st.com>
Link: https://lore.kernel.org/r/1597043558-29668-3-git-send-email-alain.volmat@st.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
ADESTM authored and gregkh committed Sep 3, 2020
1 parent 87fb6c0 commit 0e92f6b
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions drivers/spi/spi-stm32.c
Expand Up @@ -468,27 +468,37 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
/**
* stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
* @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 */
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)
fthlv = half_fifo;
fthlv = packet;
else if (spi->cur_bpw <= 16)
fthlv = half_fifo / 2;
fthlv = packet / 2;
else
fthlv = half_fifo / 4;
fthlv = packet / 4;

/* align packet size with data registers access */
if (spi->cur_bpw > 8)
fthlv -= (fthlv % 2); /* multiple of 2 */
else
fthlv -= (fthlv % 4); /* multiple of 4 */

if (!fthlv)
fthlv = 1;

return fthlv;
}

Expand Down Expand Up @@ -1394,7 +1404,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
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;

cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
Expand Down Expand Up @@ -1589,6 +1599,8 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,

spin_lock_irqsave(&spi->lock, flags);

spi->cur_xferlen = transfer->len;

if (spi->cur_bpw != transfer->bits_per_word) {
spi->cur_bpw = transfer->bits_per_word;
spi->cfg->set_bpw(spi);
Expand Down Expand Up @@ -1636,8 +1648,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
goto out;
}

spi->cur_xferlen = transfer->len;

dev_dbg(spi->dev, "transfer communication mode set to %d\n",
spi->cur_comm);
dev_dbg(spi->dev,
Expand Down

0 comments on commit 0e92f6b

Please sign in to comment.