原来在e2e上发的问题,tony让我在这边发一下,麻烦帮我解答一下,谢谢。
Part Number: AM3352
Tool/software: Linux
CPU:AM335x
Linux Kernel:4.4.10
I'm working on am335x's dma, my goal is to use a gpio interrupt to trigger a EDMA's mem to mem transfer, that copying 8 bytes from GPMC SRAM to ram.
The trigger gpio is GP2[29], which is a indirect mapped dma event.
I add the dma binding code in dts file:
|
1
2
3
4
5
6
|
dma_test { compatible = status = dmas = <&edma_xbar 32 0 32>; dma-names =}; |
My test code is listed below, I have tried two methods to request a dma channel, but have different result.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
dma_cap_zero(mask); dma_cap_set(DMA_MEMCPY, mask);/* !!!!!!!!!!!!!!!!!!!!!! *//* Method 1: dma_request_channel without any param */ dma_ch = dma_request_channel(mask, 0, NULL);/* Methed 2: dma_request_chan, which can obtain dma channel info. specified in dts file */ dma_ch = dma_request_chan(&pdev->dev, if(dma_ch == NULL) { printk("request_channel failed.\n"); gotoerr; } printk("got dma_ch = 0x%x\n", dma_ch); rxconf.src_addr = ADC_ADDR; rxconf.dst_addr = dma_buf_phys_addr; rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; rxconf.src_maxburst = 1; rxconf.dst_maxburst = 1; rxconf.device_fc = 0; rxconf.slave_id = 0; ret = dmaengine_slave_config(dma_ch, &rxconf); if(ret) gotoerr; printk("dmaengine_slave_config pass.\n"); /* debug: print device struct info */ dma_ch_debug(dma_ch); if(dma_ch->device->device_prep_dma_memcpy == NULL) { printk("device_prep_dma_memcpy = NULL\n"); gotoerr; } tx_desc = dma_ch->device->device_prep_dma_memcpy(dma_ch, dma_buf_phys_addr, ADC_ADDR, 8, DMA_CTRL_ACK | DMA_PREP_INTERRUPT); if(!tx_desc) gotoerr; printk("device_prep_dma_memcpy pass.\n"); tx_desc->callback = dma_callback_func; tx_desc->callback_param = NULL; cookie = tx_desc->tx_submit(tx_desc); if(dma_submit_error(cookie)){ printk(KERN_INFO gotoerr; } printk("tx_submit pass.\n"); dma_async_issue_pending(dma_ch); |
|
1
|
|
When I use dma_request_channel() API, I get a memcpy only dma channel:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[ 1349.049411] Key get value 1[ 1349.060336] read 8 bytes:[ 1349.063125] 00 05 c1 13 0b 60 f0 5b[ 1349.074218] got dma_buf = 0xf0ea8000 dma_buf_phys_addr = 0xbd042000[ 1349.085953] got dma_ch = 0xee9715f0[ 1349.092285] dmaengine_slave_config pass.[ 1349.096434] device = 0xee93dcd0[ 1349.104284] device->chancnt = 2[ 1349.110178] device->dev_id = 1[ 1349.113406] device->dev = 0xee90fa10[ 1349.121617] device->filter = 0x00000000[ 1349.125670] device->cap_mask = 0x601 [ 1349.133862] device->device_config = 0xc02598c4[ 1349.141089] device->device_prep_dma_memcpy=0xc0259938 [ 1349.146424] device->device_prep_slave_sg = 0x00000000 [ 1349.156189] device->device_prep_slave_cyclic = 0x00000000 [ 1349.164455] tx_submit pass.[ 1349.170017] 00 05 c1 13 0b 60 f0 5b |
It can start a mem_to_mem transfer but without GPIO trigger.
The cap_mask is only DMA_MEMCPY, DMA_ASYNC_TX..
When I use dma_request_chanl() API, I get a hw triggered dma channel but it does not have device_prep_dma_memcpy() function registed.
The cap_mask is 0x1E00, which DMA_MEMCPY bit is not set.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[ 1373.798536] Key get value 1[ 1373.810160] read 8 bytes:[ 1373.812952] 00 05 c1 13 0b 60 f0 5b[ 1373.824948] got dma_buf = 0xf0eca000 dma_buf_phys_addr = 0xbd042000[ 1373.834724] got dma_ch = 0xee972310[ 1373.841227] dmaengine_slave_config pass.[ 1373.845376] device = 0xee94f044[ 1373.853261] device->chancnt = 62[ 1373.859267] device->dev_id = 0[ 1373.862495] device->dev = 0xee90fa10[ 1373.866261] device->filter = 0xc025a2bc[ 1373.876557] device->cap_mask = 0x1e00 [ 1373.883061] device->device_config = 0xc02598c4[ 1373.890323] device->device_prep_dma_memcpy=0x00000000 [ 1373.895657] device->device_prep_slave_sg = 0xc0259f8c [ 1373.905423] device->device_prep_slave_cyclic = 0xc0259b90 [ 1373.913609] device_prep_dma_memcpy = NULL |
Question:
能否用dmaengine api实现gpio event触发的mem_to_mem传输?
Eggsy Pang:
可以发整体的文件给我吗?我这边测试一下
DachuanLiu:
回复 Eggsy Pang:
附件是测试代码
有点乱,没怎么整理
有个init_dma函数有两份,一个是从dts申请通道的的,一个是直接request的
dts配置在上面帖子上
DachuanLiu:
回复 Eggsy Pang:
any update?
TI中文支持网