GDMA(Generic Direct Memory Access),提供多个DMA通道,多个通道可以同时工作,独立配置给不同内存数据搬运使用
FGDMA 驱动程序主要完成 GDMA 模块的初始化,GDMA 通道的分配与释放, 相关源文件为:
fgdma
.
├── fgdma.c
├── fgdma.h
├── fgdma_g.c
├── fgdma_hw.h
├── fgdma_intr.c
├── fgdma_selftest.c
└── fgdma_sinit.c
以下部分将指导您完成 FGDMA 驱动的软件配置:
GDMA控制器配置
typedef struct
{
u32 instance_id; /* GDMA控制器ID */
u32 irq_num; /* GDMA控制器中断号 */
u32 irq_prority; /* GDMA控制器中断优先级 */
volatile uintptr_t base_addr; /* GDMA控制器基地址 */
FGdmaOperPriority rd_qos; /* 读操作优先级 */
FGdmaOperPriority wr_qos; /* 写操作优先级 */
} FGdmaConfig;
DMA通道配置
typedef struct
{
FGdmaChanIndex chan_id; /* DMA通道ID */
FGdmaOperPriority rd_qos; /* DMA通道读Qos配置 */
FGdmaOperPriority wr_qos; /* DMA通道写Qos配置 */
FGdmaOperMode trans_mode; /* DMA通道的操作模式,直接模式或者BDL模式 */
/* Direct模式有效 */
FGdmaBurstSize rd_align; /* DMA读请求的Burst对齐方式 */
FGdmaBurstSize wr_align; /* DMA写请求的Burst对齐方式 */
/* BDL模式有效 */
boolean roll_back; /* 循环模式,TRUE: 当前BDL列表完成后,从第一个BDL项从新开始传输 */
FGdmaBdlDesc *descs;
u32 total_desc_num;
u32 valid_desc_num;
} FGdmaChanConfig; /* DMA通道配置 */
GDMA通道实例
typedef struct _FGdmaChan
{
FGdmaChanConfig config; /* DMA通道配置 */
FGdma *gdma; /* DMA控制器实例 */
FGdmaChanEvtHandler evt_handlers[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数 */
void *evt_handler_args[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数入参 */
} FGdmaChan; /* GDMA通道实例 */
GDMA控制器实例
typedef struct _FGdma
{
FGdmaConfig config; /* GDMA控制器配置 */
u32 is_ready; /* GDMA控制器初始化是否完成 */
FGdmaChan *chans[FGDMA_NUM_OF_CHAN]; /* GDMA通道实例,如果通道没有分配,值为NULL */
} FGdma; /* GDMA控制器实例 */
BDL描述符
typedef struct
{
u32 src_addr_l; /* 0x0, 数据源地址低32位 */
u32 src_addr_h; /* 0x4, 数据源地址高32位 */
u32 dst_addr_l; /* 0x8, 数据目的地址低32位 */
u32 dst_addr_h; /* 0xc, 数据目的地址高32位 */
#define FGDMA_SRC_TC_BDL_BURST_SET(x) SET_REG32_BITS((x), 1U, 0U)
#define FGDMA_SRC_TC_BDL_SIZE_SET(x) SET_REG32_BITS((x), 6U, 4U)
#define FGDMA_SRC_TC_BDL_LEN_SET(x) SET_REG32_BITS((x), 15U, 8U)
u32 src_tc; /* 0x10, 源传输控制位 */
#define FGDMA_DST_TC_BDL_BURST_SET(x) SET_REG32_BITS((x), 1U, 0U)
#define FGDMA_DST_TC_BDL_SIZE_SET(x) SET_REG32_BITS((x), 6U, 4U)
#define FGDMA_DST_TC_BDL_LEN_SET(x) SET_REG32_BITS((x), 15U, 8U)
u32 dst_tc; /* 0x14, 目的传输控制 */
u32 total_bytes;/* 0x18, 传输数据总量,以Byte为单位 */
u32 ioc; /* 0x1c, 该条目传输完成中断产生控制位 */
} __attribute__((__packed__)) FGdmaBdlDesc; /* BDL描述符 */
#define FGDMA_SUCCESS : 成功
#define FGDMA_ERR_NOT_INIT : 驱动未初始化
#define FGDMA_ERR_CHAN_IN_USE : 通道已经绑定无法分配
#define FGDMA_ERR_CHAN_NOT_INIT : 通道未初始化
#define FGDMA_ERR_INVALID_ADDR : 传输地址非法
#define FGDMA_ERR_INVALID_SIZE : 传输字节数非法
#define FGDMA_ERR_BDL_NOT_ENOUGH : BDL已经使用完
const FGdmaConfig *FGdmaLookupConfig(u32 instance_id)
Note:
Input:
Return:
FError FGdmaCfgInitialize(FGdma *const instance_p, const FGdmaConfig *input_config)
Note:
Input:
Return:
void FGdmaDeInitialize(FGdma *const instance_p)
Note:
Input:
Return:
FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const dma_chan,
const FGdmaChanConfig *dma_chan_config)
Note:
Input:
Return:
FError FGdmaDellocateChan(FGdmaChan *const dma_chan)
Note:
Input:
Return:
FError FGdmaDirectTransfer(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len);
Note:
Input:
Return:
FError FGdmaAppendBDLEntry(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len)
Note:
Input:
Return:
FError FGdmaBDLTransfer(FGdmaChan *const chan_p)
Note:
Input:
Return:
FError FGdmaStart(FGdma *const instance_p)
Note:
Input:
Return:
FError FGdmaStop(FGdma *const instance_p)
Note:
Input:
Return:
void FGdmaIrqHandler(s32 vector, void *args)
Note:
Input:
Return:
void FGdmaChanRegisterEvtHandler(FGdmaChan *const chan_p, FGdmaChanEvtType evt,
FGdmaChanEvtHandler handler, void *handler_arg)
Note:
Input:
Return: