1 /** 2 * @file dma.h 3 * 4 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** @defgroup hct_dma 19 * @ingroup drivers 20 */ 21 22 #ifndef _DMA_H_ 23 #define _DMA_H_ 24 25 #include <hi_types_base.h> 26 #include <hi_dma.h> 27 28 #ifdef __cplusplus 29 #if __cplusplus 30 extern "C" { 31 #endif 32 #endif 33 34 #ifdef DMA_DEBUG 35 #define dma_print(fmt...) \ 36 do { \ 37 printf(fmt); \ 38 printf("\r\n"); \ 39 } while (0) 40 #else 41 #define dma_print(fmt...) 42 #endif 43 44 /* DMA registers address */ 45 #define DMA_BASE_ADDR 0x40200000 46 #define DMA_INT_STAT (DMA_BASE_ADDR + 0x000) 47 #define DMA_INT_TC_STAT (DMA_BASE_ADDR + 0x004) 48 #define DMA_INT_TC_CLR (DMA_BASE_ADDR + 0x008) 49 #define DMA_INT_ERR_STAT (DMA_BASE_ADDR + 0x00C) 50 #define DMA_INT_ERR_CLR (DMA_BASE_ADDR + 0x010) 51 #define DMA_RAW_INT_TC_STATUS (DMA_BASE_ADDR + 0x014) 52 #define DMA_RAW_INT_ERR_STATUS (DMA_BASE_ADDR + 0x018) 53 #define DMA_ENBLD_CHNS (DMA_BASE_ADDR + 0x01C) 54 #define DMA_SOFT_BREQ (DMA_BASE_ADDR + 0x020) 55 #define DMA_SOFT_SREQ (DMA_BASE_ADDR + 0x024) 56 #define DMA_SOFT_LBREQ (DMA_BASE_ADDR + 0x028) 57 #define DMA_SOFT_LSREQ (DMA_BASE_ADDR + 0x02C) 58 #define DMA_CFG_REG (DMA_BASE_ADDR + 0x030) 59 #define DMA_SYNC (DMA_BASE_ADDR + 0x034) 60 /* Source Address Register for Channel x */ 61 #define dma_sar(x) (DMA_BASE_ADDR + 0x100 + (x)*0x020) 62 /* Destination Address Register for Channel x */ 63 #define dma_dar(x) (DMA_BASE_ADDR + 0x104 + (x)*0x020) 64 /* Linked List Pointer Register for Channel x */ 65 #define dma_lli(x) (DMA_BASE_ADDR + 0x108 + (x)*0x020) 66 /* Control Register for Channel x */ 67 #define dma_ctl(x) (DMA_BASE_ADDR + 0x10C + (x)*0x020) 68 /* Configuration Register for Channel x */ 69 #define dma_cfg(x) (DMA_BASE_ADDR + 0x110 + (x)*0x020) 70 71 #define DMA_MASK_INT 0 72 #define DMA_UNMASK_INT 1 73 74 #define DMA_CHANNEL_0 0x01 75 #define DMA_CHANNEL_1 0x02 76 #define DMA_CHANNEL_2 0x04 77 #define DMA_CHANNEL_3 0x08 78 79 #define DMA_CHANNEL_NUM_0 0 80 #define DMA_CHANNEL_NUM_1 1 81 #define DMA_CHANNEL_NUM_2 2 82 #define DMA_CHANNEL_NUM_3 3 83 84 #define DMA_CHANNEL_NUM 4 85 86 #define DMA_DISABLE 0 87 #define DMA_ENABLE 1 88 89 #define DMA_TR_ADDR_INCREMENT 1 90 #define DMA_TR_ADDR_NOCHANGE 0 91 92 #define DMA_WORD_WIDTH 4 93 94 #define DMA_TS_MAX 4095 95 #define DMA_TS_BLOCK 4092 96 97 #define DMA_TRANSFER_COMPLETE 0 98 #define DMA_TRANSFER_INCOMPLETE 1 99 #define DMA_TRANSFER_ERR 2 100 101 #define DMA_TIMEOUT_US 50000 102 103 #define dma_pkt_b_to_dma_addr(_virt_addr) ((hi_u32)(_virt_addr) + PKT_B_OFFSET) 104 #define dma_pkt_h_to_dma_addr(_virt_addr) ((hi_u32)(_virt_addr) + PKT_H_OFFSET) 105 106 #define DCACHE_ENABLE 1 107 #define DCACHE_EN_REG 0x7C1 108 109 /** 110 * @ingroup hct_dma 111 * 112 * DMA transfer mode. CNcomment:DMA传输模式。CNend 113 */ 114 typedef enum { 115 DMA_MEM_TO_MEM = 0, 116 DMA_MEM_TO_PHL, 117 DMA_PHL_TO_MEM, 118 DMA_PHL_TO_PHL, 119 } hi_dma_tr_type; 120 121 /** 122 * @ingroup hct_dma 123 * 124 * Peripheral ID that supports DMA transfer. CNcomment:支持DMA传输的外设ID。CNend 125 */ 126 typedef enum { 127 UART0_RX = 0, 128 UART0_TX, 129 UART1_RX, 130 UART1_TX, 131 UART2_RX, 132 UART2_TX, 133 SPI0_RX, 134 SPI0_TX, 135 SPI1_RX, 136 SPI1_TX, 137 I2S0_RX, 138 I2S0_TX, 139 PHL_MAX, 140 } hi_dma_phl; 141 142 /** 143 * @ingroup hct_dma 144 * 145 * One DMA burst transmission length. CNcomment:一次DMA burst传输长度。CNend 146 */ 147 typedef enum { 148 DMA_BURST_MSIZE_1 = 0, 149 DMA_BURST_MSIZE_4, 150 DMA_BURST_MSIZE_8, 151 DMA_BURST_MSIZE_16, 152 DMA_BURST_MSIZE_32, 153 DMA_BURST_MSIZE_64, 154 DMA_BURST_MSIZE_128, 155 DMA_BURST_MSIZE_256, 156 } hi_dma_burst_size; 157 158 typedef union dma_ch_sel { 159 struct { 160 hi_u32 channel_0 : 1; 161 hi_u32 channel_1 : 1; 162 hi_u32 channel_2 : 1; 163 hi_u32 channel_3 : 1; 164 hi_u32 reserved : 28; 165 } ch_bit; 166 hi_u32 ch_set_u32; 167 } dma_ch_sel; 168 169 typedef union dma_init_cfg { 170 struct { 171 hi_u32 dma_en : 1; 172 hi_u32 master1_endianness : 1; 173 hi_u32 master2_endianness : 1; 174 hi_u32 reserved : 29; 175 } dma_cfg_bit; 176 hi_u32 dma_cfg_u32; 177 } dma_init_cfg; 178 179 typedef union dma_ch_cfg { 180 struct { 181 hi_u32 en : 1; 182 hi_u32 src_peripheral : 4; 183 hi_u32 reserved0 : 1; 184 hi_u32 dst_peripheral : 4; 185 hi_u32 reserved1 : 1; 186 hi_u32 flow_cntrl : 3; 187 hi_u32 err_int_mask : 1; 188 hi_u32 tc_int_mask : 1; 189 hi_u32 lock : 1; 190 hi_u32 active : 1; 191 hi_u32 halt : 1; 192 hi_u32 reserved2 : 13; 193 } ch_cfg_bit; 194 hi_u32 ch_cfg_u32; 195 } dma_ch_cfg; 196 197 typedef union dma_llp { 198 struct { 199 hi_u32 lms : 1; 200 hi_u32 reserved : 1; 201 hi_u32 loc : 30; 202 } llp_bit; 203 hi_u32 llp_u32; 204 } dma_llp; 205 206 typedef struct dma_channel_para dma_channel_para_t; 207 208 /** 209 * @ingroup dma 210 * 211 * The channel control register structure of DMA. CNcomment:DMA 通道控制寄存器结构。CNend 212 */ 213 typedef struct dma_ch_ctl_t dma_ch_ctl; 214 typedef union dma_ch_ctl { 215 struct { 216 hi_u32 transfer_size : 12; 217 hi_u32 src_burst_size : 3; 218 hi_u32 dst_burst_size : 3; 219 hi_u32 src_width : 3; 220 hi_u32 dst_width : 3; 221 hi_u32 master_src_sel : 1; 222 hi_u32 master_dst_sel : 1; 223 hi_u32 src_inc : 1; 224 hi_u32 dst_inc : 1; 225 hi_u32 prot : 3; 226 hi_u32 lli_tc_int_en : 1; 227 } ch_ctl_bit; 228 hi_u32 ch_ctl_u32; 229 } dma_ch_ctl_t; 230 231 /** 232 * @ingroup dma 233 * 234 * The link structure of DMA link list item. CNcomment:DMA link list item链表结构。CNend 235 */ 236 typedef struct dma_lli_stru dma_lli_stru_t; 237 typedef struct dma_lli_stru { 238 hi_u32 saddr; 239 hi_u32 daddr; 240 dma_lli_stru_t *llp_next; 241 dma_ch_ctl_t st_ctl; 242 } dma_lli_stru_t; 243 244 typedef struct dma_channel_para { 245 dma_llp llp; 246 dma_ch_ctl_t ch_ctl; 247 dma_ch_cfg ch_cfg; 248 hi_void (*cb)(hi_u32); 249 volatile hi_u32 is_transfering; 250 dma_lli_stru_t *ch_lli; 251 } dma_channel_para; 252 253 typedef struct dma_data { 254 hi_bool is_inited; 255 volatile hi_u32 ch_mask; 256 dma_channel_para ch_data[DMA_CHANNEL_NUM]; 257 } dma_data; 258 259 /** 260 * @ingroup hct_dma 261 * 262 * The general setting structure of the user's incoming DMA. It is used for the transmission participated by IO. 263 CNcomment:用户传入DMA的通用设置结构,主要用于外设参与的传输。CNend 264 */ 265 typedef struct hi_dma_para { 266 hi_u32 tr_type; 267 hi_u32 src_phl; 268 hi_u32 dst_phl; 269 uintptr_t src_addr; 270 uintptr_t dst_addr; 271 hi_u32 src_burst_size; 272 hi_u32 dst_burst_size; 273 hi_u32 src_width; 274 hi_u32 dst_width; 275 hi_u32 transfer_size; 276 hi_void (*cb)(hi_u32); 277 } hi_dma_para; 278 279 /** 280 * @ingroup hct_dma 281 * @brief Start dma transmission. CNcomment:启动dma传输。CNend 282 * 283 * @par 描述: 284 * Start dma transmission and channel will be released after success or failure. 285 CNcomment:启动dma传输,成功或失败后会释放通道。CNend 286 * 287 * @attention 288 * @param dma_para [IN/OUT] type #hi_dma_user_para_sSetting incoming dma transfer parameter. 289 CNcomment:传入DMA传输参数设置。CNend 290 * @param block [IN] type #hi_bool,Whether to block for waiting dma tranmission completeness 291 CNcomment:是否阻塞等待DMA传输完成。CNend 292 * 293 * @retval #HI_ERR_SUCCESS Success. 294 * @retval #Other Failure. For details, see hi_errno.h. 295 * @par 依赖: 296 * @li hi_dma.h: DMA driver implementation interface. CNcomment:DMA驱动实现接口。CNend 297 * @see None 298 */ 299 hi_u32 hi_dma_transfer(const hi_dma_para *dma_para, hi_bool block); 300 /** 301 * @ingroup hct_dma 302 * @brief Start dma transmission. CNcomment:启动dma传输。CNend 303 * 304 * @par 描述: 305 * Start dma transmission and channel will be released after success or failure. 306 CNcomment:启动dma传输,成功或失败后会释放通道。CNend 307 * 308 * @attention 309 * @param dma_para [IN/OUT] type #hi_dma_user_para_sSetting incoming dma transfer parameter. 310 CNcomment:传入DMA传输参数设置。CNend 311 * @param dma_ch [IN] type #hi_bool,return dma channel number 312 CNcomment:返回申请的通道号。CNend 313 * 314 * @retval #HI_ERR_SUCCESS Success. 315 * @retval #Other Failure. For details, see hi_errno.h. 316 * @par 依赖: 317 * @li hi_dma.h: DMA driver implementation interface. CNcomment:DMA驱动实现接口。CNend 318 * @see None 319 */ 320 hi_u32 dma_hw_request_transfer(const hi_dma_para *dma_para, hi_u32 *dma_ch); 321 void dma_write_data(hi_u32 ch_num, const hi_dma_para *dma_para); 322 #ifdef __cplusplus 323 #if __cplusplus 324 } 325 #endif 326 #endif 327 328 #endif 329