rt-thread/bsp/phytium/libraries/standalone/drivers/dma/fgdma/fgdma.h

258 lines
9.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fgdma.h
* Date: 2022-02-10 14:53:42
* LastEditTime: 2022-02-18 08:25:35
* Description:  This file is for gdma user api implementation
*
* Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
* 1.0 huanghe 2021/11/5 init commit
* 1.1 zhugengyu 2022/5/16 modify according to tech manual.
*/
#ifndef FGDMA_H
#define FGDMA_H
#include "ftypes.h"
#include "fassert.h"
#include "ferror_code.h"
#include "fkernel.h"
#ifdef __cplusplus
extern "C"
{
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
/* gdma capacity mask */
#define FGDMA_IRQ1_MASK BIT(0) /* All Gdma channel share a single interrupt */
#define FGDMA_IRQ2_MASK BIT(1) /* Each gdma channel owns an independent interrupt */
#define FGDMA_TRANS_NEED_RESET_MASK BIT(2) /* Gdma needs to be reset before transmission */
typedef enum
{
FGDMA_OPER_NONE_PRIORITY_POLL = -1, /* Priority = -1 表示读写请求仲裁模式为Poll */
FGDMA_OPER_PRIORITY0 = 0, /* Priority >= 0 表示读写请求仲裁模式为Qos */
FGDMA_OPER_PRIORITY1 = 1,
FGDMA_OPER_PRIORITY2 = 2,
FGDMA_OPER_PRIORITY3 = 3,
FGDMA_OPER_PRIORITY4 = 4,
FGDMA_OPER_PRIORITY5 = 5,
FGDMA_OPER_PRIORITY6 = 6,
FGDMA_OPER_PRIORITY7 = 7,
FGDMA_OPER_PRIORITY8 = 8,
FGDMA_OPER_PRIORITY9 = 9,
FGDMA_OPER_PRIORITY10 = 10,
FGDMA_OPER_PRIORITY11 = 11,
FGDMA_OPER_PRIORITY12 = 12,
FGDMA_OPER_PRIORITY13 = 13,
FGDMA_OPER_PRIORITY14 = 14,
FGDMA_OPER_PRIORITY15 = 15
} FGdmaOperPriority; /* Qos配置值越高优先级越高 */
typedef enum
{
FGDMA_OPER_DIRECT = 0, /* 直接操作模式 */
FGDMA_OPER_BDL /* BDL操作模式 */
} FGdmaOperMode; /* 支持的操作模式 */
typedef enum
{
FGDMA_BURST_SIZE_1_BYTE = 0,
FGDMA_BURST_SIZE_2_BYTE = 1,
FGDMA_BURST_SIZE_4_BYTE = 2,
FGDMA_BURST_SIZE_8_BYTE = 3,
FGDMA_BURST_SIZE_16_BYTE = 4
} FGdmaBurstSize; /* 支持的读写请求size大小 */
#define FGDMA_GET_BURST_SIZE(brust_align) (1U << brust_align)
typedef enum
{
FGDMA_CHAN_EVT_FIFO_EMPTY = 0, /* 通道Fifo空事件 */
FGDMA_CHAN_EVT_FIFO_FULL, /* 通道Fifo满事件 */
FGDMA_CHAN_EVT_BDL_END, /* BDL模式下一个BDL条目传输完成 */
FGDMA_CHAN_EVT_TRANS_END, /* 所有传输数据完成 */
FGDMA_CHAN_EVT_BUSY, /* 前一次传输未完成,当前还处于传输中 */
FGDMA_CHAN_NUM_OF_EVT
} FGdmaChanEvtType; /* 通道中断事件 */
#define FGDMA_SUCCESS FT_SUCCESS
#define FGDMA_ERR_NOT_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 0)
#define FGDMA_ERR_CHAN_IN_USE FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 1)
#define FGDMA_ERR_CHAN_NOT_INIT FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 2)
#define FGDMA_ERR_INVALID_ADDR FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 3)
#define FGDMA_ERR_INVALID_SIZE FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 4)
#define FGDMA_ERR_BDL_NOT_ENOUGH FT_MAKE_ERRCODE(ErrModBsp, ErrGdma, 5)
#define FGDMA_ADDR_ALIGMENT 128U /* 直接模式和BDL模式的地址需要按128位对齐 */
/**************************** Type Definitions *******************************/
typedef struct _FGdma FGdma;
typedef struct _FGdmaChan FGdmaChan;
typedef struct
{
u32 instance_id; /* GDMA控制器ID */
u32 irq_num[FGDMA_NUM_OF_CHAN]; /* GDMA控制器中断号 */
u32 irq_prority; /* GDMA控制器中断优先级 */
volatile uintptr_t base_addr; /* GDMA控制器基地址 */
FGdmaOperPriority rd_qos; /* 读操作优先级 */
FGdmaOperPriority wr_qos; /* 写操作优先级 */
u32 caps; /* driver capacity */
} FGdmaConfig; /* GDMA控制器配置 */
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描述符 */
FASSERT_STATIC(0x20U == sizeof(FGdmaBdlDesc));
typedef u32 FGdmaChanIndex;
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通道配置 */
typedef void (*FGdmaChanEvtHandler)(FGdmaChan *const chan, void *args);
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通道实例 */
typedef struct _FGdma
{
FGdmaConfig config; /* GDMA控制器配置 */
u32 is_ready; /* GDMA控制器初始化是否完成 */
FGdmaChan *chans[FGDMA_NUM_OF_CHAN]; /* GDMA通道实例如果通道没有分配值为NULL */
} FGdma; /* GDMA控制器实例 */
/************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/* 获取默认的通道配置 */
#define FGDMA_DEFAULT_DIRECT_CHAN_CONFIG(_chan_id)\
(FGdmaChanConfig){ \
.chan_id = (_chan_id),\
.rd_align = FGDMA_BURST_SIZE_4_BYTE,\
.wr_align = FGDMA_BURST_SIZE_4_BYTE,\
.rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\
.wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\
.trans_mode = FGDMA_OPER_DIRECT,\
.roll_back = FALSE\
}
#define FGDMA_DEFAULT_BDL_CHAN_CONFIG(_chan_id, _bdl_descs, _bdl_desc_num)\
(FGdmaChanConfig){ \
.chan_id = (_chan_id),\
.rd_align = FGDMA_BURST_SIZE_4_BYTE,\
.wr_align = FGDMA_BURST_SIZE_4_BYTE,\
.rd_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\
.wr_qos = FGDMA_OPER_NONE_PRIORITY_POLL,\
.trans_mode = FGDMA_OPER_BDL,\
.roll_back = FALSE,\
.descs = _bdl_descs,\
.total_desc_num = _bdl_desc_num,\
.valid_desc_num = 0U\
}
/************************** Function Prototypes ******************************/
/* 获取GDMA控制器默认配置 */
const FGdmaConfig *FGdmaLookupConfig(u32 instance_id);
/* 初始化GDMA控制器实例 */
FError FGdmaCfgInitialize(FGdma *const instance_p, const FGdmaConfig *config_p);
/* 去初始化GDMA控制器实例 */
void FGdmaDeInitialize(FGdma *const instance_p);
/* 分配指定GDMA通道 */
FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const chan_p,
const FGdmaChanConfig *config_p);
/* 释放GDMA通道 */
FError FGdmaDellocateChan(FGdmaChan *const chan_p);
/* 直接操作模式下发起DMA传输 */
FError FGdmaDirectTransfer(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len);
/* 设置BDL描述符的一个条目 */
FError FGdmaAppendBDLEntry(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len);
/* BDL操作模式下发起DMA传输 */
FError FGdmaBDLTransfer(FGdmaChan *const chan_p);
/* 使能启动GDMA控制器 */
FError FGdmaStart(FGdma *const instance_p);
/* 停止GDMA控制器 */
FError FGdmaStop(FGdma *const instance_p);
/* GDMA中断处理函数 */
void FGdmaIrqHandler(s32 vector, void *args);
void FGdmaIrqHandlerPrivateChannel(s32 vector, void *args);
/* 注册GDMA通道事件回调函数 */
void FGdmaChanRegisterEvtHandler(FGdmaChan *const chan_p, FGdmaChanEvtType evt,
FGdmaChanEvtHandler handler, void *handler_arg);
/* 打印当前的GDMA寄存器值, DEBUG模式下有效 */
void FGdmaDumpRegisterVals(uintptr base_addr, u32 max_chan);
#ifdef __cplusplus
}
#endif
#endif