00001
00045 #ifndef DMA_CONTROLLER_H_INCLUDED
00046 #define DMA_CONTROLLER_H_INCLUDED
00047
00048 #include <dma.h>
00049 #include <slist.h>
00050 #include <types.h>
00051 #include <buffer.h>
00052
00053 #include <chip/dma_controller.h>
00054
00055 struct buffer;
00056
00057 struct dmac_channel;
00058
00062 enum dmac_reg_width {
00063 DMAC_REG_WIDTH_8BIT = 0,
00064 DMAC_REG_WIDTH_16BIT = 1,
00065 DMAC_REG_WIDTH_32BIT = 2,
00066 };
00067
00071 enum dmac_burst_length {
00072 DMAC_BURST_LENGTH_1 = 0,
00073 DMAC_BURST_LENGTH_4 = 1,
00074 DMAC_BURST_LENGTH_8 = 2,
00075 DMAC_BURST_LENGTH_16 = 3,
00076 DMAC_BURST_LENGTH_32 = 4,
00077 };
00078
00082 struct dmac_request {
00084 struct slist buf_list;
00086 struct slist_node node;
00088 enum dma_direction direction;
00090 enum dmac_reg_width reg_width;
00092 enum dmac_burst_length burst_length;
00098 void (*req_done)(struct dmac_channel *chan,
00099 struct dmac_request *req);
00101 void *context;
00103 int status;
00105 size_t bytes_xfered;
00106 };
00107
00111 struct dmac_channel {
00112 void (*submit_req)(struct dmac_channel *chan,
00113 struct dmac_request *req);
00114 void (*reset)(struct dmac_channel *chan);
00116 size_t max_buffer_size;
00117 };
00118
00122 struct dma_controller {
00123 struct dmac_channel *(*alloc_chan)(struct dma_controller *dmac,
00124 enum dmac_periph_id rx_periph,
00125 enum dmac_periph_id tx_periph,
00126 phys_addr_t rx_reg_addr,
00127 phys_addr_t tx_reg_addr);
00128 void (*free_chan)(struct dma_controller *dmac,
00129 struct dmac_channel *chan);
00130 };
00131
00146 static inline struct dmac_channel *dmac_alloc_channel(
00147 struct dma_controller *dmac,
00148 enum dmac_periph_id rx_periph,
00149 enum dmac_periph_id tx_periph,
00150 phys_addr_t rx_reg_addr,
00151 phys_addr_t tx_reg_addr)
00152 {
00153 return dmac->alloc_chan(dmac, rx_periph, tx_periph,
00154 rx_reg_addr, tx_reg_addr);
00155 }
00156
00162 static inline void dmac_free_channel(struct dma_controller *dmac,
00163 struct dmac_channel *chan)
00164 {
00165 dmac->free_chan(dmac, chan);
00166 }
00167
00178 static inline void dmac_chan_submit_request(struct dmac_channel *chan,
00179 struct dmac_request *req)
00180 {
00181 chan->submit_req(chan, req);
00182 }
00183
00191 static inline void dmac_chan_reset(struct dmac_channel *chan)
00192 {
00193 chan->reset(chan);
00194 }
00195
00200 static inline void dmac_req_init(struct dmac_request *req)
00201 {
00202 slist_init(&req->buf_list);
00203 }
00204
00210 static inline void dmac_req_add_buffer(struct dmac_request *req,
00211 struct buffer *buf)
00212 {
00213 slist_insert_tail(&req->buf_list, &buf->node);
00214 }
00215
00216 #define dmac_req_for_each_buffer(req, buf) \
00217 slist_for_each(&req->buf_list, buf, node)
00218
00219 #define dmac_req_for_each_buffer_safe(req, buf, buf_next) \
00220 slist_for_each_safe(&req->buf_list, buf, buf_next, node)
00221
00222 #endif