Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 1 | DMA Engine API Guide |
| 2 | ==================== |
| 3 | |
| 4 | Vinod Koul <vinod dot koul at intel.com> |
| 5 | |
| 6 | NOTE: For DMA Engine usage in async_tx please see: |
| 7 | Documentation/crypto/async-tx-api.txt |
| 8 | |
| 9 | |
| 10 | Below is a guide to device driver writers on how to use the Slave-DMA API of the |
| 11 | DMA Engine. This is applicable only for slave DMA usage only. |
| 12 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 13 | The slave DMA usage consists of following steps: |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 14 | 1. Allocate a DMA slave channel |
| 15 | 2. Set slave and controller specific parameters |
| 16 | 3. Get a descriptor for transaction |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 17 | 4. Submit the transaction |
| 18 | 5. Issue pending requests and wait for callback notification |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 19 | |
| 20 | 1. Allocate a DMA slave channel |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 21 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 22 | Channel allocation is slightly different in the slave DMA context, |
| 23 | client drivers typically need a channel from a particular DMA |
| 24 | controller only and even in some cases a specific channel is desired. |
Peter Ujfalusi | a8135d0 | 2015-12-14 22:47:40 +0200 | [diff] [blame] | 25 | To request a channel dma_request_chan() API is used. |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 26 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 27 | Interface: |
Peter Ujfalusi | a8135d0 | 2015-12-14 22:47:40 +0200 | [diff] [blame] | 28 | struct dma_chan *dma_request_chan(struct device *dev, const char *name); |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 29 | |
Peter Ujfalusi | a8135d0 | 2015-12-14 22:47:40 +0200 | [diff] [blame] | 30 | Which will find and return the 'name' DMA channel associated with the 'dev' |
| 31 | device. The association is done via DT, ACPI or board file based |
| 32 | dma_slave_map matching table. |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 33 | |
| 34 | A channel allocated via this interface is exclusive to the caller, |
| 35 | until dma_release_channel() is called. |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 36 | |
| 37 | 2. Set slave and controller specific parameters |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 38 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 39 | Next step is always to pass some specific information to the DMA |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 40 | driver. Most of the generic information which a slave DMA can use |
| 41 | is in struct dma_slave_config. This allows the clients to specify |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 42 | DMA direction, DMA addresses, bus widths, DMA burst lengths etc |
| 43 | for the peripheral. |
| 44 | |
| 45 | If some DMA controllers have more parameters to be sent then they |
| 46 | should try to embed struct dma_slave_config in their controller |
| 47 | specific structure. That gives flexibility to client to pass more |
| 48 | parameters, if required. |
| 49 | |
| 50 | Interface: |
| 51 | int dmaengine_slave_config(struct dma_chan *chan, |
| 52 | struct dma_slave_config *config) |
| 53 | |
| 54 | Please see the dma_slave_config structure definition in dmaengine.h |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 55 | for a detailed explanation of the struct members. Please note |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 56 | that the 'direction' member will be going away as it duplicates the |
| 57 | direction given in the prepare call. |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 58 | |
| 59 | 3. Get a descriptor for transaction |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 60 | |
| 61 | For slave usage the various modes of slave transfers supported by the |
| 62 | DMA-engine are: |
| 63 | |
| 64 | slave_sg - DMA a list of scatter gather buffers from/to a peripheral |
| 65 | dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 66 | operation is explicitly stopped. |
Jassi Brar | b14dab7 | 2011-10-13 12:33:30 +0530 | [diff] [blame] | 67 | interleaved_dma - This is common to Slave as well as M2M clients. For slave |
| 68 | address of devices' fifo could be already known to the driver. |
| 69 | Various types of operations could be expressed by setting |
| 70 | appropriate values to the 'dma_interleaved_template' members. |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 71 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 72 | A non-NULL return of this transfer API represents a "descriptor" for |
| 73 | the given transaction. |
| 74 | |
| 75 | Interface: |
Geert Uytterhoeven | 96cb989 | 2014-06-16 15:13:24 +0200 | [diff] [blame] | 76 | struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 77 | struct dma_chan *chan, struct scatterlist *sgl, |
| 78 | unsigned int sg_len, enum dma_data_direction direction, |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 79 | unsigned long flags); |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 80 | |
Geert Uytterhoeven | 96cb989 | 2014-06-16 15:13:24 +0200 | [diff] [blame] | 81 | struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 82 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
| 83 | size_t period_len, enum dma_data_direction direction); |
| 84 | |
Geert Uytterhoeven | 96cb989 | 2014-06-16 15:13:24 +0200 | [diff] [blame] | 85 | struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma( |
Jassi Brar | b14dab7 | 2011-10-13 12:33:30 +0530 | [diff] [blame] | 86 | struct dma_chan *chan, struct dma_interleaved_template *xt, |
| 87 | unsigned long flags); |
| 88 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 89 | The peripheral driver is expected to have mapped the scatterlist for |
Geert Uytterhoeven | 58d06e9 | 2014-08-20 15:18:44 +0200 | [diff] [blame] | 90 | the DMA operation prior to calling dmaengine_prep_slave_sg(), and must |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 91 | keep the scatterlist mapped until the DMA operation has completed. |
Geert Uytterhoeven | 70c9b8b | 2014-07-11 17:56:21 +0200 | [diff] [blame] | 92 | The scatterlist must be mapped using the DMA struct device. |
| 93 | If a mapping needs to be synchronized later, dma_sync_*_for_*() must be |
| 94 | called using the DMA struct device, too. |
| 95 | So, normal setup should look like this: |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 96 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 97 | nr_sg = dma_map_sg(chan->device->dev, sgl, sg_len); |
| 98 | if (nr_sg == 0) |
| 99 | /* error */ |
Vinod Koul | 46b2903 | 2011-05-25 14:49:20 -0700 | [diff] [blame] | 100 | |
Geert Uytterhoeven | 96cb989 | 2014-06-16 15:13:24 +0200 | [diff] [blame] | 101 | desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags); |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 102 | |
| 103 | Once a descriptor has been obtained, the callback information can be |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 104 | added and the descriptor must then be submitted. Some DMA engine |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 105 | drivers may hold a spinlock between a successful preparation and |
| 106 | submission so it is important that these two operations are closely |
| 107 | paired. |
| 108 | |
| 109 | Note: |
| 110 | Although the async_tx API specifies that completion callback |
| 111 | routines cannot submit any new operations, this is not the |
| 112 | case for slave/cyclic DMA. |
| 113 | |
| 114 | For slave DMA, the subsequent transaction may not be available |
| 115 | for submission prior to callback function being invoked, so |
| 116 | slave DMA callbacks are permitted to prepare and submit a new |
| 117 | transaction. |
| 118 | |
| 119 | For cyclic DMA, a callback function may wish to terminate the |
Lars-Peter Clausen | b36f09c | 2015-10-20 11:46:28 +0200 | [diff] [blame] | 120 | DMA via dmaengine_terminate_async(). |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 121 | |
| 122 | Therefore, it is important that DMA engine drivers drop any |
| 123 | locks before calling the callback function which may cause a |
| 124 | deadlock. |
| 125 | |
| 126 | Note that callbacks will always be invoked from the DMA |
| 127 | engines tasklet, never from interrupt context. |
| 128 | |
| 129 | 4. Submit the transaction |
| 130 | |
| 131 | Once the descriptor has been prepared and the callback information |
| 132 | added, it must be placed on the DMA engine drivers pending queue. |
| 133 | |
| 134 | Interface: |
| 135 | dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc) |
| 136 | |
| 137 | This returns a cookie can be used to check the progress of DMA engine |
| 138 | activity via other DMA engine calls not covered in this document. |
| 139 | |
| 140 | dmaengine_submit() will not start the DMA operation, it merely adds |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 141 | it to the pending queue. For this, see step 5, dma_async_issue_pending. |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 142 | |
| 143 | 5. Issue pending DMA requests and wait for callback notification |
| 144 | |
| 145 | The transactions in the pending queue can be activated by calling the |
| 146 | issue_pending API. If channel is idle then the first transaction in |
| 147 | queue is started and subsequent ones queued up. |
| 148 | |
| 149 | On completion of each DMA operation, the next in queue is started and |
| 150 | a tasklet triggered. The tasklet will then call the client driver |
| 151 | completion callback routine for notification, if set. |
| 152 | |
| 153 | Interface: |
| 154 | void dma_async_issue_pending(struct dma_chan *chan); |
| 155 | |
| 156 | Further APIs: |
| 157 | |
Lars-Peter Clausen | b36f09c | 2015-10-20 11:46:28 +0200 | [diff] [blame] | 158 | 1. int dmaengine_terminate_sync(struct dma_chan *chan) |
| 159 | int dmaengine_terminate_async(struct dma_chan *chan) |
| 160 | int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */ |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 161 | |
| 162 | This causes all activity for the DMA channel to be stopped, and may |
| 163 | discard data in the DMA FIFO which hasn't been fully transferred. |
| 164 | No callback functions will be called for any incomplete transfers. |
| 165 | |
Lars-Peter Clausen | b36f09c | 2015-10-20 11:46:28 +0200 | [diff] [blame] | 166 | Two variants of this function are available. |
| 167 | |
| 168 | dmaengine_terminate_async() might not wait until the DMA has been fully |
| 169 | stopped or until any running complete callbacks have finished. But it is |
| 170 | possible to call dmaengine_terminate_async() from atomic context or from |
| 171 | within a complete callback. dmaengine_synchronize() must be called before it |
| 172 | is safe to free the memory accessed by the DMA transfer or free resources |
| 173 | accessed from within the complete callback. |
| 174 | |
| 175 | dmaengine_terminate_sync() will wait for the transfer and any running |
| 176 | complete callbacks to finish before it returns. But the function must not be |
| 177 | called from atomic context or from within a complete callback. |
| 178 | |
| 179 | dmaengine_terminate_all() is deprecated and should not be used in new code. |
| 180 | |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 181 | 2. int dmaengine_pause(struct dma_chan *chan) |
| 182 | |
| 183 | This pauses activity on the DMA channel without data loss. |
| 184 | |
| 185 | 3. int dmaengine_resume(struct dma_chan *chan) |
| 186 | |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 187 | Resume a previously paused DMA channel. It is invalid to resume a |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 188 | channel which is not currently paused. |
| 189 | |
| 190 | 4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, |
| 191 | dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) |
| 192 | |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 193 | This can be used to check the status of the channel. Please see |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 194 | the documentation in include/linux/dmaengine.h for a more complete |
| 195 | description of this API. |
| 196 | |
| 197 | This can be used in conjunction with dma_async_is_complete() and |
Geert Uytterhoeven | 96cb989 | 2014-06-16 15:13:24 +0200 | [diff] [blame] | 198 | the cookie returned from dmaengine_submit() to check for |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 199 | completion of a specific DMA transaction. |
| 200 | |
| 201 | Note: |
| 202 | Not all DMA engine drivers can return reliable information for |
Vinod Koul | 4dc7b43 | 2016-11-03 07:01:41 -0600 | [diff] [blame] | 203 | a running DMA channel. It is recommended that DMA engine users |
Geert Uytterhoeven | 58d06e9 | 2014-08-20 15:18:44 +0200 | [diff] [blame] | 204 | pause or stop (via dmaengine_terminate_all()) the channel before |
Russell King - ARM Linux | 5a42fb9 | 2011-07-26 14:25:10 +0100 | [diff] [blame] | 205 | using this API. |
Lars-Peter Clausen | b36f09c | 2015-10-20 11:46:28 +0200 | [diff] [blame] | 206 | |
| 207 | 5. void dmaengine_synchronize(struct dma_chan *chan) |
| 208 | |
| 209 | Synchronize the termination of the DMA channel to the current context. |
| 210 | |
| 211 | This function should be used after dmaengine_terminate_async() to synchronize |
| 212 | the termination of the DMA channel to the current context. The function will |
| 213 | wait for the transfer and any running complete callbacks to finish before it |
| 214 | returns. |
| 215 | |
| 216 | If dmaengine_terminate_async() is used to stop the DMA channel this function |
| 217 | must be called before it is safe to free memory accessed by previously |
| 218 | submitted descriptors or to free any resources accessed within the complete |
| 219 | callback of previously submitted descriptors. |
| 220 | |
| 221 | The behavior of this function is undefined if dma_async_issue_pending() has |
| 222 | been called between dmaengine_terminate_async() and this function. |