• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_sSetting 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_sSetting 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