1 /* 2 * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 */ 4 5 /****************************************************************************** 6 * @file dma.h 7 * @brief header file for dma driver 8 * @version V1.0 9 * @date 08. Apr 2020 10 * @model dma 11 ******************************************************************************/ 12 13 #ifndef _DRV_DMA_H_ 14 #define _DRV_DMA_H_ 15 16 #include <stdint.h> 17 #include <stdio.h> 18 #include <drv/common.h> 19 #include <drv/list.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /****** DMA Event *****/ 26 typedef enum { 27 DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete 28 DMA_EVENT_TRANSFER_HALF_DONE, ///< transfer half done 29 DMA_EVENT_TRANSFER_ERROR, ///< transfer error 30 } csi_dma_event_t; 31 32 typedef enum { 33 DMA_ADDR_INC = 0, 34 DMA_ADDR_DEC, 35 DMA_ADDR_CONSTANT 36 } csi_dma_addr_inc_t; 37 38 typedef enum { 39 DMA_DATA_WIDTH_8_BITS = 0, 40 DMA_DATA_WIDTH_16_BITS, 41 DMA_DATA_WIDTH_32_BITS, 42 DMA_DATA_WIDTH_64_BITS, 43 DMA_DATA_WIDTH_128_BITS, 44 DMA_DATA_WIDTH_512_BITS 45 } csi_dma_data_width_t; 46 47 typedef enum { 48 DMA_MEM2MEM = 0, 49 DMA_MEM2PERH, 50 DMA_PERH2MEM, 51 } csi_dma_trans_dir_t; 52 53 typedef struct { 54 int8_t ctrl_idx; 55 int8_t ch_idx; 56 } csi_dma_ch_desc_t; 57 58 typedef struct { 59 uint16_t dev_tag; 60 int8_t ctrl_idx; 61 const csi_dma_ch_desc_t *ch_list; 62 } csi_dma_ch_spt_list_t; 63 64 typedef struct { 65 csi_dma_addr_inc_t src_inc; ///< source address increment 66 csi_dma_addr_inc_t dst_inc; ///< destination address increment 67 csi_dma_data_width_t src_tw; ///< source transfer width in byte 68 csi_dma_data_width_t dst_tw; ///< destination transfer width in byte 69 csi_dma_trans_dir_t trans_dir; ///< transfer direction 70 uint16_t handshake; ///< handshake id 71 uint16_t group_len; ///< group transaction length (unit: bytes) 72 uint8_t src_reload_en; ///< 1:dma enable src addr auto reload, 0:disable 73 uint8_t dst_reload_en; ///< 1:dma enable dst addr auto reload, 0:disable 74 uint8_t half_int_en; ///< 1:dma enable half interrupt, 0: disable 75 uint8_t lli_src_en; ///< 1:dma enable llp, 0 disable 76 uint8_t lli_dst_en; ///< 1:dma enable llp, 0 disable 77 } csi_dma_ch_config_t; 78 79 #ifndef DMA_LLI_SIZE 80 #define DMA_LLI_SIZE 28 81 #endif 82 83 #define DEFINE_DESC_BUF(buf_name, num) uint8_t buf_name[num * DMA_LLI_SIZE] 84 85 typedef struct csi_dma_ch csi_dma_ch_t; 86 87 struct csi_dma_ch { 88 void *parent; 89 int8_t ctrl_id; 90 int8_t ch_id; 91 void (*callback)(csi_dma_ch_t *dma_ch, csi_dma_event_t event, void *arg); 92 void *arg; 93 uint32_t lli_num; //lli buffer len 94 uint32_t lli_count; //lli data count 95 int32_t lli_w_p; //write position 96 int32_t lli_r_p; //read position 97 void *lli; //lli buffer 98 uint32_t lli_loop_buf0; //lli loop data 99 uint32_t lli_loop_buf1; //lli loop data 100 uint8_t lli_loop[DMA_LLI_SIZE]; //lli loop handle 101 int16_t etb_ch_id; 102 slist_t next; 103 }; 104 105 typedef struct { 106 csi_dev_t dev; 107 slist_t head; 108 uint32_t alloc_status; 109 uint32_t ch_num; 110 void *priv; 111 } csi_dma_t; 112 113 /** 114 \brief Init dma controller 115 \param[in] dma the dma controller operate handle 116 \param[in] ctrl_id the dma controller id 117 \return csi error code 118 */ 119 csi_error_t csi_dma_init(csi_dma_t *dma, int8_t ctrl_id); 120 121 /** 122 \brief Uninit dma controller 123 \param[in] dma the dma controller operate handle 124 \return none 125 */ 126 void csi_dma_uninit(csi_dma_t *dma); 127 128 /** 129 \brief Alloc a dma channel 130 \param[in] dma_ch the dma channel operate handle 131 \param[in] ch_id the channel id of dma; when set -1, means auto alloc 132 \param[in] ctrl_id the dma controller id; when set -1, means auto alloc 133 \return csi error code 134 */ 135 csi_error_t csi_dma_ch_alloc(csi_dma_ch_t *dma_ch, int8_t ch_id, int8_t ctrl_id); 136 137 /** 138 \brief Free a dma channel 139 \param[in] dma_ch the dma channel operate handle 140 \return none 141 */ 142 void csi_dma_ch_free(csi_dma_ch_t *dma_ch); 143 144 /** 145 \brief Config a dma channel 146 \param[in] dma_ch the dma channel operate handle 147 \param[in] config the config structure for dma channel 148 \return csi error code 149 */ 150 csi_error_t csi_dma_ch_config(csi_dma_ch_t *dma_ch, csi_dma_ch_config_t *config); 151 152 /** 153 \brief Start a dma channel 154 \param[in] dma_ch the dma channel operate handle 155 \param[in] psrcaddr transfer source address 156 \param[in] pdstaddr transfer destination address 157 \param[in] length transfer length (unit: bytes), if set data_width is 16, the length should be the multiple of 2, and 158 if set data_width is 32, the length should be the multiple of 4 159 \return none 160 */ 161 void csi_dma_ch_start(csi_dma_ch_t *dma_ch, void *srcaddr, void *dstaddr, uint32_t length); 162 163 /** 164 \brief Stop a dma channel 165 \param[in] dma_ch the dma channel operate handle 166 \return none 167 */ 168 void csi_dma_ch_stop(csi_dma_ch_t *dma_ch); 169 170 /** 171 \brief Attach the callback handler to DMA channel 172 \param[in] dma_ch operate handle. 173 \param[in] callback callback function 174 \param[in] arg user can define it by himself as callback's param 175 \return error code 176 */ 177 csi_error_t csi_dma_ch_attach_callback(csi_dma_ch_t *dma_ch, void *callback, void *arg); 178 179 /** 180 \brief detach the callback handler 181 \param[in] uart operate handle. 182 */ 183 void csi_dma_ch_detach_callback(csi_dma_ch_t *dma_ch); 184 185 /** 186 \brief enable dma power manage 187 \param[in] dma dma handle to operate. 188 \return error code 189 */ 190 csi_error_t csi_dma_enable_pm(csi_dma_t *dma); 191 192 /** 193 \brief disable dma power manage 194 \param[in] dma dma handle to operate. 195 */ 196 void csi_dma_disable_pm(csi_dma_t *dma); 197 198 #ifdef __cplusplus 199 } 200 #endif 201 202 #endif /* _CSI_DMA_H_ */ 203