2025-05-08 18:01:52 +08:00

633 lines
15 KiB
C
Executable File

// 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.
//
#pragma once
#include <common/bk_include.h>
#include <driver/dma_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Init the DMA driver
*
* This API init the resoure common to all dma channels:
* - Init dma driver control memory
*
* This API should be called before any other dma APIs.
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_driver_init(void);
/**
* @brief Deinit the DMA driver
*
* This API free all resource related to dma and power down all dma channels.
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_driver_deinit(void);
/**
* @brief Allocate a DMA channel
*
* @attention: This API can only be called in task context,
* - and can't be called in context that interrupt is disabled.
*
* This API should be called before any other dma channel APIs.
*
* @param user_id DMA channel applicant
*
* @return DMA channel id.
* - > DMA_ID_MAX: no free DMA channel.
*/
dma_id_t bk_dma_alloc(u16 user_id);
#if CONFIG_GDMA_HW_V2PX
/**
* @brief Allocate a fixed DMA channel.Maybe some APP needs to have a
* fixed channel forever, then it can use this API.
*
* @attention: This API is just for CONFIG_GDMA_HW_V2PX
* And CONFIG_GDMA_HW_V1PX doesn't support it.
*
* This API should be called before any other dma channel APIs.
*
* @param user_id DMA channel applicant
* @param fixed_chnl_id application wants to get which fixed channel
*
* @return DMA channel id.
* - > DMA_ID_MAX: if the fixed_chnl_id has been allocated, it will
* return DMA_ID_MAX which means error.
* - > fixed_chnl_id: the fixed_chnl_id is allocated suc.
*/
dma_id_t bk_fixed_dma_alloc(u16 user_id, dma_id_t fixed_chnl_id);
#endif
/**
* @brief Free the DMA channel
*
* @attention: This API can only be called in task context,
* - and can't be called in context that interrupt is disabled.
*
* @param user_id DMA channel applicant, the same as in bk_dma_alloc.
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_free(u16 user_id, dma_id_t id);
/**
* @brief get the user of DMA channel
*
* @param id DMA channel
*
* @return DMA channel user_id.
* - u32: high u16 is the CPU_ID, low 16 bits is the applicant_id.
*/
uint32_t bk_dma_user(dma_id_t id);
/**
* @brief Init the DMA channel
*
* @attention 1. the higher channel priority value, the higher the priority
*
* @param id DMA channel
* @param config DMA configuration
*
* @return
* - BK_OK: succeed
* - BK_ERR_DMA_NOT_INIT: DMA driver not init
* - BK_ERR_NULL_PARAM: config is NULL
* - BK_ERR_DMA_ID: invalid DMA channel
* - BK_ERR_DMA_INVALID_ADDR: invalid DMA address
* - others: other errors.
*/
bk_err_t bk_dma_init(dma_id_t id, const dma_config_t *config);
/**
* @brief Deinit a DMA channel
*
* This API deinit the DMA channel:
* - Stop the DMA channel
* - Reset all configuration of DMA channel to default value
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_deinit(dma_id_t id);
/**
* @brief Start a DMA channel
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_start(dma_id_t id);
/**
* @brief Stop a DMA channel
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_stop(dma_id_t id);
/**
* @brief Transfer data from memory to peripheral
*
* @param id DMA channel
* @param data DMA transfer data
* @param size data size
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_write(dma_id_t id, const uint8_t *data, uint32_t size);
/**
* @brief Transfer data from peripheral to memory
*
* @param id DMA channel
* @param data DMA transfer data
* @param size data size
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_read(dma_id_t id, uint8_t *data, uint32_t size);
/**
* @brief Enable DMA finish intterrup
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*
* @NOTES before enable interrupt, please confirm have called bk_dma_register_isr.
*/
bk_err_t bk_dma_enable_finish_interrupt(dma_id_t id);
/**
* @brief Disable DMA finish intterrup
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_finish_interrupt(dma_id_t id);
/**
* @brief Enable DMA half finish intterrup
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*
* @NOTES before enable interrupt, please confirm have called bk_dma_register_isr.
*/
bk_err_t bk_dma_enable_half_finish_interrupt(dma_id_t id);
/**
* @brief Disable DMA half finish intterrup
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_half_finish_interrupt(dma_id_t id);
/**
* @brief Register the interrupt service routine for DMA channel
*
* This API regist dma isr callback function.
*
* @param id DMA channel
* @param half_finish_isr DMA half finish callback
* @param finish_isr DMA finish callback
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_register_isr(dma_id_t id, dma_isr_t half_finish_isr, dma_isr_t finish_isr);
#if CONFIG_GDMA_HW_V2PX
/**
* @brief Register the interrupt service routine for DMA channel
*
* This API regist dma isr callback function.
*
* @param id DMA channel
* @param half_finish_isr DMA half finish callback
* @param finish_isr DMA finish callback
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_register_bus_err_isr(dma_id_t id, dma_isr_t bus_err_isr);
#endif
/**
* @brief get DMA transfer max length in one round, default value is 65536 bytes.
*
* @param id DMA channel
*
* @return
* - max len: how many bytes can be copy by DMA in one round.
*/
uint32_t bk_dma_get_transfer_len_max(dma_id_t id);
/**
* @brief Set DMA transfer length
*
* @param id DMA channel
* @param tran_len DMA transfer length, the tran_len should be <= bk_dma_get_transfer_len_max() bytes.
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_transfer_len(dma_id_t id, uint32_t tran_len);
/**
* @brief Set DMA source address
*
* @attention 1. address should be zero when there is no value, e.g. bk_dma_set_src_addr(1, 0x80210C, 0)
*
* @param id DMA channel
* @param start_addr DMA source start address
* @param end_addr DMA source end address
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_src_addr(dma_id_t id, uint32_t start_addr, uint32_t end_addr);
/**
* @brief Set DMA source start address
*
* @param id DMA channel
* @param start_addr DMA source start address
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_src_start_addr(dma_id_t id, uint32_t start_addr);
/**
* @brief Set DMA dest address
*
* @attention 1. address should be zero when there is no value, e.g. bk_dma_set_dest_addr(1, 0x80210C, 0)
*
* @param id DMA channel
* @param start_addr DMA dest start address
* @param end_addr DMA dest end address
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_dest_addr(dma_id_t id, uint32_t start_addr, uint32_t end_addr);
/**
* @brief Set DMA dest start address
*
* @param id DMA channel
* @param start_addr DMA dest start address
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_dest_start_addr(dma_id_t id, uint32_t start_addr);
/**
* @brief Enable DMA source address increase
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_enable_src_addr_increase(dma_id_t id);
/**
* @brief Disable DMA source address increase
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_src_addr_increase(dma_id_t id);
/**
* @brief Enable DMA source address loop
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_enable_src_addr_loop(dma_id_t id);
/**
* @brief Disable DMA source address loop
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_src_addr_loop(dma_id_t id);
/**
* @brief Enable DMA dest address increase
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_enable_dest_addr_increase(dma_id_t id);
/**
* @brief Disable DMA dest address increase
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_dest_addr_increase(dma_id_t id);
/**
* @brief Enable DMA dest address loop
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_enable_dest_addr_loop(dma_id_t id);
/**
* @brief Disable DMA dest address loop
*
* @param id DMA channel
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_disable_dest_addr_loop(dma_id_t id);
/**
* @brief Get DMA transfer remain length
*
* @param id DMA channel
*
* @return DMA transfer remain length
*/
uint32_t bk_dma_get_remain_len(dma_id_t id);
/**
* @brief Gets the current DMA channel working status
*
* @param id DMA channel
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
uint32_t bk_dma_get_enable_status(dma_id_t id);
/**
* @brief flush reserved data in dma internal buffer
* I.E:If source data width is not 4bytes, and data size isn't 4bytes align,
* but dest data width is 4bytes, then maybe 1~3 bytes data reserved in
* dma internal buffer, then the left 1~3 bytes data not copy to dest address.
*
* @param id DMA channel
* @param attr DMA privileged attr
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_flush_src_buffer(dma_id_t id);
#ifdef CONFIG_SPE
/**
* @brief To configure the beat length,
* DMA actually applies for the bus one at a time and divides the total
* amount of data to be transmitted into small data blocks. For example, if
* you want to transfer 64 bytes, then dma may be divided into 2 times internally.
* 64/2=32 bytes are transferred at one time.This 2(a) times is called burst.
*
* @param id DMA channel
* @param len DMA dest burst len
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_dest_burst_len(dma_id_t id, dma_burst_len_t len);
/**
* @brief Get the configured length of burst
*
* @param id DMA channel
*
* @return DMA dest burst length
*/
uint32_t bk_dma_get_dest_burst_len(dma_id_t id);
/**
* @brief To configure the beat length,
* DMA actually applies for the bus one at a time and divides the total
* amount of data to be transmitted into small data blocks. For example, if
* you want to transfer 64 bytes, then dma may be divided into 2 times internally.
* 64/2=32 bytes are transferred at one time.This 2(a) times is called burst.
*
* @param id DMA channel
* @param len DMA dest burst len
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_src_burst_len(dma_id_t id, dma_burst_len_t len);
/**
* @brief Get the configured length of burst
*
* @param id DMA channel
*
* @return DMA dest burst length
*/
uint32_t bk_dma_get_src_burst_len(dma_id_t id);
/**
* @brief Select the conversion mode that needs to be configured for DMA conversion of
* video formats during data transfer.
*
* @param id DMA channel
* @param type DMA Select conversion mode
*
* @return
* - BK_OK: succeed
* - others: other errors.
*/
bk_err_t bk_dma_set_pixel_trans_type(dma_id_t id, dma_pixel_trans_type_t type);
/**
* @brief Get the conversion mode
*
* @param id DMA channel
*
* @return DMA conversion mode
*/
uint32_t bk_dma_get_pixel_trans_type(dma_id_t id);
/**
* @brief Enable the current DMA channel bus err interrupt
*
* @param id DMA channel
*
* @return
* - 0: enable success state
* - others: Channel busy state.
*/
bk_err_t bk_dma_bus_err_int_enable(dma_id_t id);
/**
* @brief Disable the current DMA channel bus err interrupt
*
* @param id DMA channel
*
* @return
* - 0: disable success state
* - others: Channel busy state.
*/
bk_err_t bk_dma_bus_err_int_disable(dma_id_t id);
/**
* @brief Set the current DMA channel dest secure attr
*
* @param id DMA channel
* @param attr DMA secure attr
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_set_dest_sec_attr(dma_id_t id, dma_sec_attr_t attr);
/**
* @brief Set the current DMA channel src secure attr
*
* @param id DMA channel
* @param attr DMA secure attr
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_set_src_sec_attr(dma_id_t id, dma_sec_attr_t attr);
#endif
#if (CONFIG_SPE)
/**
* @brief Set the all DMA channel secure attr
*
* @param id DMA channel
* @param attr DMA secure attr
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_set_sec_attr(dma_id_t id, dma_sec_attr_t attr);
/**
* @brief Set the all DMA channel privileded attr
*
* @param id DMA channel
* @param attr DMA privileged attr
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_set_privileged_attr(dma_id_t id, dma_sec_attr_t attr);
/**
* @brief Configure the same DMA channel to trigger the interrupt state on a fixed core
*
* @param id DMA channel
* @param DMA interrupt id
*
* @return
* - 0: Channel idle state
* - others: Channel busy state.
*/
bk_err_t bk_dma_set_int_allocate(dma_id_t id,dma_int_id_t int_id);
#endif
#ifdef __cplusplus
}
#endif