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 "dma_hal.h"
16 #include "dma_ll.h"
17
18 #define DMA_HAL_RETURN_ON_INVALID_ADDR(start_addr, end_addr) do {\
19 if ((0 < (end_addr)) && ((end_addr) < (start_addr))) {\
20 return BK_ERR_DMA_HAL_INVALID_ADDR;\
21 }\
22 } while(0)
23
dma_hal_init(dma_hal_t * hal)24 bk_err_t dma_hal_init(dma_hal_t *hal)
25 {
26 hal->hw = (dma_hw_t *)DMA_LL_REG_BASE(hal->id);
27 #if !CONFIG_SLAVE_CORE
28 dma_ll_init(hal->hw);
29 #endif
30 dma_ll_set_prio_mode_round_robin(hal->hw);
31 return BK_OK;
32 }
33
dma_hal_init_dma(dma_hal_t * hal,dma_id_t id,const dma_config_t * config)34 bk_err_t dma_hal_init_dma(dma_hal_t *hal, dma_id_t id, const dma_config_t *config)
35 {
36 DMA_HAL_RETURN_ON_INVALID_ADDR(config->src.start_addr, config->src.end_addr);
37 DMA_HAL_RETURN_ON_INVALID_ADDR(config->dst.start_addr, config->dst.end_addr);
38
39 dma_ll_set_work_mode(hal->hw, id, config->mode);
40 dma_ll_set_chan_prio(hal->hw, id, config->chan_prio);
41
42 dma_ll_set_dest_data_width(hal->hw, id, config->dst.width);
43 dma_ll_set_src_data_width(hal->hw, id, config->src.width);
44
45 dma_ll_set_dest_req_mux(hal->hw, id, config->dst.dev);
46 dma_ll_set_src_req_mux(hal->hw, id, config->src.dev);
47
48 dma_ll_set_src_start_addr(hal->hw, id, config->src.start_addr);
49 dma_ll_set_src_loop_addr(hal->hw, id, config->src.start_addr, config->src.end_addr);
50 dma_ll_set_dest_start_addr(hal->hw, id, config->dst.start_addr);
51 dma_ll_set_dest_loop_addr(hal->hw, id, config->dst.start_addr, config->dst.end_addr);
52
53 if (config->src.addr_inc_en) {
54 dma_ll_enable_src_addr_inc(hal->hw, id);
55 } else {
56 dma_ll_disable_src_addr_inc(hal->hw, id);
57 }
58
59 if (config->src.addr_loop_en) {
60 dma_ll_enable_src_addr_loop(hal->hw, id);
61 } else {
62 dma_ll_disable_src_addr_loop(hal->hw, id);
63 }
64
65 if (config->dst.addr_inc_en) {
66 dma_ll_enable_dest_addr_inc(hal->hw, id);
67 } else {
68 dma_ll_disable_dest_addr_inc(hal->hw, id);
69 }
70
71 if (config->dst.addr_loop_en) {
72 dma_ll_enable_dest_addr_loop(hal->hw, id);
73 } else {
74 dma_ll_disable_dest_addr_loop(hal->hw, id);
75 }
76
77 return BK_OK;
78 }
79
dma_hal_start_common(dma_hal_t * hal,dma_id_t id)80 bk_err_t dma_hal_start_common(dma_hal_t *hal, dma_id_t id)
81 {
82 dma_ll_enable(hal->hw, id);
83 return BK_OK;
84 }
85
dma_hal_stop_common(dma_hal_t * hal,dma_id_t id)86 bk_err_t dma_hal_stop_common(dma_hal_t *hal, dma_id_t id)
87 {
88 dma_ll_clear_interrupt_status(hal->hw, id);
89 dma_ll_disable(hal->hw, id);
90 return BK_OK;
91 }
92
93