mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 04:04:19 +00:00
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>
This commit is contained in:
parent
689f05586e
commit
12eb621e1a
@ -221,6 +221,7 @@ enum stm32_dma3_port_data_width {
|
||||
#define STM32_DMA3_DT_BREQ BIT(8) /* CTR2_BREQ */
|
||||
#define STM32_DMA3_DT_PFREQ BIT(9) /* CTR2_PFREQ */
|
||||
#define STM32_DMA3_DT_TCEM GENMASK(13, 12) /* CTR2_TCEM */
|
||||
#define STM32_DMA3_DT_NOPACK BIT(16) /* CTR1_PAM */
|
||||
|
||||
/* struct stm32_dma3_chan .config_set bitfield */
|
||||
#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
|
||||
/* Set source (memory) data width and burst */
|
||||
sdw = stm32_dma3_get_max_dw(chan->max_burst, sap_max_dw, len, src_addr);
|
||||
sbl_max = stm32_dma3_get_max_burst(len, sdw, chan->max_burst);
|
||||
if (!!FIELD_GET(STM32_DMA3_DT_NOPACK, tr_conf)) {
|
||||
sdw = ddw;
|
||||
sbl_max = dbl_max;
|
||||
}
|
||||
|
||||
_ctr1 |= FIELD_PREP(CTR1_SDW_LOG2, ilog2(sdw));
|
||||
_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
|
||||
/* Set destination (memory) data width and burst */
|
||||
ddw = stm32_dma3_get_max_dw(chan->max_burst, dap_max_dw, len, dst_addr);
|
||||
dbl_max = stm32_dma3_get_max_burst(len, ddw, chan->max_burst);
|
||||
if (!!FIELD_GET(STM32_DMA3_DT_NOPACK, tr_conf) ||
|
||||
((_ctr2 & CTR2_PFREQ) && ddw > sdw)) { /* Packing to wider ddw not supported */
|
||||
ddw = sdw;
|
||||
dbl_max = sbl_max;
|
||||
}
|
||||
|
||||
_ctr1 |= FIELD_PREP(CTR1_SDW_LOG2, ilog2(sdw));
|
||||
_ctr1 |= FIELD_PREP(CTR1_SBL_1, sbl_max - 1);
|
||||
|
Loading…
Reference in New Issue
Block a user