Hi all,
我们集成了一颗FPGA到系统(通过GPMC总线),现在希望通过dma读取FPGA数据,遇到点问题,如下:
1. 我应该使用哪个DMA通道?
根据TRM 10.3.20,一些通道已经绑定到特定的模块了,所以我只能使用那些没有被绑定的通道,比如通道4,对吗?
2. 如何正确地使用dma api:
bool fpga_dma_filter_fn(struct dma_chan *chan, void *param)
{
int chan_id = *(unsigned int *)param;
if (chan_id == chan->chan_id)
return true;
return false;
}
void dma_init()
{
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
unsigned int id = 4;
gFpgaDmaChan = dma_request_channel(mask, fpga_dma_filter_fn, &id);
}
int fpga_dma_read(dma_addr_t dst, unsigned int len)
{
struct dma_slave_config config;
struct dma_async_tx_descriptor *desc;
unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
config.direction = DMA_DEV_TO_MEM;
config.dst_addr = dst;
config.src_addr = FPGA_PHY_BASE + 6; –> the source address
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
config.dst_maxburst = 16;
config.src_maxburst = 16;
dmaengine_slave_config(gFpgaDmaChan, &config);
desc = dmaengine_prep_slave_single(
gFpgaDmaChan, dst, len, DMA_DEV_TO_MEM, flags);
desc->callback = fpga_dma_callback;
dmaengine_submit(desc);
dma_async_issue_pending(gFpgaDmaChan);
return 1;
}
void fpga_test()
{
dma_addr_t dest;
char *ptr = dma_alloc_coherent(NULL, 1024, &dest, GFP_DMA);
memset(ptr, 0x11, 1024);
fpga_dma_read(dest, 1024);
mdelay(1000);
for (int i=0;i<33;i++){
printk("0x%x ", ptr[i]);
}
}
我在调用fpga_test时候,发现dma仅仅拷贝了config.src_maxburst * config.src_addr_width = 16 * 2 = 32 bytes,然后就停止了,ptr[32]及后面的数据仍为0x11,并且fpga_dma_callback也没有被调用到,是我哪里使用、配置的不对吗?
烦请大牛们帮帮忙啊,谢谢了!!!
Shine:
1. 所有通道都可以用,10.3.20是EDMA的触发事件。2. param参数是如何设置的?
song zhang4:
回复 Shine:
多谢回复!
你说的这个参数是在drivers/dma/dma.c里面设置的吧?
这个还没有看,这个EDMA看起来好复杂,我只是需要使用它而已,现在不清楚是不是使用的api什么的有问题?
我看drivers/mtd/nand/omap2.c里面也差不多是这么使用dma api的。
我测过过Memory To Memory的传输,是正常工作的。
另外,我的Kernel是4.4.19的。
song zhang4:
回复 Shine:
Hi,我打印了下param的设置:
@@@@@@@ acnt: 2, bcnt: 16, opt: 0x4004, src: 0x4000006, a_b_cnt: 0x100002, dst: 0xbc000000, src_dst_bidx: 0x20000, link_bcntrld: 0xffffffff, src_dst_cidx: 0x200000, ccnt: 16
song zhang4:
回复 Shine:
Hi,
我配置了ITCCHEN,这样就可以正确传输了,搜索edma.c,发现只有在edma_prep_dma_memcpy里面才会去配置这个bit,而我们用的是自定义的FPGA,按说这个外设应该和SD卡之类的一样的配置,是不是因为我们自定义的外设没有trigger event?
TI中文支持网