1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #include <soc/soc.h>
18 #include "hal_port.h"
19 #include "dma_hw.h"
20 #include <driver/hal/hal_dma_types.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define DMA_LL_REG_BASE(_dma_unit_id) (SOC_GENER_DMA_REG_BASE)
27 #define CASE_DEV(dev) case DMA_DEV_##dev: return DMA_V_REQ_MUX_##dev
28 #define CASE_D() default: return 0
29
dma_ll_init(dma_hw_t * hw)30 static inline void dma_ll_init(dma_hw_t *hw)
31 {
32 for (int dma_id = 0; dma_id < SOC_DMA_CHAN_NUM_PER_UNIT; dma_id++) {
33 hw->config_group[dma_id].ctrl.v = 0;
34 hw->config_group[dma_id].dest_start_addr = 0;
35 hw->config_group[dma_id].src_start_addr = 0;
36 hw->config_group[dma_id].dest_loop_end_addr = 0;
37 hw->config_group[dma_id].dest_loop_start_addr = 0;
38 hw->config_group[dma_id].src_loop_end_addr = 0;
39 hw->config_group[dma_id].src_loop_start_addr = 0;
40 hw->config_group[dma_id].req_mux.v = 0;
41 }
42 hw->prio_mode.v = 0;
43 hw->int_status.v = 0;
44 }
45
dma_ll_dev_to_req_mux(uint32 req_mux)46 static inline uint32_t dma_ll_dev_to_req_mux(uint32 req_mux)
47 {
48 switch (req_mux)
49 {
50 CASE_DEV(DTCM);
51 CASE_DEV(UART1);
52 CASE_DEV(GSPI0);
53 CASE_DEV(SDIO);
54 CASE_DEV(UART2);
55 CASE_DEV(UART3);
56 CASE_DEV(GSPI1);
57 CASE_DEV(USB);
58 CASE_DEV(AUDIO);
59 CASE_DEV(I2S);
60 CASE_DEV(LCD_CMD);
61 CASE_DEV(LCD_DATA);
62 CASE_DEV(JPEG);
63 CASE_D();
64 }
65 }
66
dma_ll_enable(dma_hw_t * hw,dma_id_t id)67 static inline void dma_ll_enable(dma_hw_t *hw, dma_id_t id)
68 {
69 hw->config_group[id].ctrl.enable = 1;
70 }
71
dma_ll_disable(dma_hw_t * hw,dma_id_t id)72 static inline void dma_ll_disable(dma_hw_t *hw, dma_id_t id)
73 {
74 hw->config_group[id].ctrl.enable = 0;
75 }
76
dma_ll_get_enable_status(dma_hw_t * hw,dma_id_t id)77 static inline uint32_t dma_ll_get_enable_status(dma_hw_t *hw, dma_id_t id)
78 {
79 return hw->config_group[id].ctrl.enable;
80 }
81
dma_ll_is_id_started(dma_hw_t * hw,dma_id_t id)82 static inline bool dma_ll_is_id_started(dma_hw_t *hw, dma_id_t id)
83 {
84 return !!(hw->config_group[id].ctrl.enable == 1);
85 }
86
dma_ll_enable_finish_interrupt(dma_hw_t * hw,dma_id_t id)87 static inline void dma_ll_enable_finish_interrupt(dma_hw_t *hw, dma_id_t id)
88 {
89 hw->config_group[id].ctrl.finish_int_en = 1;
90 }
91
dma_ll_disable_finish_interrupt(dma_hw_t * hw,dma_id_t id)92 static inline void dma_ll_disable_finish_interrupt(dma_hw_t *hw, dma_id_t id)
93 {
94 hw->config_group[id].ctrl.finish_int_en = 0;
95 }
96
dma_ll_enable_half_finish_interrupt(dma_hw_t * hw,dma_id_t id)97 static inline void dma_ll_enable_half_finish_interrupt(dma_hw_t *hw, dma_id_t id)
98 {
99 hw->config_group[id].ctrl.half_finish_int_en = 1;
100 }
101
dma_ll_disable_half_finish_interrupt(dma_hw_t * hw,dma_id_t id)102 static inline void dma_ll_disable_half_finish_interrupt(dma_hw_t *hw, dma_id_t id)
103 {
104 hw->config_group[id].ctrl.half_finish_int_en = 0;
105 }
106
dma_ll_enable_interrupt(dma_hw_t * hw,dma_id_t id)107 static inline void dma_ll_enable_interrupt(dma_hw_t *hw, dma_id_t id)
108 {
109 dma_ll_enable_half_finish_interrupt(hw, id);
110 dma_ll_enable_finish_interrupt(hw, id);
111 }
112
dma_ll_disable_interrupt(dma_hw_t * hw,dma_id_t id)113 static inline void dma_ll_disable_interrupt(dma_hw_t *hw, dma_id_t id)
114 {
115 dma_ll_disable_half_finish_interrupt(hw, id);
116 dma_ll_disable_finish_interrupt(hw, id);
117 }
118
dma_ll_clear_finish_interrupt_status(dma_hw_t * hw,dma_id_t id)119 static inline void dma_ll_clear_finish_interrupt_status(dma_hw_t *hw, dma_id_t id)
120 {
121 hw->int_status.v = BIT(id);
122 }
123
dma_ll_clear_half_finish_interrupt_status(dma_hw_t * hw,dma_id_t id)124 static inline void dma_ll_clear_half_finish_interrupt_status(dma_hw_t *hw, dma_id_t id)
125 {
126 hw->int_status.v = (BIT(id) << 16);
127 }
128
dma_ll_clear_interrupt_status(dma_hw_t * hw,dma_id_t id)129 static inline void dma_ll_clear_interrupt_status(dma_hw_t *hw, dma_id_t id)
130 {
131 dma_ll_clear_half_finish_interrupt_status(hw, id);
132 dma_ll_clear_finish_interrupt_status(hw, id);
133 }
134
dma_ll_is_finish_interrupt_triggered(dma_hw_t * hw,dma_id_t id)135 static inline bool dma_ll_is_finish_interrupt_triggered(dma_hw_t *hw, dma_id_t id)
136 {
137 return !!(hw->int_status.finish_int_status & BIT(id));
138 }
139
dma_ll_is_half_finish_interrupt_triggered(dma_hw_t * hw,dma_id_t id)140 static inline bool dma_ll_is_half_finish_interrupt_triggered(dma_hw_t *hw, dma_id_t id)
141 {
142 return !!(hw->int_status.half_finish_int_status & BIT(id));
143 }
144
dma_ll_reset_config_to_default(dma_hw_t * hw,volatile dma_id_t id)145 static inline void dma_ll_reset_config_to_default(dma_hw_t *hw, volatile dma_id_t id)
146 {
147 hw->config_group[id].ctrl.v = 0;
148 hw->config_group[id].dest_start_addr = 0;
149 hw->config_group[id].src_start_addr = 0;
150 hw->config_group[id].dest_loop_end_addr = 0;
151 hw->config_group[id].dest_loop_start_addr = 0;
152 hw->config_group[id].src_loop_end_addr = 0;
153 hw->config_group[id].src_loop_start_addr = 0;
154 hw->config_group[id].req_mux.v = 0;
155 }
156
dma_ll_set_work_mode(dma_hw_t * hw,dma_id_t id,uint32_t mode)157 static inline void dma_ll_set_work_mode(dma_hw_t *hw, dma_id_t id, uint32_t mode)
158 {
159 hw->config_group[id].ctrl.mode = mode & 0x01;
160 }
161
162 #define dma_ll_set_mode_single(hw, id) dma_ll_set_work_mode(hw, id, DMA_V_WORK_MODE_SINGLE)
163 #define dma_ll_set_mode_repeat(hw, id) dma_ll_set_work_mode(hw, id, DMA_V_WORK_MODE_REPEAT)
164
dma_ll_set_chan_prio(dma_hw_t * hw,dma_id_t id,uint32_t chan_prio)165 static inline void dma_ll_set_chan_prio(dma_hw_t *hw, dma_id_t id, uint32_t chan_prio)
166 {
167 hw->config_group[id].ctrl.chan_prio = chan_prio & 0x07;
168 }
169
dma_ll_set_dest_data_width(dma_hw_t * hw,dma_id_t id,uint32_t data_width)170 static inline void dma_ll_set_dest_data_width(dma_hw_t *hw, dma_id_t id, uint32_t data_width)
171 {
172 hw->config_group[id].ctrl.dest_data_width = data_width & 0x03;
173 }
174
dma_ll_set_src_data_width(dma_hw_t * hw,dma_id_t id,uint32_t data_width)175 static inline void dma_ll_set_src_data_width(dma_hw_t *hw, dma_id_t id, uint32_t data_width)
176 {
177 hw->config_group[id].ctrl.src_data_width = data_width & 0x03;
178 }
179
dma_ll_set_dest_req_mux(dma_hw_t * hw,dma_id_t id,uint32_t req_mux)180 static inline void dma_ll_set_dest_req_mux(dma_hw_t *hw, dma_id_t id, uint32_t req_mux)
181 {
182 hw->config_group[id].req_mux.dest_req_mux = (dma_ll_dev_to_req_mux(req_mux)) & 0xf;
183 }
184
dma_ll_set_src_req_mux(dma_hw_t * hw,dma_id_t id,uint32_t req_mux)185 static inline void dma_ll_set_src_req_mux(dma_hw_t *hw, dma_id_t id, uint32_t req_mux)
186 {
187 hw->config_group[id].req_mux.src_req_mux = (dma_ll_dev_to_req_mux(req_mux)) & 0xf;
188 }
189
dma_ll_enable_src_addr_inc(dma_hw_t * hw,dma_id_t id)190 static inline void dma_ll_enable_src_addr_inc(dma_hw_t *hw, dma_id_t id)
191 {
192 hw->config_group[id].ctrl.src_addr_inc_en = 1;
193 }
194
dma_ll_disable_src_addr_inc(dma_hw_t * hw,dma_id_t id)195 static inline void dma_ll_disable_src_addr_inc(dma_hw_t *hw, dma_id_t id)
196 {
197 hw->config_group[id].ctrl.src_addr_inc_en = 0;
198 }
199
dma_ll_enable_dest_addr_inc(dma_hw_t * hw,dma_id_t id)200 static inline void dma_ll_enable_dest_addr_inc(dma_hw_t *hw, dma_id_t id)
201 {
202 hw->config_group[id].ctrl.dest_addr_inc_en = 1;
203 }
204
dma_ll_disable_dest_addr_inc(dma_hw_t * hw,dma_id_t id)205 static inline void dma_ll_disable_dest_addr_inc(dma_hw_t *hw, dma_id_t id)
206 {
207 hw->config_group[id].ctrl.dest_addr_inc_en = 0;
208 }
209
dma_ll_enable_src_addr_loop(dma_hw_t * hw,dma_id_t id)210 static inline void dma_ll_enable_src_addr_loop(dma_hw_t *hw, dma_id_t id)
211 {
212 hw->config_group[id].ctrl.src_addr_loop_en = 1;
213 }
214
dma_ll_disable_src_addr_loop(dma_hw_t * hw,dma_id_t id)215 static inline void dma_ll_disable_src_addr_loop(dma_hw_t *hw, dma_id_t id)
216 {
217 hw->config_group[id].ctrl.src_addr_loop_en = 0;
218 }
219
dma_ll_enable_dest_addr_loop(dma_hw_t * hw,dma_id_t id)220 static inline void dma_ll_enable_dest_addr_loop(dma_hw_t *hw, dma_id_t id)
221 {
222 hw->config_group[id].ctrl.dest_addr_loop_en = 1;
223 }
224
dma_ll_disable_dest_addr_loop(dma_hw_t * hw,dma_id_t id)225 static inline void dma_ll_disable_dest_addr_loop(dma_hw_t *hw, dma_id_t id)
226 {
227 hw->config_group[id].ctrl.dest_addr_loop_en = 0;
228 }
229
dma_ll_set_dest_start_addr(dma_hw_t * hw,volatile dma_id_t id,uint32_t addr)230 static inline void dma_ll_set_dest_start_addr(dma_hw_t *hw, volatile dma_id_t id, uint32_t addr)
231 {
232 hw->config_group[id].dest_start_addr = addr;
233 }
234
dma_ll_set_src_start_addr(dma_hw_t * hw,dma_id_t id,uint32_t addr)235 static inline void dma_ll_set_src_start_addr(dma_hw_t *hw, dma_id_t id, uint32_t addr)
236 {
237 hw->config_group[id].src_start_addr = addr;
238 }
239
dma_ll_set_dest_loop_addr(dma_hw_t * hw,dma_id_t id,uint32_t start_addr,uint32_t end_addr)240 static inline void dma_ll_set_dest_loop_addr(dma_hw_t *hw, dma_id_t id, uint32_t start_addr, uint32_t end_addr)
241 {
242 hw->config_group[id].dest_loop_start_addr = start_addr;
243 hw->config_group[id].dest_loop_end_addr = end_addr;
244 }
245
dma_ll_set_src_loop_addr(dma_hw_t * hw,dma_id_t id,uint32_t start_addr,uint32_t end_addr)246 static inline void dma_ll_set_src_loop_addr(dma_hw_t *hw, dma_id_t id, uint32_t start_addr, uint32_t end_addr)
247 {
248 hw->config_group[id].src_loop_start_addr = start_addr;
249 hw->config_group[id].src_loop_end_addr = end_addr;
250 }
251
dma_ll_set_transfer_len(dma_hw_t * hw,dma_id_t id,uint32_t tran_len)252 static inline void dma_ll_set_transfer_len(dma_hw_t *hw, dma_id_t id, uint32_t tran_len)
253 {
254 hw->config_group[id].ctrl.v &= 0xFFFF;
255 hw->config_group[id].ctrl.v |= ((tran_len - 1) << 16);
256 }
257
dma_ll_get_remain_len(dma_hw_t * hw,dma_id_t id)258 static inline uint32_t dma_ll_get_remain_len(dma_hw_t *hw, dma_id_t id)
259 {
260 return (uint32_t)hw->status_group[id].status.remain_len;
261 }
262
dma_ll_set_prio_mode(dma_hw_t * hw,uint32_t prio_mode)263 static inline void dma_ll_set_prio_mode(dma_hw_t *hw, uint32_t prio_mode)
264 {
265 hw->prio_mode.prio_mode = prio_mode & 0x1;
266 }
267
268 #define dma_ll_set_prio_mode_round_robin(hw) dma_ll_set_prio_mode(hw, DMA_V_PRIO_MODE_ROUND_ROBIN)
269 #define dma_ll_set_prio_mode_fixed_prio(hw) dma_ll_set_prio_mode(hw, DMA_V_PRIO_MODE_FIXED_PRIO)
270
dma_ll_set_src_pause_addr(dma_hw_t * hw,dma_id_t id,uint32_t addr)271 static inline void dma_ll_set_src_pause_addr(dma_hw_t *hw, dma_id_t id, uint32_t addr)
272 {
273 hw->src_pause_addr[id] = addr;
274 }
275
dma_ll_set_dest_pause_addr(dma_hw_t * hw,dma_id_t id,uint32_t addr)276 static inline void dma_ll_set_dest_pause_addr(dma_hw_t *hw, dma_id_t id, uint32_t addr)
277 {
278 hw->dest_pause_addr[id] = addr;
279 }
280
dma_ll_get_src_read_addr(dma_hw_t * hw,dma_id_t id)281 static inline uint32_t dma_ll_get_src_read_addr(dma_hw_t *hw, dma_id_t id)
282 {
283 return hw->src_rd_addr[id];
284 }
285
dma_ll_get_dest_write_addr(dma_hw_t * hw,dma_id_t id)286 static inline uint32_t dma_ll_get_dest_write_addr(dma_hw_t *hw, dma_id_t id)
287 {
288 return hw->dest_wr_addr[id];
289 }
290
291 #ifdef __cplusplus
292 }
293 #endif
294
295