/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef __AXIDMA_H__ #define __AXIDMA_H__ #include "osi_api.h" #ifdef __cplusplus extern "C" { #endif /** * @brief AXIDMA interrupt event */ typedef enum { AD_EVT_FINISH = (1 << 0), ///< event transfer done AD_EVT_PART_FINISH = (1 << 1), ///< event transfer once done (part size) AD_EVT_STOP = (1 << 2), ///< event the channel stop } drvAxidmaIrqEvent_t; /** * @brief AXIDMA data type */ typedef enum { AD_DATA_8BIT = 0, AD_DATA_16BIT = 1, AD_DATA_32BIT = 2, AD_DATA_64BIT = 3, } drvAxidmaDataType_t; /** * @brief function type to process AXIDMA channel interrupt */ typedef void (*drvAxidmaIsr_t)(drvAxidmaIrqEvent_t evt, void *p); /** * @brief the AXIDMA channel, call do not need to know its implement */ typedef struct drv_axidma_channel drvAxidmaCh_t; /** * @brief AXIDMA channel config */ typedef struct drv_axidma_config { uint32_t src_addr; ///< source address uint32_t dst_addr; ///< destination address uint32_t data_size; ///< data size in byte uint32_t part_trans_size; ///< transfer size once in byte drvAxidmaDataType_t data_type; ///< dma data type drvAxidmaIrqEvent_t mask; ///< react interrupt mask uint8_t src_addr_fix : 1; ///< source address fixed (like hw fifo) uint8_t dst_addr_fix : 1; ///< destination address fixed uint8_t sync_irq : 1; ///< request trigger mode uint8_t force_trans : 1; ///< force trans start uint8_t req_sel_level : 1; ///< high level trigger } drvAxidmaCfg_t; /** * @brief AXIDMA module initialization * * CP will rely on the initialization, so it should be called before * release CP reset. */ void drvAxidmaInit(void); /** * @brief AXIDMA resume after wakeup * * Due to CP will rely on AXIDMA, it will be called explicitly rather * than using the suspend/resume callback. This will make it earlier to * release CP reset. */ void drvAxidmaResume(osiSuspendMode_t mode, uint32_t source); /** * @brief allocate an AXIDMA channel * * @return * - NULL no free axidma channel * - OTHERS axidma channel */ drvAxidmaCh_t *drvAxidmaChAllocate(); /** * @brief release an AXIDMA channel * * @param ch the AXIDMA channel */ void drvAxidmaChRelease(drvAxidmaCh_t *ch); /** * @brief start the AXIDMA channel * * @param ch the AXIDMA channel * @param cfg start config * @return * - true success * - flase fail */ bool drvAxidmaChStart(drvAxidmaCh_t *ch, const drvAxidmaCfg_t *cfg); /** * @brief stop the AXIDMA channel * * Stop the AXIDMA channel, all transfer will stop, may triger a STOP event. * * During stop, channel pending data count may be modified. So, the return * value of \p drvAxidmaChCount after this is unreliable. Rather, the return * value of this function shall be used. * * @param ch the AXIDMA channel * @return * - channel pending data count * - 0 on invalid parameter */ unsigned drvAxidmaChStop(drvAxidmaCh_t *ch); /** * @brief check if the AXIDMA channel is busy * * @param ch the AXIDMA channel * @return * - true busy * - false not busy */ bool drvAxidmaChBusy(drvAxidmaCh_t *ch); /** * @brief set AXIDMA map for a specific channel * * @param ch the AXIDMA channel * @param req_source request source * @param ack_map ack map */ void drvAxidmaChSetDmamap(drvAxidmaCh_t *ch, uint8_t req_source, uint8_t ack_map); /** * @brief get AXIDMA channel pending count * * Get pending data for an AXIDMA channel in bytes. * Caller can calculate the AXIDMA actually transfered data size * by total size minus this count. * * @param ch the AXIDMA channel * @return * - (Non-negative integer) pending data count in byte */ uint32_t drvAxidmaChCount(drvAxidmaCh_t *ch); /** * @brief register a interrupt handler for a specific AXIDMA channel * * @param ch the AXIDMA channel * @param isr interrupt routine * @param param call private data (like context) */ void drvAxidmaChRegisterIsr(drvAxidmaCh_t *ch, drvAxidmaIsr_t isr, void *param); /** * @brief stop all AXIDMA channel * * It is only intented to be called at enter panic. */ void drvAxidmaStopAll(void); #endif /* __AXIDMA_H__ */