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 | |
| 13 | The slave DMA usage consists of following steps |
| 14 | 1. Allocate a DMA slave channel |
| 15 | 2. Set slave and controller specific parameters |
| 16 | 3. Get a descriptor for transaction |
| 17 | 4. Submit the transaction and wait for callback notification |
| 18 | |
| 19 | 1. Allocate a DMA slave channel |
| 20 | Channel allocation is slightly different in the slave DMA context, client |
| 21 | drivers typically need a channel from a particular DMA controller only and even |
| 22 | in some cases a specific channel is desired. To request a channel |
| 23 | dma_request_channel() API is used. |
| 24 | |
| 25 | Interface: |
| 26 | struct dma_chan *dma_request_channel(dma_cap_mask_t mask, |
| 27 | dma_filter_fn filter_fn, |
| 28 | void *filter_param); |
| 29 | where dma_filter_fn is defined as: |
| 30 | typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); |
| 31 | |
| 32 | When the optional 'filter_fn' parameter is set to NULL dma_request_channel |
| 33 | simply returns the first channel that satisfies the capability mask. Otherwise, |
| 34 | when the mask parameter is insufficient for specifying the necessary channel, |
| 35 | the filter_fn routine can be used to disposition the available channels in the |
| 36 | system. The filter_fn routine is called once for each free channel in the |
| 37 | system. Upon seeing a suitable channel filter_fn returns DMA_ACK which flags |
| 38 | that channel to be the return value from dma_request_channel. A channel |
| 39 | allocated via this interface is exclusive to the caller, until |
| 40 | dma_release_channel() is called. |
| 41 | |
| 42 | 2. Set slave and controller specific parameters |
| 43 | Next step is always to pass some specific information to the DMA driver. Most of |
| 44 | the generic information which a slave DMA can use is in struct dma_slave_config. |
| 45 | It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA |
| 46 | burst lengths etc. If some DMA controllers have more parameters to be sent then |
| 47 | they should try to embed struct dma_slave_config in their controller specific |
| 48 | structure. That gives flexibility to client to pass more parameters, if |
| 49 | required. |
| 50 | |
| 51 | Interface: |
| 52 | int dmaengine_slave_config(struct dma_chan *chan, |
| 53 | struct dma_slave_config *config) |
| 54 | |
| 55 | 3. Get a descriptor for transaction |
| 56 | For slave usage the various modes of slave transfers supported by the |
| 57 | DMA-engine are: |
| 58 | slave_sg - DMA a list of scatter gather buffers from/to a peripheral |
| 59 | dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the |
| 60 | operation is explicitly stopped. |
| 61 | The non NULL return of this transfer API represents a "descriptor" for the given |
| 62 | transaction. |
| 63 | |
| 64 | Interface: |
| 65 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)( |
| 66 | struct dma_chan *chan, |
| 67 | struct scatterlist *dst_sg, unsigned int dst_nents, |
| 68 | struct scatterlist *src_sg, unsigned int src_nents, |
| 69 | unsigned long flags); |
| 70 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)( |
| 71 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
| 72 | size_t period_len, enum dma_data_direction direction); |
| 73 | |
| 74 | 4. Submit the transaction and wait for callback notification |
| 75 | To schedule the transaction to be scheduled by dma device, the "descriptor" |
| 76 | returned in above (3) needs to be submitted. |
| 77 | To tell the dma driver that a transaction is ready to be serviced, the |
| 78 | descriptor->submit() callback needs to be invoked. This chains the descriptor to |
| 79 | the pending queue. |
| 80 | The transactions in the pending queue can be activated by calling the |
| 81 | issue_pending API. If channel is idle then the first transaction in queue is |
| 82 | started and subsequent ones queued up. |
| 83 | On completion of the DMA operation the next in queue is submitted and a tasklet |
| 84 | triggered. The tasklet would then call the client driver completion callback |
| 85 | routine for notification, if set. |
| 86 | Interface: |
| 87 | void dma_async_issue_pending(struct dma_chan *chan); |
| 88 | |
| 89 | ============================================================================== |
| 90 | |
| 91 | Additional usage notes for dma driver writers |
| 92 | 1/ Although DMA engine specifies that completion callback routines cannot submit |
| 93 | any new operations, but typically for slave DMA subsequent transaction may not |
| 94 | be available for submit prior to callback routine being called. This requirement |
| 95 | is not a requirement for DMA-slave devices. But they should take care to drop |
| 96 | the spin-lock they might be holding before calling the callback routine |