title: Linux DMA API: specifying address increment behavior?
body: <p>I am writing a driver for <a href="http://www.altera.com/products/devkits/altera/kit-cyclone-v-soc.html" rel="nofollow">Altera Soc Developement Kit</a> and need to support two modes of data transfer to/from a FPGA:</p>
  
  <ol>
  <li><strong>FIFO transfers</strong>: When writing to (or reading from) an FPGA FIFO, the destination (or source) address must not be incremented by the DMA controller.</li>
  <li><strong>non-FIFO transfers</strong>:  These are normal (RAM-like) transfers where both the source and destination addresses require an increment for each word transferred.</li>
  </ol>
  
  <p>The particular DMA controller I am using is the CoreLink DMA-330 DMA Controller and its Linux driver is pl330.c (drivers/dma/pl330.c).  This DMA controller does provide a mechanism to switch between "Fixed-address burst" and "Incrementing-address burst" (these are synonymous with my "FIFO transfers" and "non-FIFO transfers").  The pl330 driver specifies which behavior it wants by setting the appropriate bits in the CCRn register</p>
  
  <pre><code>#define CC_SRCINC       (1 &lt;&lt; 0)
  #define CC_DSTINC       (1 &lt;&lt; 14)
  </code></pre>
  
  <p><strong>My question</strong>: it is not at all clear to me how clients of the pl330 (my driver, for example) should specify the address-incrementing behavior.</p>
  
  <p>The <a href="https://www.kernel.org/doc/Documentation/dmaengine/client.txt" rel="nofollow">DMA engine client API</a> says nothing about how to specify this while the <a href="https://www.kernel.org/doc/Documentation/dmaengine/provider.txt" rel="nofollow">DMA engine provider API</a> simply states:</p>
  
  <blockquote>
    <p>Addresses pointing to RAM are typically incremented (or decremented)
    after each transfer. In case of a ring buffer, they may loop
    (DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO)
    are typically fixed.</p>
  </blockquote>
  
  <p>without giving any detail as to how the address types are communicated to providers (in my case the pl300 driver).</p>
  
  <p>The in the pl330_prep_slave_sg method it does:</p>
  
  <pre><code> if (direction == DMA_MEM_TO_DEV) {                  
       desc-&gt;rqcfg.src_inc = 1;                        
       desc-&gt;rqcfg.dst_inc = 0;                        
       desc-&gt;req.rqtype = MEMTODEV;                    
       fill_px(&amp;desc-&gt;px,                              
           addr, sg_dma_address(sg), sg_dma_len(sg));  
   } else {                                            
       desc-&gt;rqcfg.src_inc = 0;                        
       desc-&gt;rqcfg.dst_inc = 1;                        
       desc-&gt;req.rqtype = DEVTOMEM;                    
       fill_px(&amp;desc-&gt;px,                              
           sg_dma_address(sg), addr, sg_dma_len(sg));  
   }    
  </code></pre>
  
  <p>where later, the desc->rqcfg.src_inc, and desc->rqcfg.dst_inc are used by the driver to specify the address-increment behavior.</p>
  
  <p>This implies the following:</p>
  
  <ul>
  <li>Specifying a direction = DMA_MEM_TO_DEV means the client wishes to pull data from a FIFO into RAM.  And presumably DMA_DEV_TO_MEM means the client wishes to push data from RAM into a FIFO.</li>
  <li>Scatter-gather DMA operations (for the pl300 at least) is restricted to cases where either the source or destination end point is a FIFO.  What if I wanted to do a scatter-gather operation from system RAM into FPGA (non-FIFO) memory?</li>
  </ul>
  
  <p>Am I misunderstanding and/or overlooking something?  Does the DMA engine already provide a (undocumented) mechanism to specify address-increment behavior?</p>