The IMX6DL acquires FPGA data using an EIM port through DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The IMX6DL acquires FPGA data using an EIM port through DMA

633 Views
YangGang1
Contributor I

Hello!

我正在开发一个医疗项目,这个项目的基本信息如下:
I am working on a medical project with the basic information of this project as follows:

kernel:Linux3.0.15
chip:IMX6DL
device:FPGA
requirements:将FPGA采集的数据通过EIM口高效的传递给芯片
(The data collected by the FPGA is efficiently transmitted to the chip through the EIM port)

现已实现FPGA通过EIM口与IMX6DL芯片互通,为了优化传递速度,想要采取DMA传输的方式。现在遇到了一些问题,希望能得到你们的帮助。
Now that the FPGA is interconnected with the IMX6DL chip through the EIM port, DMA transmission is wanted to be adopted in order to optimize the transmission speed. I'm having some problems now, and I hope to get your help.?

 

 

struct dma_data{
    unsigned char *rx_buf;
    struct dma_chan *rx_chan;
};
struct dma_data* dma;
struct completion rx_cmp;
dma_addr_t dma_dst;


//DMA callback
static void rx_callback(void *completion){
    printk("[ko] rx_callback!\n");
    struct completion *cmp = completion;
    complete(cmp);
    dma_unmap_single(NULL, dma_dst, BUFF_SIZE, DMA_FROM_DEVICE);
    return ;
}

//DMA channel filtering
static bool dma_filter(struct dma_chan *chan, void *filter_param){
    if (!imx_dma_is_general_purpose(chan))
	return false;
    chan->private = filter_param;
    printk("dma_filter success chan = %d\n", chan->chan_id);
    return true;
}

{
    int ret;
    dma_cap_mask_t rx_mask;
    struct imx_dma_data rx_data = {0};
    struct dma_slave_config rx_conf = {0};
    struct dma_async_tx_descriptor *rx_desc;
    unsigned char* virt_tmp_buf;

    dma = kzalloc(sizeof(struct dma_data), GFP_KERNEL);
    if (!dma){
        printk("DMA kzalloc failed\n");
        return -ENOMEM;
    }

    dma->rx_buf = kmalloc(BUFF_SIZE,GFP_DMA);
    if (dma->rx_buf == NULL) {
	printk("rx_buf kmalloc faul!\n");
        return -ENOMEM;
    }
    memset(dma->rx_buf, 0, BUFF_SIZE);

    virt_tmp_buf = kmalloc(BUFF_SIZE, GFP_DMA);
    if (virt_tmp_buf == NULL) {
        printk("virt_tmp_buf kmalloc faul!\n");
        return -ENOMEM;
    }
    memset(virt_tmp_buf, 0x33, BUFF_SIZE);

    init_completion(&rx_cmp);
}

 

方案一:内存To内存
The solution 1: memory to memory

 

{
    // 1)Request DMA channel
    dma_cap_zero(rx_mask);     
    dma_cap_set(DMA_MEMCPY, rx_mask);   
    rx_data.peripheral_type = IMX_DMATYPE_MEMORY;  
    rx_data.priority = DMA_PRIO_HIGH;  
    dma->tx_chan = dma_request_channel(rx_mask, dma_filter, &rx_data);
}

 

现象:无法申请到通道
Phenomenon: Unable to apply for channel
Kernel hints:
Nov 8 10:55:33 zhx user.debug kernel: private_candidate: wrong capabilities
Nov 8 10:55:33 zhx user.debug kernel: private_candidate: wrong capabilities
Nov 8 10:55:33 zhx user.debug kernel: __dma_request_channel: fail ((null))
结论:申请通道失败,没必要进行下一步了!
Conclusion: The application channel failed, there is no need to proceed to the next step!

 

方案二:设备To内存
The solution two: device to memory

 

{
    // 1)Request DMA channel
    dma_cap_zero(rx_mask);
    dma_cap_set(DMA_SLAVE, rx_mask);
    rx_data.peripheral_type = IMX_DMATYPE_EXT;
    rx_data.priority = DMA_PRIO_HIGH;
    dma->rx_chan = dma_request_channel(rx_mask, dma_filter, &rx_data);
    if(!dma->rx_chan){
        printk("[****fail****] rx_chan is null\n");	
        return -EINVAL;
    }
    
    // 2)Configure the parameters of the DMA channel
    rx_conf.direction = DMA_FROM_DEVICE;
    //rx_conf.src_addr = FPGA_FIFO_ADDR;
    rx_conf.src_addr = virt_to_phys(virt_tmp_buf);
    rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
    rx_conf.src_maxburst = 1;
    ret = dmaengine_slave_config(dma->rx_chan, &rx_conf);
    if (ret < 0) {
	printk("can't configure rx_chan\n");
	return -1;
    }
	
    // 3)Get transport descriptor
    dma_dst = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, BUFF_SIZE, DMA_FROM_DEVICE);
    if (dma_mapping_error(dma->rx_chan->device->dev, dma_dst)) {
	printk("rx:DMA mapping failed\n");
	goto err_desc;
    }
    rx_desc = dmaengine_prep_slave_single(dma->rx_chan, &dma_dst, BUFF_SIZE, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
    if (!rx_desc) {
	printk("Not able to get desc for DMA xfer\n");
	goto err_desc;
    }
    rx_desc->callback = rx_callback;
    rx_desc->callback_param = &rx_cmp;
    rx_desc->cookie = dmaengine_submit(rx_desc);
    
    // 4)Commit transport descriptor
    if (dma_submit_error(rx_desc->cookie)) {
	printk(" DMA submit failed\n");
	goto err_submit;
    }
    dma_async_issue_pending(dma->rx_chan);
}

 

现象:可以申请到通道dma1chan0
Phenomenon: You can apply to channel DMA1CHAN0
Kernel hints:
Nov 8 11:02:14 zhx user.warn kernel: dma_filter chan = 0
Nov 8 11:02:14 zhx user.debug kernel: __dma_request_channel: success (dma1chan0)
结论:设备的内存空间是我虚拟的一块内存地址,申请通道成功,传输数据是失败的,因为一直未进入回调函数!
Conclusion: The memory space of the device is my virtual memory address, the application channel is successful, and the data transfer is failed because it has not entered the callback function!

 

My question:
1.为什么方案一内存To内存的方式,申请通道会失败!
1. Why does the solution one memory to the memory method, the request channel will fail!

2.为什么方案二设备To内存,传输数据会失败,通道的参数配置,比如:
2. Why does the second device to memory, transfer data will fail, channel parameter configuration.

such as:
​ dma_cap_set(DMA_SLAVE, rx_mask);
​ rx_data.peripheral_type = IMX_DMATYPE_EXT;
​ rx_data.priority = DMA_PRIO_HIGH;
​ 是正确的吗?(That's right?)

这些问题困惑我很久了,如果有大牛知道怎么解决,请协助我!
These problems have puzzled me for a long time, if there are any experts who know how to solve them, please help me!

万分感谢!
Thank you very much!

 
Labels (1)
0 Kudos
3 Replies

621 Views
YangGang1
Contributor I
please help me
0 Kudos

614 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello,

One can use eim interface, for example codes one can

look at attached sdk test and pdf document Chapter 7 Configuring the EIM Driver

clock requirements are the same in multiplexed address/data mode

and timing diagrams can be found in datasheet and RM (EIM chapter).

Regards

0 Kudos

584 Views
YangGang1
Contributor I

Hello

I know how to use EIM, now the problem I have is a problem with DMA, please read my question again and look forward to your reply, thank you!

0 Kudos