Additionally, we tested:
Looking at the fsl-edma.c code of the LSDK1812 I am using,
It seems to support device_prep_slave_sg and device_prep_dma_cyclic.
dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
So, I have written as follows.
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE,mask);
dma_chan = dma_request_channel(mask,0,NULL);
if(dma_chan == 0) printk("failed to request DMA channel\n");
else printk("passed to request DMA channel %d\n", dma_chan->chan_id);
I have been assigned an ID without any issues.
static ssize_t dma_memcpy_sg(uint64_t paddr_dst, uint64_t paddr_src, size_t count)
{
struct dma_async_tx_descriptor *tx_desc = NULL;
struct dma_device *dma_dev = dma_chan->device;
dma_cookie_t cookie;
int ret, src_cnt = 1;
enum dma_transfer_direction dir = DMA_DEV_TO_MEM;
struct scatterlist sg;
struct dma_slave_config dma_config;
/* Configure the slave DMA */
memset(&dma_config, 0, sizeof(dma_config));
dma_config.direction = DMA_DEV_TO_MEM;
dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_config.src_addr = dma_buf_handle_tx;
dma_config.src_maxburst = 1;
//ret = dmaengine_slave_config(dma_chan, &dma_config);
ret = dma_dev->device_config(dma_chan, &dma_config);
if (ret) {
pr_err("Failed to configure DMA slave\n");
}
sg_init_table(&sg, src_cnt);
sg_dma_address(&sg) = (uint64_t)paddr_dst;
sg_dma_len(&sg) = count;
//tx_desc = dmaengine_prep_slave_sg(dma_chan,
tx_desc = dma_dev->device_prep_slave_sg(dma_chan,
&sg,
src_cnt,
dir,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK, NULL);
if (!tx_desc) {
pr_err("[%d]Failed to prepare DMA memcpy\n", __LINE__);
return -1;
}
tx_desc->callback = complete_rx_dma;
//cookie = dmaengine_submit(tx_desc);
cookie = tx_desc->tx_submit(tx_desc);
if (dma_submit_error(cookie)) {
pr_err("[%d]Failed to do DMA tx_submit\n",__LINE__);
return -1;
}
dma_async_issue_pending(dma_chan);
}
When I execute the dma_memcpy_sg function, there are no pr_err messages, and there is no increase in the edma interrupt in /proc/interrupt. I'm not able to perform the copy, so I would appreciate some advice on what could be the problem.
Thanks,
Gyosun.