@@ -272,6 +272,173 @@ static void dma_mcux_edma_multi_channels_irq_handler(const struct device *dev, u
272
272
}
273
273
#endif
274
274
275
+ static int dma_mcux_edma_configure_sg_loop (const struct device * dev ,
276
+ uint32_t channel ,
277
+ struct dma_config * config ,
278
+ edma_transfer_type_t transfer_type )
279
+ {
280
+ uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
281
+ edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
282
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
283
+ struct dma_block_config * block_config = config -> head_block ;
284
+ int ret = 0 ;
285
+ edma_tcd_t * tcd = NULL ;
286
+
287
+ /* Loop SG mode */
288
+ data -> transfer_settings .write_idx = 0 ;
289
+ data -> transfer_settings .empty_tcds = CONFIG_DMA_TCD_QUEUE_SIZE ;
290
+
291
+ EDMA_PrepareTransfer (
292
+ & data -> transferConfig , (void * )block_config -> source_address ,
293
+ config -> source_data_size , (void * )block_config -> dest_address ,
294
+ config -> dest_data_size , config -> source_burst_length ,
295
+ block_config -> block_size , transfer_type );
296
+
297
+ /* Init all TCDs with the para in transfer config and link them. */
298
+ for (int i = 0 ; i < CONFIG_DMA_TCD_QUEUE_SIZE ; i ++ ) {
299
+ #if defined(CONFIG_DMA_MCUX_EDMA_V5 )
300
+ EDMA_TcdSetTransferConfigExt (DEV_BASE (dev ),
301
+ & DEV_CFG (dev )-> tcdpool [channel ][i ], & data -> transferConfig ,
302
+ & DEV_CFG (dev )-> tcdpool [channel ][(i + 1 ) %
303
+ CONFIG_DMA_TCD_QUEUE_SIZE ]);
304
+ /* Enable Major loop interrupt.*/
305
+ EDMA_TcdEnableInterruptsExt (DEV_BASE (dev ),
306
+ & DEV_CFG (dev )-> tcdpool [channel ][i ],
307
+ kEDMA_MajorInterruptEnable );
308
+ #else
309
+ EDMA_TcdSetTransferConfig (& DEV_CFG (dev )-> tcdpool [channel ][i ],
310
+ & data -> transferConfig ,
311
+ & DEV_CFG (dev )-> tcdpool [channel ][(i + 1 ) %
312
+ CONFIG_DMA_TCD_QUEUE_SIZE ]);
313
+ EDMA_TcdEnableInterrupts (& DEV_CFG (dev )-> tcdpool [channel ][i ],
314
+ kEDMA_MajorInterruptEnable );
315
+ #endif
316
+ }
317
+
318
+ /* Load valid transfer parameters */
319
+ while (block_config != NULL && data -> transfer_settings .empty_tcds > 0 ) {
320
+ tcd = & (DEV_CFG (dev )-> tcdpool [channel ]
321
+ [data -> transfer_settings .write_idx ]);
322
+
323
+ #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET ) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
324
+ EDMA_TCD_SADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
325
+ MEMORY_ConvertMemoryMapAddress (
326
+ (uint32_t )(block_config -> source_address ),
327
+ kMEMORY_Local2DMA );
328
+ EDMA_TCD_DADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
329
+ MEMORY_ConvertMemoryMapAddress (
330
+ (uint32_t )(block_config -> dest_address ),
331
+ kMEMORY_Local2DMA );
332
+ #else
333
+
334
+ EDMA_TCD_SADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
335
+ block_config -> source_address ;
336
+ EDMA_TCD_DADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
337
+ block_config -> dest_address ;
338
+ #endif
339
+ EDMA_TCD_BITER (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
340
+ block_config -> block_size / config -> source_data_size ;
341
+ EDMA_TCD_CITER (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
342
+ block_config -> block_size / config -> source_data_size ;
343
+ /*Enable auto stop for last transfer.*/
344
+ if (block_config -> next_block == NULL ) {
345
+ EDMA_TCD_CSR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) |=
346
+ DMA_CSR_DREQ (1U );
347
+ } else {
348
+ EDMA_TCD_CSR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) &=
349
+ ~DMA_CSR_DREQ (1U );
350
+ }
351
+
352
+ data -> transfer_settings .write_idx =
353
+ (data -> transfer_settings .write_idx + 1 ) %
354
+ CONFIG_DMA_TCD_QUEUE_SIZE ;
355
+ data -> transfer_settings .empty_tcds -- ;
356
+ block_config = block_config -> next_block ;
357
+ }
358
+
359
+ if (block_config != NULL && data -> transfer_settings .empty_tcds == 0 ) {
360
+ /* User input more blocks than TCD number, return error */
361
+ LOG_ERR ("Too much request blocks,increase TCD buffer size!" );
362
+ ret = - ENOBUFS ;
363
+ }
364
+ /* Push the 1st TCD into HW */
365
+ EDMA_InstallTCD (p_handle -> base , hw_channel ,
366
+ & DEV_CFG (dev )-> tcdpool [channel ][0 ]);
367
+
368
+ return ret ;
369
+ }
370
+
371
+ static int dma_mcux_edma_configure_sg_dynamic (const struct device * dev ,
372
+ uint32_t channel ,
373
+ struct dma_config * config ,
374
+ edma_transfer_type_t transfer_type )
375
+ {
376
+ edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
377
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
378
+ struct dma_block_config * block_config = config -> head_block ;
379
+ int ret = 0 ;
380
+
381
+ /* Dynamic Scatter Gather mode */
382
+ EDMA_InstallTCDMemory (p_handle , DEV_CFG (dev )-> tcdpool [channel ],
383
+ CONFIG_DMA_TCD_QUEUE_SIZE );
384
+
385
+ while (block_config != NULL ) {
386
+ EDMA_PrepareTransfer (& (data -> transferConfig ),
387
+ (void * )block_config -> source_address ,
388
+ config -> source_data_size ,
389
+ (void * )block_config -> dest_address ,
390
+ config -> dest_data_size ,
391
+ config -> source_burst_length ,
392
+ block_config -> block_size , transfer_type );
393
+
394
+ const status_t submit_status =
395
+ EDMA_SubmitTransfer (p_handle , & (data -> transferConfig ));
396
+
397
+ if (submit_status != kStatus_Success ) {
398
+ LOG_ERR ("Error submitting EDMA Transfer: 0x%x" ,
399
+ submit_status );
400
+ ret = - EFAULT ;
401
+ }
402
+ block_config = block_config -> next_block ;
403
+ }
404
+
405
+ return ret ;
406
+ }
407
+
408
+ static int dma_mcux_edma_configure_basic (const struct device * dev ,
409
+ uint32_t channel ,
410
+ struct dma_config * config ,
411
+ edma_transfer_type_t transfer_type )
412
+ {
413
+ edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
414
+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
415
+ struct dma_block_config * block_config = config -> head_block ;
416
+ uint32_t hw_channel ;
417
+ int ret = 0 ;
418
+
419
+ /* block_count shall be 1 */
420
+ LOG_DBG ("block size is: %d" , block_config -> block_size );
421
+ EDMA_PrepareTransfer (& (data -> transferConfig ),
422
+ (void * )block_config -> source_address ,
423
+ config -> source_data_size ,
424
+ (void * )block_config -> dest_address ,
425
+ config -> dest_data_size ,
426
+ config -> source_burst_length ,
427
+ block_config -> block_size , transfer_type );
428
+
429
+ const status_t submit_status = EDMA_SubmitTransfer (p_handle , & (data -> transferConfig ));
430
+
431
+ if (submit_status != kStatus_Success ) {
432
+ LOG_ERR ("Error submitting EDMA Transfer: 0x%x" , submit_status );
433
+ ret = - EFAULT ;
434
+ }
435
+
436
+ LOG_DBG ("DMA TCD CSR 0x%x" , EDMA_HW_TCD_CSR (dev , hw_channel ));
437
+
438
+ return ret ;
439
+ }
440
+
441
+
275
442
/* Configure a channel */
276
443
static int dma_mcux_edma_configure (const struct device * dev , uint32_t channel ,
277
444
struct dma_config * config )
@@ -281,15 +448,15 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
281
448
return - EINVAL ;
282
449
}
283
450
451
+ uint32_t hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
284
452
edma_handle_t * p_handle = DEV_EDMA_HANDLE (dev , channel );
285
453
struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
286
454
struct dma_block_config * block_config = config -> head_block ;
455
+ bool sg_mode = block_config -> source_gather_en || block_config -> dest_scatter_en ;
287
456
uint32_t slot = config -> dma_slot ;
288
- uint32_t hw_channel ;
289
457
edma_transfer_type_t transfer_type ;
290
458
unsigned int key ;
291
459
int ret = 0 ;
292
- edma_tcd_t * tcd = NULL ;
293
460
294
461
if (slot >= DEV_CFG (dev )-> dma_requests ) {
295
462
LOG_ERR ("source number is out of scope %d" , slot );
@@ -301,7 +468,6 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
301
468
return - EINVAL ;
302
469
}
303
470
304
- hw_channel = dma_mcux_edma_add_channel_gap (dev , channel );
305
471
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT ) && FSL_FEATURE_SOC_DMAMUX_COUNT
306
472
uint8_t dmamux_idx , dmamux_channel ;
307
473
@@ -399,132 +565,12 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
399
565
sizeof (DEV_CFG (dev )-> tcdpool [channel ][i ]));
400
566
}
401
567
402
- if (block_config -> source_gather_en || block_config -> dest_scatter_en ) {
403
- if (config -> cyclic ) {
404
- /* Loop SG mode */
405
- data -> transfer_settings .write_idx = 0 ;
406
- data -> transfer_settings .empty_tcds = CONFIG_DMA_TCD_QUEUE_SIZE ;
407
-
408
- EDMA_PrepareTransfer (
409
- & data -> transferConfig , (void * )block_config -> source_address ,
410
- config -> source_data_size , (void * )block_config -> dest_address ,
411
- config -> dest_data_size , config -> source_burst_length ,
412
- block_config -> block_size , transfer_type );
413
-
414
- /* Init all TCDs with the para in transfer config and link them. */
415
- for (int i = 0 ; i < CONFIG_DMA_TCD_QUEUE_SIZE ; i ++ ) {
416
- #if defined(CONFIG_DMA_MCUX_EDMA_V5 )
417
- EDMA_TcdSetTransferConfigExt (DEV_BASE (dev ),
418
- & DEV_CFG (dev )-> tcdpool [channel ][i ], & data -> transferConfig ,
419
- & DEV_CFG (dev )-> tcdpool [channel ][(i + 1 ) %
420
- CONFIG_DMA_TCD_QUEUE_SIZE ]);
421
- /* Enable Major loop interrupt.*/
422
- EDMA_TcdEnableInterruptsExt (DEV_BASE (dev ),
423
- & DEV_CFG (dev )-> tcdpool [channel ][i ],
424
- kEDMA_MajorInterruptEnable );
425
- #else
426
- EDMA_TcdSetTransferConfig (& DEV_CFG (dev )-> tcdpool [channel ][i ],
427
- & data -> transferConfig ,
428
- & DEV_CFG (dev )-> tcdpool [channel ][(i + 1 ) %
429
- CONFIG_DMA_TCD_QUEUE_SIZE ]);
430
- EDMA_TcdEnableInterrupts (& DEV_CFG (dev )-> tcdpool [channel ][i ],
431
- kEDMA_MajorInterruptEnable );
432
- #endif
433
- }
434
-
435
- /* Load valid transfer parameters */
436
- while (block_config != NULL && data -> transfer_settings .empty_tcds > 0 ) {
437
- tcd = & (DEV_CFG (dev )-> tcdpool [channel ]
438
- [data -> transfer_settings .write_idx ]);
439
-
440
- #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET ) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
441
- EDMA_TCD_SADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
442
- MEMORY_ConvertMemoryMapAddress (
443
- (uint32_t )(block_config -> source_address ),
444
- kMEMORY_Local2DMA );
445
- EDMA_TCD_DADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
446
- MEMORY_ConvertMemoryMapAddress (
447
- (uint32_t )(block_config -> dest_address ),
448
- kMEMORY_Local2DMA );
449
- #else
450
-
451
- EDMA_TCD_SADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
452
- block_config -> source_address ;
453
- EDMA_TCD_DADDR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
454
- block_config -> dest_address ;
455
- #endif
456
- EDMA_TCD_BITER (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
457
- block_config -> block_size / config -> source_data_size ;
458
- EDMA_TCD_CITER (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) =
459
- block_config -> block_size / config -> source_data_size ;
460
- /*Enable auto stop for last transfer.*/
461
- if (block_config -> next_block == NULL ) {
462
- EDMA_TCD_CSR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) |=
463
- DMA_CSR_DREQ (1U );
464
- } else {
465
- EDMA_TCD_CSR (tcd , EDMA_TCD_TYPE ((void * )DEV_BASE (dev ))) &=
466
- ~DMA_CSR_DREQ (1U );
467
- }
468
-
469
- data -> transfer_settings .write_idx =
470
- (data -> transfer_settings .write_idx + 1 ) %
471
- CONFIG_DMA_TCD_QUEUE_SIZE ;
472
- data -> transfer_settings .empty_tcds -- ;
473
- block_config = block_config -> next_block ;
474
- }
475
-
476
- if (block_config != NULL && data -> transfer_settings .empty_tcds == 0 ) {
477
- /* User input more blocks than TCD number, return error */
478
- LOG_ERR ("Too much request blocks,increase TCD buffer size!" );
479
- ret = - ENOBUFS ;
480
- }
481
- /* Push the 1st TCD into HW */
482
- EDMA_InstallTCD (p_handle -> base , hw_channel ,
483
- & DEV_CFG (dev )-> tcdpool [channel ][0 ]);
484
-
485
- } else {
486
- /* Dynamic Scatter Gather mode */
487
- EDMA_InstallTCDMemory (p_handle , DEV_CFG (dev )-> tcdpool [channel ],
488
- CONFIG_DMA_TCD_QUEUE_SIZE );
489
-
490
- while (block_config != NULL ) {
491
- EDMA_PrepareTransfer (& (data -> transferConfig ),
492
- (void * )block_config -> source_address ,
493
- config -> source_data_size ,
494
- (void * )block_config -> dest_address ,
495
- config -> dest_data_size ,
496
- config -> source_burst_length ,
497
- block_config -> block_size , transfer_type );
498
-
499
- const status_t submit_status =
500
- EDMA_SubmitTransfer (p_handle , & (data -> transferConfig ));
501
- if (submit_status != kStatus_Success ) {
502
- LOG_ERR ("Error submitting EDMA Transfer: 0x%x" ,
503
- submit_status );
504
- ret = - EFAULT ;
505
- }
506
- block_config = block_config -> next_block ;
507
- }
508
- }
568
+ if (sg_mode && config -> cyclic ) {
569
+ dma_mcux_edma_configure_sg_loop (dev , channel , config , transfer_type );
570
+ } else if (sg_mode ) {
571
+ dma_mcux_edma_configure_sg_dynamic (dev , channel , config , transfer_type );
509
572
} else {
510
- /* block_count shall be 1 */
511
- LOG_DBG ("block size is: %d" , block_config -> block_size );
512
- EDMA_PrepareTransfer (& (data -> transferConfig ),
513
- (void * )block_config -> source_address ,
514
- config -> source_data_size ,
515
- (void * )block_config -> dest_address ,
516
- config -> dest_data_size ,
517
- config -> source_burst_length ,
518
- block_config -> block_size , transfer_type );
519
-
520
- const status_t submit_status =
521
- EDMA_SubmitTransfer (p_handle , & (data -> transferConfig ));
522
- if (submit_status != kStatus_Success ) {
523
- LOG_ERR ("Error submitting EDMA Transfer: 0x%x" , submit_status );
524
- ret = - EFAULT ;
525
- }
526
-
527
- LOG_DBG ("DMA TCD CSR 0x%x" , EDMA_HW_TCD_CSR (dev , hw_channel ));
573
+ dma_mcux_edma_configure_basic (dev , channel , config , transfer_type );
528
574
}
529
575
530
576
if (config -> dest_chaining_en ) {
0 commit comments