105 lines
3.2 KiB
C
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;
|
||
|
|
}
|
||
|
|
|