Skip to content

Commit 2ff0fb9

Browse files
ADESTMvinodkoul
authored andcommitted
dmaengine: stm32-dma3: prevent LL refactoring thanks to DT configuration
stm32-dma3 driver refactors the linked-list in order to address the memory with the highest possible data width. It means that it can introduce up to 2 linked-list items. One with a transfer length multiple of channel maximum burst length and so with the highest possible data width. And an extra one with the latest bytes, with lower data width. Some devices (e.g. FMC ECC) don't support having several transfers instead of only one. So add the possibility to prevent linked-list refactoring, when bit 17 of the 'DMA transfer requirements' bit mask is set in device tree. When NOPACK feature is used (bit 16 pf the 'DMA transfer requirements' bit mask in device tree), linked-list refactoring can be avoided, since the memory data width and burst will be aligned with the device ones. Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com> Link: https://lore.kernel.org/r/20241016-dma3-mp25-updates-v3-5-8311fe6f228d@foss.st.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent e18a983 commit 2ff0fb9

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

drivers/dma/stm32/stm32-dma3.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ enum stm32_dma3_port_data_width {
222222
#define STM32_DMA3_DT_PFREQ BIT(9) /* CTR2_PFREQ */
223223
#define STM32_DMA3_DT_TCEM GENMASK(13, 12) /* CTR2_TCEM */
224224
#define STM32_DMA3_DT_NOPACK BIT(16) /* CTR1_PAM */
225+
#define STM32_DMA3_DT_NOREFACT BIT(17)
225226

226227
/* struct stm32_dma3_chan .config_set bitfield */
227228
#define STM32_DMA3_CFG_SET_DT BIT(0)
@@ -1126,10 +1127,13 @@ static void stm32_dma3_free_chan_resources(struct dma_chan *c)
11261127
chan->config_set = 0;
11271128
}
11281129

1129-
static u32 stm32_dma3_get_ll_count(struct stm32_dma3_chan *chan, size_t len)
1130+
static u32 stm32_dma3_get_ll_count(struct stm32_dma3_chan *chan, size_t len, bool prevent_refactor)
11301131
{
11311132
u32 count;
11321133

1134+
if (prevent_refactor)
1135+
return DIV_ROUND_UP(len, STM32_DMA3_MAX_BLOCK_SIZE);
1136+
11331137
count = len / STM32_DMA3_MAX_BLOCK_SIZE;
11341138
len -= (len / STM32_DMA3_MAX_BLOCK_SIZE) * STM32_DMA3_MAX_BLOCK_SIZE;
11351139

@@ -1179,8 +1183,10 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_memcpy(struct dma_cha
11791183
struct stm32_dma3_swdesc *swdesc;
11801184
size_t next_size, offset;
11811185
u32 count, i, ctr1, ctr2;
1186+
bool prevent_refactor = !!FIELD_GET(STM32_DMA3_DT_NOPACK, chan->dt_config.tr_conf) ||
1187+
!!FIELD_GET(STM32_DMA3_DT_NOREFACT, chan->dt_config.tr_conf);
11821188

1183-
count = stm32_dma3_get_ll_count(chan, len);
1189+
count = stm32_dma3_get_ll_count(chan, len, prevent_refactor);
11841190

11851191
swdesc = stm32_dma3_chan_desc_alloc(chan, count);
11861192
if (!swdesc)
@@ -1196,7 +1202,8 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_memcpy(struct dma_cha
11961202
remaining = len - offset;
11971203
next_size = min_t(size_t, remaining, STM32_DMA3_MAX_BLOCK_SIZE);
11981204

1199-
if (next_size < STM32_DMA3_MAX_BLOCK_SIZE && next_size >= chan->max_burst)
1205+
if (!prevent_refactor &&
1206+
(next_size < STM32_DMA3_MAX_BLOCK_SIZE && next_size >= chan->max_burst))
12001207
next_size = chan->max_burst * (remaining / chan->max_burst);
12011208

12021209
ret = stm32_dma3_chan_prep_hw(chan, DMA_MEM_TO_MEM, &swdesc->ccr, &ctr1, &ctr2,
@@ -1235,11 +1242,13 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_slave_sg(struct dma_chan
12351242
size_t len;
12361243
dma_addr_t sg_addr, dev_addr, src, dst;
12371244
u32 i, j, count, ctr1, ctr2;
1245+
bool prevent_refactor = !!FIELD_GET(STM32_DMA3_DT_NOPACK, chan->dt_config.tr_conf) ||
1246+
!!FIELD_GET(STM32_DMA3_DT_NOREFACT, chan->dt_config.tr_conf);
12381247
int ret;
12391248

12401249
count = 0;
12411250
for_each_sg(sgl, sg, sg_len, i)
1242-
count += stm32_dma3_get_ll_count(chan, sg_dma_len(sg));
1251+
count += stm32_dma3_get_ll_count(chan, sg_dma_len(sg), prevent_refactor);
12431252

12441253
swdesc = stm32_dma3_chan_desc_alloc(chan, count);
12451254
if (!swdesc)
@@ -1256,7 +1265,8 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_slave_sg(struct dma_chan
12561265
do {
12571266
size_t chunk = min_t(size_t, len, STM32_DMA3_MAX_BLOCK_SIZE);
12581267

1259-
if (chunk < STM32_DMA3_MAX_BLOCK_SIZE && chunk >= chan->max_burst)
1268+
if (!prevent_refactor &&
1269+
(chunk < STM32_DMA3_MAX_BLOCK_SIZE && chunk >= chan->max_burst))
12601270
chunk = chan->max_burst * (len / chan->max_burst);
12611271

12621272
if (dir == DMA_MEM_TO_DEV) {

0 commit comments

Comments
 (0)