Skip to content

Commit 12eb621

Browse files
ADESTMvinodkoul
authored andcommitted
dmaengine: stm32-dma3: prevent pack/unpack thanks to DT configuration
When source data width/burst and destination data width/burst are different, data are packed or unpacked in DMA3 channel FIFO, using CxTR1.PAM. Data are pushed out from DMA3 channel FIFO when the destination burst length (= data width * burst) is reached. If the transfer is stopped before CxBR1.BNDT = 0, and if some bytes are packed/unpacked in the DMA3 channel FIFO, these bytes are lost. Indeed, DMA3 channel FIFO has no flush capability, only reset. To avoid potential bytes lost, pack/unpack must be prevented by setting memory data width/burst equal to peripheral data width/burst. Memory accesses will be penalized. But it is the only way to avoid bytes lost. Prevent pack/unpack feature can be activated by setting bit 16 of DMA3 Transfer requirements bitfield (tr_conf) in device tree. Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com> Link: https://lore.kernel.org/r/20241016-dma3-mp25-updates-v3-2-8311fe6f228d@foss.st.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 689f055 commit 12eb621

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/dma/stm32/stm32-dma3.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ enum stm32_dma3_port_data_width {
221221
#define STM32_DMA3_DT_BREQ BIT(8) /* CTR2_BREQ */
222222
#define STM32_DMA3_DT_PFREQ BIT(9) /* CTR2_PFREQ */
223223
#define STM32_DMA3_DT_TCEM GENMASK(13, 12) /* CTR2_TCEM */
224+
#define STM32_DMA3_DT_NOPACK BIT(16) /* CTR1_PAM */
224225

225226
/* struct stm32_dma3_chan .config_set bitfield */
226227
#define STM32_DMA3_CFG_SET_DT BIT(0)
@@ -622,6 +623,10 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf
622623
/* Set source (memory) data width and burst */
623624
sdw = stm32_dma3_get_max_dw(chan->max_burst, sap_max_dw, len, src_addr);
624625
sbl_max = stm32_dma3_get_max_burst(len, sdw, chan->max_burst);
626+
if (!!FIELD_GET(STM32_DMA3_DT_NOPACK, tr_conf)) {
627+
sdw = ddw;
628+
sbl_max = dbl_max;
629+
}
625630

626631
_ctr1 |= FIELD_PREP(CTR1_SDW_LOG2, ilog2(sdw));
627632
_ctr1 |= FIELD_PREP(CTR1_SBL_1, sbl_max - 1);
@@ -652,6 +657,11 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf
652657
/* Set destination (memory) data width and burst */
653658
ddw = stm32_dma3_get_max_dw(chan->max_burst, dap_max_dw, len, dst_addr);
654659
dbl_max = stm32_dma3_get_max_burst(len, ddw, chan->max_burst);
660+
if (!!FIELD_GET(STM32_DMA3_DT_NOPACK, tr_conf) ||
661+
((_ctr2 & CTR2_PFREQ) && ddw > sdw)) { /* Packing to wider ddw not supported */
662+
ddw = sdw;
663+
dbl_max = sbl_max;
664+
}
655665

656666
_ctr1 |= FIELD_PREP(CTR1_SDW_LOG2, ilog2(sdw));
657667
_ctr1 |= FIELD_PREP(CTR1_SBL_1, sbl_max - 1);

0 commit comments

Comments
 (0)