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 #include <common/bk_include.h>
16 #include <common/bk_compiler.h>
17 #include <os/mem.h>
18 #include "icu_driver.h"
19 #include "dma_driver.h"
20 #include "dma_hal.h"
21 #include <driver/dma.h>
22 #include "bk_general_dma.h"
23 #include <driver/int.h>
24 #include "sys_driver.h"
25 #if CONFIG_SLAVE_CORE
26 #include "mb_ipc_cmd.h"
27 #endif
28
29 #if CONFIG_CACHE_ENABLE
30 #include "cache.h"
31 #endif
32
33 #define DMA_CPU_MASTER 0
34 #define DMA_CPU_SLAVE1 1
35
36 static void dma_isr(void) __BK_SECTION(".itcm");
37
38 typedef struct {
39 dma_hal_t hal;
40 uint32_t id_init_bits;
41 } dma_driver_t;
42
43 static dma_driver_t s_dma = {0};
44 static dma_isr_t s_dma_finish_isr[SOC_DMA_CHAN_NUM_PER_UNIT] = {NULL};
45 static dma_isr_t s_dma_half_finish_isr[SOC_DMA_CHAN_NUM_PER_UNIT] = {NULL};
46 static bool s_dma_driver_is_init = false;
47 static dma_chnl_pool_t s_dma_chnl_pool = {0};
48
49 #define DMA_RETURN_ON_NOT_INIT() do {\
50 if (!s_dma_driver_is_init) {\
51 return BK_ERR_DMA_NOT_INIT;\
52 }\
53 } while(0)
54
55 #define DMA_RETURN_ON_INVALID_ID(id) do {\
56 if ((id) >= SOC_DMA_CHAN_NUM_PER_UNIT) {\
57 return BK_ERR_DMA_ID;\
58 }\
59 } while(0)
60
61 #define DMA_RETURN_ON_ID_NOT_INIT(id) do {\
62 if (!(s_dma.id_init_bits & BIT((id)))) {\
63 return BK_ERR_DMA_ID_NOT_INIT;\
64 }\
65 } while(0)
66
67 #define DMA_LOG_ON_ID_IS_STARTED(id) do {\
68 if (dma_hal_is_id_started(&s_dma.hal, (id))) {\
69 DMA_LOGW("%s dma%d is working.\n", __func__, id);\
70 }\
71 } while(0)
72
73 #define DMA_RETURN_ON_INVALID_ADDR(start_addr, end_addr) do {\
74 if ((0 < (end_addr)) && ((end_addr) < (start_addr))) {\
75 return BK_ERR_DMA_INVALID_ADDR;\
76 }\
77 } while(0)
78
dma_id_init_common(dma_id_t id)79 static void dma_id_init_common(dma_id_t id)
80 {
81 s_dma.id_init_bits |= BIT(id);
82 }
83
dma_id_deinit_common(dma_id_t id)84 static void dma_id_deinit_common(dma_id_t id)
85 {
86 s_dma.id_init_bits &= ~BIT(id);
87 dma_hal_stop_common(&s_dma.hal, id);
88 dma_hal_reset_config_to_default(&s_dma.hal, id);
89 }
90
dma_id_enable_interrupt_common(dma_id_t id)91 static void dma_id_enable_interrupt_common(dma_id_t id)
92 {
93 #if (CONFIG_SYSTEM_CTRL)
94 sys_drv_int_enable(GDMA_INTERRUPT_CTRL_BIT);
95 #else
96 icu_enable_dma_interrupt();
97 #endif
98 }
99
100 /* used internally, called in context of interrupt disabled. */
dma_chnl_alloc(u32 user_id)101 u8 dma_chnl_alloc(u32 user_id)
102 {
103 u8 chnl_id;
104
105 for(chnl_id = 0; chnl_id < DMA_ID_MAX; chnl_id++)
106 {
107 if((s_dma_chnl_pool.chnl_bitmap & (0x01 << chnl_id)) == 0)
108 {
109 s_dma_chnl_pool.chnl_bitmap |= (0x01 << chnl_id);
110 s_dma_chnl_pool.chnl_user[chnl_id] = user_id;
111 break;
112 }
113 }
114
115 return chnl_id;
116 }
117
118 /* used internally, called in context of interrupt disabled. */
dma_chnl_free(u32 user_id,dma_id_t chnl_id)119 bk_err_t dma_chnl_free(u32 user_id, dma_id_t chnl_id)
120 {
121 if( chnl_id >= DMA_ID_MAX )
122 return BK_ERR_DMA_ID;
123
124 if( s_dma_chnl_pool.chnl_user[chnl_id] != user_id )
125 return BK_ERR_PARAM;
126
127 s_dma_chnl_pool.chnl_bitmap &= ~(0x01 << chnl_id);
128 s_dma_chnl_pool.chnl_user[chnl_id] = -1;
129
130 return BK_OK;
131 }
132
133 /* used internally. */
dma_chnl_user(dma_id_t chnl_id)134 u32 dma_chnl_user(dma_id_t chnl_id)
135 {
136 if( chnl_id >= DMA_ID_MAX )
137 return -1;
138
139 return s_dma_chnl_pool.chnl_user[chnl_id];
140 }
141
bk_dma_driver_init(void)142 bk_err_t bk_dma_driver_init(void)
143 {
144 if (s_dma_driver_is_init) {
145 return BK_OK;
146 }
147
148 s_dma_chnl_pool.chnl_bitmap = 0;
149 for(u8 i = 0; i < DMA_ID_MAX; i++)
150 {
151 s_dma_chnl_pool.chnl_user[i] = -1;
152 }
153
154 /* 1)intc_service_register
155 * 2)init dma_finish_int handler, dma_half_finish_int handler
156 * 3)disable dma_en (0~6), clear int status
157 * 4)init dma_config
158 */
159 os_memset(&s_dma, 0, sizeof(s_dma));
160 os_memset(&s_dma_finish_isr, 0, sizeof(s_dma_finish_isr));
161 os_memset(&s_dma_half_finish_isr, 0, sizeof(s_dma_half_finish_isr));
162 bk_int_isr_register(INT_SRC_GDMA, dma_isr, NULL);
163 dma_hal_init(&s_dma.hal);
164
165 s_dma_driver_is_init = true;
166
167 return BK_OK;
168 }
169
bk_dma_driver_deinit(void)170 bk_err_t bk_dma_driver_deinit(void)
171 {
172 if (!s_dma_driver_is_init) {
173 return BK_OK;
174 }
175 #if !CONFIG_SLAVE_CORE
176 for (int id = 0; id < SOC_DMA_CHAN_NUM_PER_UNIT; id++) {
177 dma_id_deinit_common(id);
178 }
179 #endif
180
181 #if (CONFIG_SYSTEM_CTRL)
182 sys_drv_int_disable(GDMA_INTERRUPT_CTRL_BIT);
183 #else
184 icu_disable_dma_interrupt();
185 #endif
186
187 s_dma_driver_is_init = false;
188
189 return BK_OK;
190 }
191
bk_dma_alloc(u16 user_id)192 dma_id_t bk_dma_alloc(u16 user_id)
193 {
194 if (!s_dma_driver_is_init)
195 {
196 return DMA_ID_MAX;
197 }
198
199 #if CONFIG_SLAVE_CORE
200
201 #define DMA_USER_CPU DMA_CPU_SLAVE1
202
203 u32 dma_user = ((DMA_USER_CPU) << 16) + (u32)user_id;
204
205 return ipc_send_alloc_dma_chnl(dma_user);
206
207 #else
208
209 #define DMA_USER_CPU DMA_CPU_MASTER
210
211 u32 int_mask = rtos_disable_int();
212
213 u32 dma_user = ((DMA_USER_CPU) << 16) + (u32)user_id;
214
215 u8 chnl_id = dma_chnl_alloc(dma_user);
216
217 rtos_enable_int(int_mask);
218
219 return chnl_id;
220
221 #endif
222 }
223
bk_dma_free(u16 user_id,dma_id_t chnl_id)224 bk_err_t bk_dma_free(u16 user_id, dma_id_t chnl_id)
225 {
226 if (!s_dma_driver_is_init)
227 {
228 return BK_ERR_DMA_NOT_INIT;
229 }
230
231 #if CONFIG_SLAVE_CORE
232
233 #define DMA_USER_CPU DMA_CPU_SLAVE1
234
235 u32 dma_user = ((DMA_USER_CPU) << 16) + (u32)user_id;
236
237 return ipc_send_free_dma_chnl(dma_user, chnl_id);
238
239 #else
240
241 #define DMA_USER_CPU DMA_CPU_MASTER
242
243 u32 int_mask = rtos_disable_int();
244
245 u32 dma_user = ((DMA_USER_CPU) << 16) + (u32)user_id;
246 bk_err_t ret_val = dma_chnl_free(dma_user, chnl_id);
247
248 rtos_enable_int(int_mask);
249
250 return ret_val;
251
252 #endif
253 }
254
bk_dma_user(dma_id_t chnl_id)255 uint32_t bk_dma_user(dma_id_t chnl_id)
256 {
257 if (!s_dma_driver_is_init)
258 {
259 return -1;
260 }
261
262 #if CONFIG_SLAVE_CORE
263 return ipc_send_dma_chnl_user( (u8)chnl_id );
264 #else
265 return dma_chnl_user(chnl_id);
266 #endif
267
268 }
269
bk_dma_init(dma_id_t id,const dma_config_t * config)270 bk_err_t bk_dma_init(dma_id_t id, const dma_config_t *config)
271 {
272 DMA_RETURN_ON_NOT_INIT();
273 BK_RETURN_ON_NULL(config);
274 DMA_RETURN_ON_INVALID_ID(id);
275 DMA_RETURN_ON_INVALID_ADDR(config->src.start_addr, config->src.end_addr);
276 DMA_RETURN_ON_INVALID_ADDR(config->dst.start_addr, config->dst.end_addr);
277 DMA_LOG_ON_ID_IS_STARTED(id);
278
279 #if CONFIG_CACHE_ENABLE
280 flush_dcache((void *)config->src.start_addr, config->src.end_addr - config->src.start_addr);
281 #endif
282
283 dma_id_init_common(id);
284 return dma_hal_init_dma(&s_dma.hal, id, config);
285 }
286
bk_dma_deinit(dma_id_t id)287 bk_err_t bk_dma_deinit(dma_id_t id)
288 {
289 DMA_RETURN_ON_INVALID_ID(id);
290 dma_id_deinit_common(id);
291 bk_dma_register_isr(id, NULL, NULL);
292 return BK_OK;
293 }
294
bk_dma_start(dma_id_t id)295 bk_err_t bk_dma_start(dma_id_t id)
296 {
297 DMA_RETURN_ON_NOT_INIT();
298 DMA_RETURN_ON_ID_NOT_INIT(id);
299 dma_hal_start_common(&s_dma.hal, id);
300 return BK_OK;
301 }
302
bk_dma_stop(dma_id_t id)303 bk_err_t bk_dma_stop(dma_id_t id)
304 {
305 DMA_RETURN_ON_NOT_INIT();
306 DMA_RETURN_ON_ID_NOT_INIT(id);
307 dma_hal_stop_common(&s_dma.hal, id);
308 return BK_OK;
309 }
310
bk_dma_get_enable_status(dma_id_t id)311 uint32_t bk_dma_get_enable_status(dma_id_t id)
312 {
313 DMA_RETURN_ON_NOT_INIT();
314 DMA_RETURN_ON_ID_NOT_INIT(id);
315 uint32_t ret;
316 ret = dma_hal_get_enable_status(&s_dma.hal, id);
317 return ret;
318 }
319
320 /* DTCM->peripheral
321 */
bk_dma_write(dma_id_t id,const uint8_t * data,uint32_t size)322 bk_err_t bk_dma_write(dma_id_t id, const uint8_t *data, uint32_t size)
323 {
324 DMA_RETURN_ON_NOT_INIT();
325 DMA_RETURN_ON_ID_NOT_INIT(id);
326
327 dma_hal_set_src_start_addr(&s_dma.hal, id, (uint32_t)data);
328 dma_hal_set_src_loop_addr(&s_dma.hal, id, (uint32_t)data, (uint32_t)(data + size));
329 dma_hal_set_transfer_len(&s_dma.hal, id, size);
330 dma_hal_start_common(&s_dma.hal, id);
331
332 return BK_OK;
333 }
334
335 /* peripheral->DTCM
336 */
bk_dma_read(dma_id_t id,uint8_t * data,uint32_t size)337 bk_err_t bk_dma_read(dma_id_t id, uint8_t *data, uint32_t size)
338 {
339 DMA_RETURN_ON_NOT_INIT();
340 DMA_RETURN_ON_ID_NOT_INIT(id);
341
342 dma_hal_set_dest_start_addr(&s_dma.hal, id, (uint32_t)data);
343 dma_hal_set_dest_loop_addr(&s_dma.hal, id, (uint32_t)data, (uint32_t)(data + size));
344 dma_hal_set_transfer_len(&s_dma.hal, id, size);
345 dma_hal_start_common(&s_dma.hal, id);
346
347 return BK_OK;
348 }
349
bk_dma_enable_finish_interrupt(dma_id_t id)350 bk_err_t bk_dma_enable_finish_interrupt(dma_id_t id)
351 {
352 DMA_RETURN_ON_ID_NOT_INIT(id);
353 DMA_RETURN_ON_INVALID_ID(id);
354 dma_id_enable_interrupt_common(id);
355 dma_hal_enable_finish_interrupt(&s_dma.hal, id);
356 return BK_OK;
357 }
358
bk_dma_disable_finish_interrupt(dma_id_t id)359 bk_err_t bk_dma_disable_finish_interrupt(dma_id_t id)
360 {
361 DMA_RETURN_ON_ID_NOT_INIT(id);
362 DMA_RETURN_ON_INVALID_ID(id);
363
364 dma_hal_disable_finish_interrupt(&s_dma.hal, id);
365 dma_hal_clear_finish_interrupt_status(&s_dma.hal, id);
366 return BK_OK;
367 }
368
bk_dma_enable_half_finish_interrupt(dma_id_t id)369 bk_err_t bk_dma_enable_half_finish_interrupt(dma_id_t id)
370 {
371 DMA_RETURN_ON_ID_NOT_INIT(id);
372 DMA_RETURN_ON_INVALID_ID(id);
373 dma_id_enable_interrupt_common(id);
374 dma_hal_enable_half_finish_interrupt(&s_dma.hal, id);
375 return BK_OK;
376 }
377
bk_dma_disable_half_finish_interrupt(dma_id_t id)378 bk_err_t bk_dma_disable_half_finish_interrupt(dma_id_t id)
379 {
380 DMA_RETURN_ON_ID_NOT_INIT(id);
381 DMA_RETURN_ON_INVALID_ID(id);
382
383 dma_hal_disable_half_finish_interrupt(&s_dma.hal, id);
384 dma_hal_clear_half_finish_interrupt_status(&s_dma.hal, id);
385 return BK_OK;
386 }
387
bk_dma_register_isr(dma_id_t id,dma_isr_t half_finish_isr,dma_isr_t finish_isr)388 bk_err_t bk_dma_register_isr(dma_id_t id, dma_isr_t half_finish_isr, dma_isr_t finish_isr)
389 {
390 DMA_RETURN_ON_NOT_INIT();
391 DMA_RETURN_ON_INVALID_ID(id);
392
393 GLOBAL_INT_DECLARATION();
394 GLOBAL_INT_DISABLE();
395 s_dma_half_finish_isr[id] = half_finish_isr;
396 s_dma_finish_isr[id] = finish_isr;
397 GLOBAL_INT_RESTORE();
398
399 return BK_OK;
400 }
401
bk_dma_set_transfer_len(dma_id_t id,uint32_t tran_len)402 bk_err_t bk_dma_set_transfer_len(dma_id_t id, uint32_t tran_len)
403 {
404 DMA_RETURN_ON_NOT_INIT();
405 DMA_RETURN_ON_INVALID_ID(id);
406 dma_hal_set_transfer_len(&s_dma.hal, id, tran_len);
407 return BK_OK;
408 }
409
bk_dma_set_src_addr(dma_id_t id,uint32_t start_addr,uint32_t end_addr)410 bk_err_t bk_dma_set_src_addr(dma_id_t id, uint32_t start_addr, uint32_t end_addr)
411 {
412 DMA_RETURN_ON_NOT_INIT();
413 DMA_RETURN_ON_INVALID_ID(id);
414 dma_hal_set_src_start_addr(&s_dma.hal, id, start_addr);
415 dma_hal_set_src_loop_addr(&s_dma.hal, id, start_addr, end_addr);
416 return BK_OK;
417 }
418
bk_dma_set_src_start_addr(dma_id_t id,uint32_t start_addr)419 bk_err_t bk_dma_set_src_start_addr(dma_id_t id, uint32_t start_addr)
420 {
421 DMA_RETURN_ON_NOT_INIT();
422 DMA_RETURN_ON_INVALID_ID(id);
423 dma_hal_set_src_start_addr(&s_dma.hal, id, start_addr);
424 return BK_OK;
425 }
426
bk_dma_set_dest_addr(dma_id_t id,uint32_t start_addr,uint32_t end_addr)427 bk_err_t bk_dma_set_dest_addr(dma_id_t id, uint32_t start_addr, uint32_t end_addr)
428 {
429 DMA_RETURN_ON_NOT_INIT();
430 DMA_RETURN_ON_INVALID_ID(id);
431 dma_hal_set_dest_start_addr(&s_dma.hal, id, start_addr);
432 dma_hal_set_dest_loop_addr(&s_dma.hal, id, start_addr, end_addr);
433 return BK_OK;
434 }
435
bk_dma_set_dest_start_addr(dma_id_t id,uint32_t start_addr)436 bk_err_t bk_dma_set_dest_start_addr(dma_id_t id, uint32_t start_addr)
437 {
438 DMA_RETURN_ON_NOT_INIT();
439 DMA_RETURN_ON_INVALID_ID(id);
440 dma_hal_set_dest_start_addr(&s_dma.hal, id, start_addr);
441 return BK_OK;
442 }
443
bk_dma_enable_src_addr_increase(dma_id_t id)444 bk_err_t bk_dma_enable_src_addr_increase(dma_id_t id)
445 {
446 DMA_RETURN_ON_NOT_INIT();
447 DMA_RETURN_ON_INVALID_ID(id);
448 dma_hal_enable_src_addr_inc(&s_dma.hal, id);
449 return BK_OK;
450 }
451
bk_dma_disable_src_addr_increase(dma_id_t id)452 bk_err_t bk_dma_disable_src_addr_increase(dma_id_t id)
453 {
454 DMA_RETURN_ON_NOT_INIT();
455 DMA_RETURN_ON_INVALID_ID(id);
456 dma_hal_disable_src_addr_inc(&s_dma.hal, id);
457 return BK_OK;
458 }
459
bk_dma_enable_src_addr_loop(dma_id_t id)460 bk_err_t bk_dma_enable_src_addr_loop(dma_id_t id)
461 {
462 DMA_RETURN_ON_NOT_INIT();
463 DMA_RETURN_ON_INVALID_ID(id);
464 dma_hal_enable_src_addr_loop(&s_dma.hal, id);
465 return BK_OK;
466 }
467
bk_dma_disable_src_addr_loop(dma_id_t id)468 bk_err_t bk_dma_disable_src_addr_loop(dma_id_t id)
469 {
470 DMA_RETURN_ON_NOT_INIT();
471 DMA_RETURN_ON_INVALID_ID(id);
472 dma_hal_disable_src_addr_loop(&s_dma.hal, id);
473 return BK_OK;
474 }
475
bk_dma_enable_dest_addr_increase(dma_id_t id)476 bk_err_t bk_dma_enable_dest_addr_increase(dma_id_t id)
477 {
478 DMA_RETURN_ON_NOT_INIT();
479 DMA_RETURN_ON_INVALID_ID(id);
480 dma_hal_enable_dest_addr_inc(&s_dma.hal, id);
481 return BK_OK;
482 }
483
bk_dma_disable_dest_addr_increase(dma_id_t id)484 bk_err_t bk_dma_disable_dest_addr_increase(dma_id_t id)
485 {
486 DMA_RETURN_ON_NOT_INIT();
487 DMA_RETURN_ON_INVALID_ID(id);
488 dma_hal_disable_dest_addr_inc(&s_dma.hal, id);
489 return BK_OK;
490 }
491
bk_dma_enable_dest_addr_loop(dma_id_t id)492 bk_err_t bk_dma_enable_dest_addr_loop(dma_id_t id)
493 {
494 DMA_RETURN_ON_NOT_INIT();
495 DMA_RETURN_ON_INVALID_ID(id);
496 dma_hal_enable_dest_addr_loop(&s_dma.hal, id);
497 return BK_OK;
498 }
499
bk_dma_disable_dest_addr_loop(dma_id_t id)500 bk_err_t bk_dma_disable_dest_addr_loop(dma_id_t id)
501 {
502 DMA_RETURN_ON_NOT_INIT();
503 DMA_RETURN_ON_INVALID_ID(id);
504 dma_hal_disable_dest_addr_loop(&s_dma.hal, id);
505 return BK_OK;
506 }
507
bk_dma_get_remain_len(dma_id_t id)508 uint32_t bk_dma_get_remain_len(dma_id_t id)
509 {
510 DMA_RETURN_ON_NOT_INIT();
511 DMA_RETURN_ON_ID_NOT_INIT(id);
512 return dma_hal_get_remain_len(&s_dma.hal, id);
513 }
514
dma_set_src_pause_addr(dma_id_t id,uint32_t addr)515 bk_err_t dma_set_src_pause_addr(dma_id_t id, uint32_t addr)
516 {
517 DMA_RETURN_ON_NOT_INIT();
518 DMA_RETURN_ON_INVALID_ID(id);
519 dma_hal_set_src_pause_addr(&s_dma.hal, id, addr);
520
521 return BK_OK;
522 }
523
dma_set_dst_pause_addr(dma_id_t id,uint32_t addr)524 bk_err_t dma_set_dst_pause_addr(dma_id_t id, uint32_t addr)
525 {
526 DMA_RETURN_ON_NOT_INIT();
527 DMA_RETURN_ON_INVALID_ID(id);
528 dma_hal_set_dest_pause_addr(&s_dma.hal, id, addr);
529
530 return BK_OK;
531 }
532
dma_get_src_read_addr(dma_id_t id)533 uint32_t dma_get_src_read_addr(dma_id_t id)
534 {
535 DMA_RETURN_ON_NOT_INIT();
536 DMA_RETURN_ON_INVALID_ID(id);
537
538 return dma_hal_get_src_read_addr(&s_dma.hal, id);
539 }
540
dma_get_dest_write_addr(dma_id_t id)541 uint32_t dma_get_dest_write_addr(dma_id_t id)
542 {
543 DMA_RETURN_ON_NOT_INIT();
544 DMA_RETURN_ON_INVALID_ID(id);
545
546 return dma_hal_get_dest_write_addr(&s_dma.hal, id);
547 }
548
bk_dma_set_src_data_width(dma_id_t id,dma_data_width_t data_width)549 bk_err_t bk_dma_set_src_data_width(dma_id_t id, dma_data_width_t data_width)
550 {
551 DMA_RETURN_ON_NOT_INIT();
552 DMA_RETURN_ON_INVALID_ID(id);
553
554 dma_hal_set_src_data_width(&s_dma.hal, id, data_width);
555 return BK_OK;
556 }
557
bk_dma_set_dest_data_width(dma_id_t id,dma_data_width_t data_width)558 bk_err_t bk_dma_set_dest_data_width(dma_id_t id, dma_data_width_t data_width)
559 {
560 DMA_RETURN_ON_NOT_INIT();
561 DMA_RETURN_ON_INVALID_ID(id);
562
563 dma_hal_set_dest_data_width(&s_dma.hal, id, data_width);
564 return BK_OK;
565 }
566
dma_memcpy_by_chnl(void * out,const void * in,uint32_t len,dma_id_t cpy_chnl)567 bk_err_t dma_memcpy_by_chnl(void *out, const void *in, uint32_t len, dma_id_t cpy_chnl)
568 {
569 DMA_RETURN_ON_NOT_INIT();
570 DMA_RETURN_ON_INVALID_ID(cpy_chnl);
571
572 dma_config_t dma_config;
573
574 os_memset(&dma_config, 0, sizeof(dma_config_t));
575
576 dma_config.mode = DMA_WORK_MODE_SINGLE;
577 dma_config.chan_prio = 0;
578
579 dma_config.src.dev = DMA_DEV_DTCM;
580 dma_config.src.width = DMA_DATA_WIDTH_32BITS;
581 dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
582 dma_config.src.start_addr = (uint32_t)in;
583 dma_config.src.end_addr = (uint32_t)(in + len);
584
585 dma_config.dst.dev = DMA_DEV_DTCM;
586 dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
587 dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
588 dma_config.dst.start_addr = (uint32_t)out;
589 dma_config.dst.end_addr = (uint32_t)(out + len);
590
591 DMA_LOGD("dma_memcpy cpy_chnl: %d\r\n", cpy_chnl);
592
593 GLOBAL_INT_DECLARATION();
594 GLOBAL_INT_DISABLE();
595
596 bk_dma_init(cpy_chnl, &dma_config);
597 dma_hal_set_transfer_len(&s_dma.hal, cpy_chnl, len);
598 dma_hal_start_common(&s_dma.hal, cpy_chnl);
599 GLOBAL_INT_RESTORE();
600 BK_WHILE (dma_hal_get_enable_status(&s_dma.hal, cpy_chnl));
601
602 return BK_OK;
603
604 }
605
dma_memcpy(void * out,const void * in,uint32_t len)606 bk_err_t dma_memcpy(void *out, const void *in, uint32_t len)
607 {
608 DMA_RETURN_ON_NOT_INIT();
609
610 bk_err_t ret;
611 dma_id_t cpy_chnl = bk_dma_alloc(DMA_DEV_DTCM);
612 DMA_RETURN_ON_INVALID_ID(cpy_chnl);
613
614 ret = dma_memcpy_by_chnl(out, in, len, cpy_chnl);
615
616 bk_dma_free(DMA_DEV_DTCM, cpy_chnl);
617
618 return ret;
619 }
620
dma_isr(void)621 static void dma_isr(void)
622 {
623 dma_hal_t *hal = &s_dma.hal;
624 for (int id = 0; id < SOC_DMA_CHAN_NUM_PER_UNIT; id++) {
625 if (dma_hal_is_half_finish_interrupt_triggered(hal, id)) {
626 DMA_LOGD("dma_isr HALF FINISH TRIGGERED! id: %d\r\n", id);
627 if (s_dma_half_finish_isr[id]) {
628 DMA_LOGD("dma_isr HALF_finish_isr! id: %d\r\n", id);
629 dma_hal_clear_half_finish_interrupt_status(hal, id);
630 s_dma_half_finish_isr[id](id);
631 }
632 }
633 if (dma_hal_is_finish_interrupt_triggered(hal, id)) {
634 DMA_LOGD("dma_isr ALL FINISH TRIGGERED! id: %d\r\n", id);
635 if (s_dma_finish_isr[id]) {
636 DMA_LOGD("dma_isr ALL_finish_isr! id: %d\r\n", id);
637 dma_hal_clear_finish_interrupt_status(hal, id);
638 s_dma_finish_isr[id](id);
639 }
640 }
641 }
642 }
643
644