This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3352: GPIO triggered DMA transfer

Part Number: AM3352

Tool/software: Linux

Hello,

I have a configuration based on gpevt sample driver mentioned in this thread by Pavel:

https://e2e.ti.com/support/arm/sitara_arm/f/791/t/633610 

This is DMA transfer triggered by GPIO0 pin. This transfer seems to work but only if I submit transfers of 4 bytes.

Pseudocode for configuration (I want to transfer 1024 bytes from 0x10000000 to 0x9f000000 - both are statically configured addresses - first being device mapped to this address range, second being output buffer preconfigured statically):

request_irq()
dma->rx_chan = dma_request_slave_channel(&pdev->dev, "dmarxtx");

dma->rx_conf.dst_addr = dma->dma_buf_phys_addr;
dma->rx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma->rx_conf.dst_maxburst = 1;

ret = dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);

sg_init_table(&dma->sg, 1);
dma->sg.dma_address = SRC_BUFFER_ADDRESS;  
sg_dma_len(&dma->sg) = 4;

dma->tx_desc = dmaengine_prep_slave_sg(dma->rx_chan, &dma->sg, 1, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);

dma->tx_desc->callback = fpgasd_dma_callback_func;
dma->tx_desc->callback_param = &pdev->dev;
dmaengine_submit(dma->tx_desc);

dma_async_issue_pending(dma->rx_chan);

now if I set 

sg_dma_len(&dma->sg) = 4;

then in system log I can see configuration of EDMA:

[ 66.955306] edma 49000000.edma:
[ 66.955306] pset[0]:
[ 66.955306] chnum 22
[ 66.955306] slot 51
[ 66.955306] opt 00116000
[ 66.955306] src 10004000
[ 66.955306] dst 9f000000
[ 66.955306] abcnt 00010004
[ 66.955306] ccnt 00000001
[ 66.955306] bidx 00000004
[ 66.955306] cidx 00000004
[ 66.955306] lkrld ffffffff
[ 66.955401] edma 49000000.edma: first transfer starting on channel 22
[ 66.955428] edma 49000000.edma: ER0 04000000
[ 66.955454] edma 49000000.edma: EER0 08400000

which is what I requested (a,b, c cnt registers of EDMA set to transfer 4 bytes, callback interrupt calling is on). After there is GPIO event transfer is done and interrupt is called:

[ 67.011961] edma 49000000.edma: dma_irq_handler
[ 67.012003] edma 49000000.edma: EER0 08000000
[ 67.012033] edma 49000000.edma: txd db721540[2]: marked complete
[ 67.012061] edma 49000000.edma: Transfer completed on channel 22

So far so good. But then when I want to send 8 bytes:

sg_dma_len(&dma->sg) = 8;

I get this EDMA config:

[ 123.934027] edma 49000000.edma: vchan db141668: txd db5fd9c0[2]: submitted
[ 123.934088] edma 49000000.edma:
[ 123.934088] pset[0]:
[ 123.934088] chnum 22
[ 123.934088] slot 51
[ 123.934088] opt 00116000
[ 123.934088] src 10004000
[ 123.934088] dst 9f000000
[ 123.934088] abcnt 00020004
[ 123.934088] ccnt 00000001
[ 123.934088] bidx 00000004
[ 123.934088] cidx 00000004
[ 123.934088] lkrld ffffffff
[ 123.934184] edma 49000000.edma: first transfer starting on channel 22
[ 123.934210] edma 49000000.edma: ER0 04000000
[ 123.934236] edma 49000000.edma: EER0 08400000

OK for 8 bytes but dma interrupt handler is not called. What might be the reason for this? Any hints are most welcome.