This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM3352:由 GPIO 触发的 GPMC DMA 传输

Guru**** 2553450 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/593810/linux-am3352-gpmc-dma-transfer-triggered-by-gpio

器件型号:AM3352

工具/软件:Linux

CPU:AM335x

Linux 内核:4.4.10

我正在处理 AM335x 的 DMA、我的目标是使用 GPIO 中断来触发 EDMA 的内存到内存传输、该传输将8个字节从 GPMC SRAM 复制到 RAM。

触发 GPIO 为 GP2[29]、这是一个间接映射的 DMA 事件。

我在 DTS 文件中添加了 DMA 绑定代码:

dma_test{
compatible ="cet、AM335x-dma-test";
status ="确定";
DMA =<&EDMA_Xbar 32 0 32>;
dma-names ="dma_test";
}; 

下面列出了我的测试代码、我尝试了两种方法来请求 DMA 通道、但结果不同。

DMA_CAP_ZERO (掩码);
dma_cap_set (dma_memcpy、mask);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
//*方法1:dma_request_channel,不带任何参数*/
dma_ch = dma_request_channel (mask、0、NULL);
//方法2:dma_request_chan、可获取 DMA 通道信息。 在 DTS 文件中指定*/
dma_ch = dma_request_chan (&pdev->dev、"dma_test");//没有地方通过掩码*/

如果(dma_ch ==空)
{
printk ("request_channel failed.\n");
转至错误;
}
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 = dmaenginer_slave_config (dma_ch、&rxconf);
IF (RET)
转至错误;
printk ("dmaenginer_slave_config pass.\n");


/* debug:打印设备结构信息*/
dma_ch_debug (dma_ch);

if (dma_ch->device->device_prep_dma_memcpy = NULL)
{
printk ("device_prep_dma_memcpy = NULL);
转至错误;
}

tx_desc = dma_ch->device->device_prep_dma_memcpy (dma_ch、dma_buf_phys_addr、adc_ADDR、
8、DMA_CTRL_ACK | DMA_PRE_INTERRUPT);
如果(!TX_desc)
转至错误;
printk ("device_prep_dma_memcpy 传递。\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 "无法执行 DMA TX_submit");
转至错误;
}

printk ("TX_submit pass.\n");

dma_async_issee_pending (dma_ch);

当我使用 dma_request_channel() API 时,我会得到一个 memcpy 唯一的 DMA 通道:

[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 = 0xf0b8000 DMA_buf_phys_addr = d042000
[1349.085953] GOT DMA_ma0215d_r_bh
= 0xf8000 DMA_f094285] G_m_de2pass [1349.02951] G_me_v_ma0210_m_mu_mu_
[1349.096434]器件= 0xee93dcd0
[1349.104284]器件-> chancnt = 2
[1349.110178]器件->dev_id = 1
[1349.113406]器件->dev = 0xee90fa10
[1349.121617]器件->过滤器= 0x00000000
[1349.125670]器件= 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 通过。
[1349.170017] 00 05 C1 13 0b 60 f0 5b 

它可以启动一个 mem_to-mem 传输、但没有 GPIO 触发器。
CAP_MASK 仅为 DMA_memcpy、DMA_ASYNC_TX。

当我使用 dma_request_chanl () API 时,我会得到一个硬件触发的 DMA 通道,但它没有注册 device_prep_dma_memcpy()函数。
CAP_MASK 为0x1E00、但未设置 DMA_memcpy 位。

[1373.798536]密钥获取值1
[1373.810160]读取8个字节:
[1373.812952] 00 05 C1 13 0b 60 f0 5b
[1373.824948] GOT DMA_buf = 0xf0eca000 DMA_buf_phys_addr = 137d042000
[1373.834724] GOT DMA_pass
= 0x1373.831227]从引擎[0x27_pass =0x973.8227]。
[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.8757] device= 0x1376557_mask = eCAP //!!
[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 

问题:

如何使用 dmaEngine API 获得事件绑定的 dma_memcpy 通道?