2025-10-10 16:07:00 +08:00

105 lines
3.2 KiB
C

// Copyright 2020-2021 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dma_hal.h"
#include "dma_ll.h"
#define DMA_HAL_RETURN_ON_INVALID_ADDR(start_addr, end_addr) do {\
if ((0 < (end_addr)) && ((end_addr) < (start_addr))) {\
return BK_ERR_DMA_HAL_INVALID_ADDR;\
}\
} while(0)
bk_err_t dma_hal_init(dma_hal_t *hal)
{
hal->hw = (dma_hw_t *)DMA_LL_REG_BASE(hal->id);
//TODO:only CPU0 init hardware
#if CONFIG_SYS_CPU0
dma_ll_init(hal->hw);
#endif
dma_ll_set_prio_mode_round_robin(hal->hw);
return BK_OK;
}
void dma_hal_init_without_channels(dma_hal_t *hal)
{
hal->hw = (dma_hw_t *)DMA_LL_REG_BASE(hal->id);
//soft reset for all CPUs
dma_ll_init_without_channels(hal->hw);
}
bk_err_t dma_hal_init_dma(dma_hal_t *hal, dma_id_t id, const dma_config_t *config)
{
DMA_HAL_RETURN_ON_INVALID_ADDR(config->src.start_addr, config->src.end_addr);
DMA_HAL_RETURN_ON_INVALID_ADDR(config->dst.start_addr, config->dst.end_addr);
dma_ll_set_work_mode(hal->hw, id, config->mode);
dma_ll_set_chan_prio(hal->hw, id, config->chan_prio);
dma_ll_set_dest_data_width(hal->hw, id, config->dst.width);
dma_ll_set_src_data_width(hal->hw, id, config->src.width);
dma_ll_set_dest_req_mux(hal->hw, id, config->dst.dev);
dma_ll_set_src_req_mux(hal->hw, id, config->src.dev);
#if CONFIG_GDMA_HW_V2PX
dma_ll_set_pixel_trans_type(hal->hw, id, config->trans_type);
dma_ll_set_dest_write_interval(hal->hw, id, config->dest_wr_intlv);
dma_ll_set_src_read_interval(hal->hw, id, config->src_rd_intlv);
#endif
dma_ll_set_src_start_addr(hal->hw, id, config->src.start_addr);
dma_ll_set_src_loop_addr(hal->hw, id, config->src.start_addr, config->src.end_addr);
dma_ll_set_dest_start_addr(hal->hw, id, config->dst.start_addr);
dma_ll_set_dest_loop_addr(hal->hw, id, config->dst.start_addr, config->dst.end_addr);
if (config->src.addr_inc_en) {
dma_ll_enable_src_addr_inc(hal->hw, id);
} else {
dma_ll_disable_src_addr_inc(hal->hw, id);
}
if (config->src.addr_loop_en) {
dma_ll_enable_src_addr_loop(hal->hw, id);
} else {
dma_ll_disable_src_addr_loop(hal->hw, id);
}
if (config->dst.addr_inc_en) {
dma_ll_enable_dest_addr_inc(hal->hw, id);
} else {
dma_ll_disable_dest_addr_inc(hal->hw, id);
}
if (config->dst.addr_loop_en) {
dma_ll_enable_dest_addr_loop(hal->hw, id);
} else {
dma_ll_disable_dest_addr_loop(hal->hw, id);
}
return BK_OK;
}
bk_err_t dma_hal_start_common(dma_hal_t *hal, dma_id_t id)
{
dma_ll_enable(hal->hw, id);
return BK_OK;
}
bk_err_t dma_hal_stop_common(dma_hal_t *hal, dma_id_t id)
{
dma_ll_clear_interrupt_status(hal->hw, id);
dma_ll_disable(hal->hw, id);
return BK_OK;
}