AnsweredAssumed Answered

Looking for example for SDMA from host memory to EIM target using dmaengine API on 3.0.35

Question asked by jayakumar2 on Jul 13, 2015
Latest reply on Jul 15, 2015 by jayakumar2

Hi,

 

I'm using a i.mx6sololite board with 3.0.35 kernel. I've got a working example for memory to memory SDMA working. But I have not been able to get SDMA to an EIM target address working.

 

I took the drivers/char/mxc_sdma_memcopy_test.c example and made the following mods:

        dma_m2m_config.direction = DMA_MEM_TO_DEV;

        dma_m2m_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;

        dmaengine_slave_config(dma_m2m_chan, &dma_m2m_config);

 

So I set DMA_MEM_TO_DEV since this was host to device DMA transfer. My EIM bus is configured for 16-bit width (this works with regular host read/write).

 

        sg_init_table(sg, 1);

        sg_set_buf(&sg[0], wbuf, SDMA_BUF_SIZE);

        ret = dma_map_sg(NULL, sg, 1, dma_m2m_config.direction);

        dma_m2m_desc = dma_m2m_chan->device->device_prep_slave_sg(dma_m2m_chan,sg, 1, dma_m2m_config.direction, 1);

 

Above is my host memory buffer. The wbuf is kzalloced memory. The intention is to have app ioctl and copy_from_userspace.

 

My target address is CS1 EIM. So I do:

        int FPGA_ADDR_BASE = 0x0C000000;

 

        rbuf = ioremap(FPGA_ADDR_BASE, 1024*1024);

        if(!rbuf) {

                printk("error rbuf !!!!!!!!!!!\n");

                return -1;

        }

        printk(KERN_ERR "got rbuf=0x%x\n", rbuf);

 

        sg_init_table(sg2, 1);

        sg_set_buf(&sg2[0], rbuf, SDMA_BUF_SIZE);

        ret = dma_map_sg(NULL, sg2, 1, dma_m2m_config.direction);

        printk(KERN_ERR "%s:%d ret=%d\n", __func__, __LINE__, ret);

        dma_m2m_desc = dma_m2m_chan->device->device_prep_slave_sg(dma_m2m_chan,sg2, 1, dma_m2m_config.direction, 0);

 

But this fails at this point because device_prep_slave_sg returns NULL. When I test, I get:

got rbuf=0xc0c00000

imx-sdma imx-sdma: load_address = 0

imx-sdma imx-sdma: wml = 0x00000000

imx-sdma imx-sdma: shp_addr = 0xbfbbbf60

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000000

imx-sdma imx-sdma: event_mask1 = 0x00000000

sdma_write:215

sdma_write:224

imx-sdma imx-sdma: setting up 1 entries for channel 1.

imx-sdma imx-sdma: load_address = 0

imx-sdma imx-sdma: wml = 0x00000000

imx-sdma imx-sdma: shp_addr = 0xbfbbbf60

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000000

imx-sdma imx-sdma: event_mask1 = 0x00000000

imx-sdma imx-sdma: entry 0: count: 1024 dma: 0x8a002000  intr

sdma_write:227

sdma_write:236 ret=1

sdma_write:239 m2m_desc=  (null)

 

I have not been able to figure out why the prep_slave_sg fails as the ioremaped CS1 address is a valid DMA target.

 

I have attached the source code in case I have made any incorrect assumptions about how this is supposed to work. I tried using dma_m2m_config.dst_addr = rbuf as I was unsure whether setting the sg2 scatterlist is the correct way to specify the destination address but that fails in the same way.

 

Does anyone have an example for SDMA from host to EIM CS1 that is known to work?

 

Thanks!

Original Attachment has been moved to: mxc_sdma_memcopy_test.c.zip

Outcomes