1 .. SPDX-License-Identifier: GPL-2.0 2 3 ======================= 4 STM32 DMA-MDMA chaining 5 ======================= 6 7 8 Introduction 9 ------------ 10 11 This document describes the STM32 DMA-MDMA c 12 further, let's introduce the peripherals inv 13 14 To offload data transfers from the CPU, STM3 15 direct memory access controllers (DMA). 16 17 STM32MP1 SoCs embed both STM32 DMA and STM32 18 request routing capabilities are enhanced by 19 (STM32 DMAMUX). 20 21 **STM32 DMAMUX** 22 23 STM32 DMAMUX routes any DMA request from a g 24 controller (STM32MP1 counts two STM32 DMA co 25 26 **STM32 DMA** 27 28 STM32 DMA is mainly used to implement centra 29 the system SRAM) for different peripheral. I 30 without the ability to generate convenient b 31 load of the AXI. 32 33 **STM32 MDMA** 34 35 STM32 MDMA (Master DMA) is mainly used to ma 36 RAM data buffers without CPU intervention. I 37 hierarchical structure that uses STM32 DMA a 38 interfaces for AHB peripherals, while the ST 39 DMA with better performance. As a AXI/AHB ma 40 of the AXI/AHB bus. 41 42 43 Principles 44 ---------- 45 46 STM32 DMA-MDMA chaining feature relies on th 47 STM32 MDMA controllers. 48 49 STM32 DMA has a circular Double Buffer Mode 50 (when DMA data counter - DMA_SxNDTR - reache 51 (configured with DMA_SxSM0AR and DMA_SxM1AR) 52 counter is automatically reloaded. This allo 53 process one memory area while the second mem 54 the STM32 DMA transfer. 55 56 With STM32 MDMA linked-list mode, a single r 57 (collection of nodes) to be transferred unti 58 channel is null. The channel transfer comple 59 transfer, unless first and last nodes are li 60 case, the linked-list loops on to create a c 61 62 STM32 MDMA has direct connections with STM32 63 communication and synchronization between pe 64 resources and bus congestion. Transfer Compl 65 can triggers STM32 MDMA transfer. STM32 MDMA 66 by the STM32 DMA by writing to its Interrupt 67 stored in MDMA_CxMAR, and bit mask in MDMA_C 68 69 .. table:: STM32 MDMA interconnect table wit 70 71 +--------------+----------------+--------- 72 | STM32 DMAMUX | STM32 DMA | STM32 DM 73 | channels | channels | Transfer 74 | | | complete 75 | | | signal 76 +==============+================+========= 77 | Channel *0* | DMA1 channel 0 | dma1_tcf 78 +--------------+----------------+--------- 79 | Channel *1* | DMA1 channel 1 | dma1_tcf 80 +--------------+----------------+--------- 81 | Channel *2* | DMA1 channel 2 | dma1_tcf 82 +--------------+----------------+--------- 83 | Channel *3* | DMA1 channel 3 | dma1_tcf 84 +--------------+----------------+--------- 85 | Channel *4* | DMA1 channel 4 | dma1_tcf 86 +--------------+----------------+--------- 87 | Channel *5* | DMA1 channel 5 | dma1_tcf 88 +--------------+----------------+--------- 89 | Channel *6* | DMA1 channel 6 | dma1_tcf 90 +--------------+----------------+--------- 91 | Channel *7* | DMA1 channel 7 | dma1_tcf 92 +--------------+----------------+--------- 93 | Channel *8* | DMA2 channel 0 | dma2_tcf 94 +--------------+----------------+--------- 95 | Channel *9* | DMA2 channel 1 | dma2_tcf 96 +--------------+----------------+--------- 97 | Channel *10* | DMA2 channel 2 | dma2_tcf 98 +--------------+----------------+--------- 99 | Channel *11* | DMA2 channel 3 | dma2_tcf 100 +--------------+----------------+--------- 101 | Channel *12* | DMA2 channel 4 | dma2_tcf 102 +--------------+----------------+--------- 103 | Channel *13* | DMA2 channel 5 | dma2_tcf 104 +--------------+----------------+--------- 105 | Channel *14* | DMA2 channel 6 | dma2_tcf 106 +--------------+----------------+--------- 107 | Channel *15* | DMA2 channel 7 | dma2_tcf 108 +--------------+----------------+--------- 109 110 STM32 DMA-MDMA chaining feature then uses a 111 three fast access static internal RAMs of va 112 Due to STM32 DMA legacy (within microcontrol 113 bad with DDR, while they are optimal with SR 114 between STM32 DMA and STM32 MDMA. This buffe 115 and STM32 DMA uses one period while STM32 MD 116 simultaneously. 117 :: 118 119 dma[1:2]-tcf[0:7] 120 .----------------. 121 ____________ ' _________ V________ 122 | STM32 DMA | / __|>_ \ | STM32 M 123 |------------| | / \ | |-------- 124 | DMA_SxM0AR |<=>| | SRAM | |<=>| []-[].. 125 | DMA_SxM1AR | | \_____/ | | 126 |____________| \___<|____/ |________ 127 128 STM32 DMA-MDMA chaining uses (struct dma_sla 129 exchange the parameters needed to configure 130 gathered into a u32 array with three values: 131 132 * the STM32 MDMA request (which is actually 133 * the address of the STM32 DMA register to c 134 interrupt flag, 135 * the mask of the Transfer Complete interrup 136 137 Device Tree updates for STM32 DMA-MDMA chainin 138 ---------------------------------------------- 139 140 **1. Allocate a SRAM buffer** 141 142 SRAM device tree node is defined in SoC de 143 your board device tree to define your SRAM 144 :: 145 146 &sram { 147 my_foo_device_dma_pool: dma- 148 reg = <0x0 0x1000>; 149 }; 150 }; 151 152 Be careful of the start index, in case the 153 Define your pool size strategically: to op 154 STM32 DMA and STM32 MDMA can work simultan 155 SRAM. 156 If the SRAM period is greater than the exp 157 and STM32 MDMA will work sequentially inst 158 functional issue but it is not optimal. 159 160 Don't forget to refer to your SRAM pool in 161 define a new property. 162 :: 163 164 &my_foo_device { 165 ... 166 my_dma_pool = &my_foo_device 167 }; 168 169 Then get this SRAM pool in your foo driver 170 171 **2. Allocate a STM32 DMA channel and a STM3 172 173 You need to define an extra channel in you 174 the one you should already have for "class 175 176 This new channel must be taken from STM32 177 the DMA controller to use is the MDMA cont 178 :: 179 180 &my_foo_device { 181 [...] 182 my_dma_pool = &my_foo_device 183 dmas = <&dmamux1 ...>, 184 <&mdma1 0 0x3 0x12000 185 }; 186 187 Concerning STM32 MDMA bindings: 188 189 1. The request line number : whatever the 190 by MDMA driver with the STM32 DMAMUX chann 191 (struct dma_slave_config).peripheral_confi 192 193 2. The priority level : choose Very High ( 194 take priority other the other during reque 195 196 3. A 32bit mask specifying the DMA channel 197 destination address increment, block trans 198 transfer 199 200 4. The 32bit value specifying the register 201 request: it will be overwritten by MDMA dr 202 interrupt flag clear register address pass 203 (struct dma_slave_config).peripheral_confi 204 205 5. The 32bit mask specifying the value to 206 request: it will be overwritten by MDMA dr 207 Transfer Complete flag passed through 208 (struct dma_slave_config).peripheral_confi 209 210 Driver updates for STM32 DMA-MDMA chaining sup 211 ---------------------------------------------- 212 213 **0. (optional) Refactor the original sg_tab 214 215 In case of dmaengine_prep_slave_sg(), the 216 is. Two new sg_tables must be created from 217 STM32 DMA transfer (where memory address t 218 of DDR buffer) and one for STM32 MDMA tran 219 the DDR buffer). 220 221 The new sg_list items must fit SRAM period 222 DMA_DEV_TO_MEM: 223 :: 224 225 /* 226 * Assuming sgl and nents, respectively 227 * length. 228 * Assuming sram_dma_buf and sram_perio 229 * allocated from the pool for DMA usag 230 * which is half of the sram_buf size. 231 */ 232 struct sg_table new_dma_sgt, new_mdma_sg 233 struct scatterlist *s, *_sgl; 234 dma_addr_t ddr_dma_buf; 235 u32 new_nents = 0, len; 236 int i; 237 238 /* Count the number of entries needed */ 239 for_each_sg(sgl, s, nents, i) 240 if (sg_dma_len(s) > sram_period) 241 new_nents += DIV_ROUND_U 242 else 243 new_nents++; 244 245 /* Create sg table for STM32 DMA channel 246 ret = sg_alloc_table(&new_dma_sgt, new_n 247 if (ret) 248 dev_err(dev, "DMA sg table alloc 249 250 for_each_sg(new_dma_sgt.sgl, s, new_dma_ 251 _sgl = sgl; 252 sg_dma_len(s) = min(sg_dma_len(_ 253 /* Targets the beginning = first 254 s->dma_address = sram_buf; 255 /* 256 * Targets the second half of t 257 * for odd indexes of the item 258 */ 259 if (i & 1) 260 s->dma_address += sram_p 261 } 262 263 /* Create sg table for STM32 MDMA channe 264 ret = sg_alloc_table(&new_mdma_sgt, new_ 265 if (ret) 266 dev_err(dev, "MDMA sg_table allo 267 268 _sgl = sgl; 269 len = sg_dma_len(sgl); 270 ddr_dma_buf = sg_dma_address(sgl); 271 for_each_sg(mdma_sgt.sgl, s, mdma_sgt.ne 272 size_t bytes = min_t(size_t, len 273 274 sg_dma_len(s) = bytes; 275 sg_dma_address(s) = ddr_dma_buf; 276 len -= bytes; 277 278 if (!len && sg_next(_sgl)) { 279 _sgl = sg_next(_sgl); 280 len = sg_dma_len(_sgl); 281 ddr_dma_buf = sg_dma_add 282 } else { 283 ddr_dma_buf += bytes; 284 } 285 } 286 287 Don't forget to release these new sg_table 288 with dmaengine_prep_slave_sg(). 289 290 **1. Set controller specific parameters** 291 292 First, use dmaengine_slave_config() with a 293 configure STM32 DMA channel. You just have 294 the memory address (depending on the trans 295 SRAM buffer, and set (struct dma_slave_con 296 297 STM32 DMA driver will check (struct dma_sl 298 determine if chaining is being used or not 299 driver fills (struct dma_slave_config).per 300 three u32 : the first one containing STM32 301 the channel interrupt flag clear register 302 channel Transfer Complete flag mask. 303 304 Then, use dmaengine_slave_config with anot 305 configure STM32 MDMA channel. Take care of 306 (depending on the transfer direction) must 307 the memory address must point to the buffe 308 DMA operation. Use the previous (struct dm 309 and .peripheral_config that have been upda 310 (struct dma_slave_config).peripheral_size 311 struct dma_slave_config to configure STM32 312 :: 313 314 struct dma_slave_config dma_conf; 315 struct dma_slave_config mdma_conf; 316 317 memset(&dma_conf, 0, sizeof(dma_conf)); 318 [...] 319 config.direction = DMA_DEV_TO_MEM; 320 config.dst_addr = sram_dma_buf; / 321 config.peripheral_size = 1; / 322 323 dmaengine_slave_config(dma_chan, &dma_co 324 325 memset(&mdma_conf, 0, sizeof(mdma_conf)) 326 config.direction = DMA_DEV_TO_MEM; 327 mdma_conf.src_addr = sram_dma_buf; / 328 mdma_conf.dst_addr = rx_dma_buf; / 329 mdma_conf.peripheral_size = dma_conf.per 330 mdma_conf.peripheral_config = dma_config 331 332 dmaengine_slave_config(mdma_chan, &mdma_ 333 334 **2. Get a descriptor for STM32 DMA channel 335 336 In the same way you get your descriptor fo 337 you just have to replace the original sg_l 338 dmaengine_prep_slave_sg()) with the new sg 339 replace the original buffer address, lengt 340 dmaengine_prep_dma_cyclic()) with the new 341 342 **3. Get a descriptor for STM32 MDMA channel 343 344 If you previously get descriptor (for STM3 345 346 * dmaengine_prep_slave_sg(), then use dmae 347 STM32 MDMA; 348 * dmaengine_prep_dma_cyclic(), then use dm 349 STM32 MDMA. 350 351 Use the new sg_list using SRAM buffer (in 352 or, depending on the transfer direction, e 353 case of DMA_DEV_TO_MEM) or the SRAM buffer 354 source address being previously set with d 355 356 **4. Submit both transactions** 357 358 Before submitting your transactions, you m 359 descriptor you want a callback to be calle 360 (dmaengine_prep_slave_sg()) or the period 361 Depending on the direction, set the callba 362 the overall transfer: 363 364 * DMA_DEV_TO_MEM: set the callback on the 365 * DMA_MEM_TO_DEV: set the callback on the 366 367 Then, submit the descriptors whatever the 368 369 **5. Issue pending requests (and wait for ca 370 371 As STM32 MDMA channel transfer is triggered 372 STM32 MDMA channel before STM32 DMA channel. 373 374 If any, your callback will be called to warn 375 transfer or the period completion. 376 377 Don't forget to terminate both channels. STM 378 cyclic Double-Buffer mode so it won't be dis 379 it. STM32 MDMA channel will be stopped by HW 380 in case of cyclic transfer. You can terminat 381 382 **STM32 DMA-MDMA chaining DMA_MEM_TO_DEV spe 383 384 STM32 DMA-MDMA chaining in DMA_MEM_TO_DEV is 385 STM32 MDMA feeds the SRAM buffer with the DD 386 data from SRAM buffer. So some data (the fir 387 SRAM buffer when the STM32 DMA starts to rea 388 389 A trick could be pausing the STM32 DMA chann 390 Complete signal, triggering the STM32 MDMA c 391 by the STM32 DMA could be "wrong". The prope 392 period with dmaengine_prep_dma_memcpy(). The 393 "removed" from the sg or the cyclic transfer 394 395 Due to this complexity, rather use the STM32 396 DMA_DEV_TO_MEM and keep the "classic" DMA us 397 you're not afraid. 398 399 Resources 400 --------- 401 402 Application note, datasheet and reference ma 403 (STM32MP1_). 404 405 Dedicated focus on three application notes ( 406 dealing with STM32 DMAMUX, STM32 DMA and STM 407 408 .. _STM32MP1: https://www.st.com/en/microcontr 409 .. _AN5224: https://www.st.com/resource/en/app 410 .. _AN4031: https://www.st.com/resource/en/app 411 .. _AN5001: https://www.st.com/resource/en/app 412 413 :Authors: 414 415 - Amelie Delaunay <amelie.delaunay@foss.st.com>
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.