Hi,
I am trying to do DMA write and read over GPMC between OMAP4460 and Ethernet device. The read and write gpmc data transfer (without DMA) are working. But I am finding DMA transfers issues after the DMA is configured and started, data transfer is not happening.
A similar configration (code reference) is working between AM35xx and FPGA over GPMC in DMA mode on custom board.
From E2E forum topic (http://e2e.ti.com/support/omap/f/849/p/161654/658397.aspx#658397) its mentioned that there is difference between OMAP3 and OMAP4 DMA. But it did not throw any light on solving this issue.
I tried OMAP24XX_DMA_GPMC trigger in omap_request_dma() for requesting the channel ( channel 0 assigned for the transfer) and in omap_set_dma_transfer_params() for setting DMA transfer. Then I don't see the DMA callback getting called and and its unable to finish the DMA transfer.
I also tried DMA_NO_DEVICE trigger. But it crashes on OMAP4.
I tried a simple mem->mem transfer using the OMAP24XX_DMA_GPMC trigger. That also had the same issue.
Let me know, If I am missing anything on OMAP4 DMA setup.
My configurations look like these:
ret = omap_request_dma(OMAP24XX_DMA_GPMC, "xxxx", callback_fn, &info->comp, &info->dma_ch);
dma_transfer_func()
{
dma_addr = dma_map_single(&info->pdev->dev, info->dma_buf, len,dir);
if (dma_mapping_error(&global_info->pdev->dev, dma_addr)) {
printk("Couldn't DMA map a %d byte buffer\n", len);
goto out_copy;
}
if (is_write) {
omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
buf, 0, 0);
omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
dma_addr, 0, 0);
omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S16,
0x10, buf_len, OMAP_DMA_SYNC_FRAME,
OMAP24XX_DMA_GPMC, OMAP_DMA_DST_SYNC);
} else {
omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
buf, 0, 0);
omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
dma_addr, 0, 0);
omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S16,
0x10, buf_len, OMAP_DMA_SYNC_FRAME,
OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC);
}
init_completion(&info->comp);
omap_start_dma(info->dma_ch);
/* setup and start DMA using dma_addr */
wait_for_completion(&info->comp);
}
My callback fn:
callback_fn(int lch, u16 ch_status, void *data)
{
struct completion *comp = data;
complete (comp);
dma_unmap_single(&info->pdev->dev, info->dma_addr, len, info->dma_dir);
omap_stop_dma(info->dma_ch);
}
I have also tried BURST_MODE but that also didnt work. The configurations i used were:
omap_set_dma_src_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_8);
omap_set_dma_dest_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_8);
omap_set_dma_write_mode (info->dma_ch, OMAP_DMA_WRITE_NON_POSTED);
omap_set_dma_src_data_pack(info->dma_ch, 1);
omap_set_dma_dest_data_pack(info->dma_ch, 1);
omap_dma_set_prio_lch(info->dma_ch, DMA_CH_PRIO_HIGH, DMA_CH_PRIO_HIGH);
I'm using kernel version 3.0.8
Any help is appreciated. Thanks in advance.