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