Skip to content

Commit

Permalink
spi: stm32: add a delay before SPI disable
Browse files Browse the repository at this point in the history
As explained in errata sheet, in section "2.14.5 Truncation of SPI output
signals after EOT event":
On STM32MP1x, EOT interrupt can be thrown before the true end of
communication.

So we add a delay of a half period to wait the real end of the
transmission.

Link: https://www.st.com/resource/en/errata_sheet/es0539-stm32mp131x3x5x-device-errata-stmicroelectronics.pdf
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
Link: https://lore.kernel.org/r/20230906132735.748174-1-valentin.caron@foss.st.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Valentin Caron authored and Mark Brown committed Sep 11, 2023
1 parent 1849567 commit 6de8a70
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/spi/spi-stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ struct stm32_spi_cfg {
* @fifo_size: size of the embedded fifo in bytes
* @cur_midi: master inter-data idleness in ns
* @cur_speed: speed configured in Hz
* @cur_half_period: time of a half bit in us
* @cur_bpw: number of bits in a single SPI data frame
* @cur_fthlv: fifo threshold level (data frames in a single data packet)
* @cur_comm: SPI communication mode
Expand Down Expand Up @@ -304,6 +305,7 @@ struct stm32_spi {

unsigned int cur_midi;
unsigned int cur_speed;
unsigned int cur_half_period;
unsigned int cur_bpw;
unsigned int cur_fthlv;
unsigned int cur_comm;
Expand Down Expand Up @@ -468,6 +470,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,

spi->cur_speed = spi->clk_rate / (1 << mbrdiv);

spi->cur_half_period = DIV_ROUND_CLOSEST(USEC_PER_SEC, 2 * spi->cur_speed);

return mbrdiv - 1;
}

Expand Down Expand Up @@ -709,6 +713,10 @@ static void stm32h7_spi_disable(struct stm32_spi *spi)
return;
}

/* Add a delay to make sure that transmission is ended. */
if (spi->cur_half_period)
udelay(spi->cur_half_period);

if (spi->cur_usedma && spi->dma_tx)
dmaengine_terminate_async(spi->dma_tx);
if (spi->cur_usedma && spi->dma_rx)
Expand Down

0 comments on commit 6de8a70

Please sign in to comment.