From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit e19bdbaa31082b43dab1d936e20efcebc30aa73d ]
DMA operates in Double Buffer Mode (DBM) when the transfer is cyclic and there are at least two periods. When DBM is enabled, the DMA toggles between two memory targets (SxM0AR and SxM1AR), indicated by the SxSCR.CT bit (Current Target). There is no need to update the next memory address if two periods are configured, as SxM0AR and SxM1AR are already properly set up before the transfer begins in the stm32_dma_start_transfer() function. This avoids unnecessary updates to SxM0AR/SxM1AR, thereby preventing potential Transfer Errors. Specifically, when the channel is enabled, SxM0AR and SxM1AR can only be written if SxSCR.CT=1 and SxSCR.CT=0, respectively. Otherwise, a Transfer Error interrupt is triggered, and the stream is automatically disabled.
Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20250624-stm32_dma_dbm_fix-v1-1-337c40d6c93e@foss.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Based on my comprehensive analysis of the commit and the STM32 DMA driver code, here's my assessment:
**Backport Status: YES**
This commit should be backported to stable kernel trees. Here's an extensive explanation based on the code analysis:
## Bug Being Fixed
The commit fixes a **Transfer Error interrupt** issue in the STM32 DMA driver when operating in Double Buffer Mode (DBM) with exactly two periods. The bug manifests as follows:
1. **The Problem**: When DBM is enabled with exactly 2 scatter-gather segments (periods), the driver was unnecessarily calling `stm32_dma_configure_next_sg()` in the interrupt handler (line 748 of stm32_dma_handle_chan_done).
2. **Hardware Constraint**: As explained in the commit message, when the channel is enabled, the memory address registers (SxM0AR and SxM1AR) can only be written when specific conditions are met: - SxM0AR can only be written when CT (Current Target) = 1 - SxM1AR can only be written when CT = 0 - Writing at the wrong time triggers a Transfer Error interrupt
3. **The Fix**: The simple addition of `&& chan->desc->num_sgs > 2` condition prevents unnecessary updates when there are exactly 2 periods, as the hardware automatically toggles between the two pre- configured buffers.
## Why This Is a Good Backport Candidate
1. **Clear Bug Fix**: This fixes a specific hardware-related bug that causes Transfer Error interrupts, which can disrupt DMA operations and potentially cause system instability.
2. **Minimal and Safe Change**: The fix is a single-line conditional check that adds `&& chan->desc->num_sgs > 2` to line 747. This is: - Very small in scope (1 line change) - Low risk of regression - Only affects the specific case of DBM with 2 periods
3. **Hardware-Specific Fix**: The change addresses a specific STM32 DMA hardware behavior documented in the reference manual, making it necessary for proper operation on affected hardware.
4. **No Architectural Changes**: The commit doesn't introduce new features or change the driver's architecture - it simply prevents an unnecessary operation that violates hardware constraints.
5. **Production Impact**: Transfer Error interrupts can cause DMA streams to be automatically disabled (as mentioned in the commit message), leading to data transfer failures in production systems using cyclic DMA with 2 periods.
6. **Clear Error Path**: Looking at the interrupt handler (lines 804-809), unhandled status bits including TEI (Transfer Error Interrupt) result in error messages and potential channel disabling, which this fix prevents.
## Code Analysis Confirms the Fix
From the code analysis: - Line 1207 shows DBM is enabled for multi-period cyclic transfers - Lines 593-595 show initial setup correctly configures both SM0AR and SM1AR - Line 606 shows `stm32_dma_configure_next_sg()` is called during initial transfer setup - The problematic line 748 (now 747) was updating memory addresses unnecessarily for 2-period DBM transfers
The fix ensures that for 2-period DBM transfers, the hardware's automatic toggling mechanism is used without software intervention, preventing Transfer Error interrupts while maintaining correct operation for transfers with more than 2 periods.
drivers/dma/stm32/stm32-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/stm32/stm32-dma.c b/drivers/dma/stm32/stm32-dma.c index 917f8e922373..0e39f99bce8b 100644 --- a/drivers/dma/stm32/stm32-dma.c +++ b/drivers/dma/stm32/stm32-dma.c @@ -744,7 +744,7 @@ static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan, u32 scr) /* cyclic while CIRC/DBM disable => post resume reconfiguration needed */ if (!(scr & (STM32_DMA_SCR_CIRC | STM32_DMA_SCR_DBM))) stm32_dma_post_resume_reconfigure(chan); - else if (scr & STM32_DMA_SCR_DBM) + else if (scr & STM32_DMA_SCR_DBM && chan->desc->num_sgs > 2) stm32_dma_configure_next_sg(chan); } else { chan->busy = false;