Skip to content

dma_stm32: Transfer Error when using OSPI flash with DMA #96212

@kamnxt

Description

@kamnxt

Describe the bug

I'm using DMA with OSPI on a STM32U5A5, and keep getting transfer errors. The log output seems to suggest that the callback is somehow called before the transfer complete flag is set.

The same setup works fine without DMA configured, and happens less frequently at lower frequencies.

Regression

  • This is a regression.

Steps to reproduce

Build with the dmas and dma-names properties commented out, things work fine.
Build with them uncommented, and the log is spammed with transfer errors.
Lower the ospi-max-frequency (for example all the way down to 5M) and the errors only occur sporadically.

Relevant log output

[00:00:08.350,000] <err> dma_stm32: Transfer Error.
[00:00:08.350,000] <inf> dma_stm32: tc: 0, ht: 0, dte: 0, ule: 0, use: 0
[00:00:08.350,000] <err> flash_stm32_ospi: DMA callback error with channel 12.
[00:00:08.374,000] <err> dma_stm32: Transfer Error.
[00:00:08.374,000] <inf> dma_stm32: tc: 0, ht: 0, dte: 0, ule: 0, use: 0
[00:00:08.374,000] <err> flash_stm32_ospi: DMA callback error with channel 12.

Impact

Functional Limitation – Some features not working as expected, but system usable.

Environment

No response

Additional Context

Using the following DTS:

&octospi1 {
    pinctrl-0 = <&octospim_p1_clk_pf10 &octospim_p1_ncs_pa2
                 &octospim_p1_io0_pf8 &octospim_p1_io1_pf9
                 &octospim_p1_io2_pf7 &octospim_p1_io3_pf6>;
    pinctrl-names = "default";

    dmas = <&gpdma1 12 40 0>; /* OCTOSPI request ID = 40, flags not used */
    dma-names = "tx_rx";

    status = "okay";

    mx25l25645g: ospi-nor-flash@0 {
        compatible = "st,stm32-ospi-nor";
        reg = <0 DT_SIZE_M(32)>;
        ospi-max-frequency = <DT_FREQ_M(50)>;
        /* WP# and RESET# pin used for data lines in QUAD mode,
         * reset-gpios cannot be used in combination.
         */
        spi-bus-width = <OSPI_QUAD_MODE>;
        status = "okay";
        /* Supports DTR (double transfer rate)
         * Flash driver only allows DTR with OPI mode (8 line mode).
         */
        data-rate = <OSPI_STR_TRANSFER>;
        four-byte-opcodes;
    };
};

A coworker suggested he has seen a similar issue on another STM32, where the ISR somehow got called before the flags were set. Adding a small patch to poll the flags a few times before giving up seems to cause the problem to go away:

diff --git a/drivers/dma/dma_stm32u5.c b/drivers/dma/dma_stm32u5.c
index 88ab979df62..76445ac59a7 100644
--- a/drivers/dma/dma_stm32u5.c
+++ b/drivers/dma/dma_stm32u5.c
@@ -265,6 +265,12 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
       }
       callback_arg = id + STM32_DMA_STREAM_OFFSET;
       stream->busy = false;
+      for(int i = 0; i < 100; i++) {
+              if (!(stm32_dma_is_tc_irq_active(dma, id) | stm32_dma_is_ht_irq_active(dma, id))) {
+                      // check the flags a few times, because sometimes the interrupt comes early
+                      // for some reason
+              }
+      }
 
       /* The dma stream id is in range from STM32_DMA_STREAM_OFFSET..<dma-requests> */
       if (stm32_dma_is_ht_irq_active(dma, id)) {

Metadata

Metadata

Assignees

Labels

area: DMADirect Memory AccessbugThe issue is a bug, or the PR is fixing a bugplatform: STM32ST Micro STM32priority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions