// 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 #include #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