DMA裸板驱动使用说明
1 DMA简要说明
1.1 GDP812的dmac
812 dmac在4个subsys中集成,分别是:sysctrl、safety、mem、audio;
dmac的apb slv memmap要根据各subsys 在SOC分配的地址空间决定;
dmac的axi master能访问到的memmap 同样的需要去根据各subsys访问能力(子系统内L2 noc matrix和mainnoc matrix)决定;
dmac 本身是支持44bit地址全SOC访问;
1.2 DMA-330的使用
DMA-330采用MicroCode的方式实现DMA的独立控制,可以理解为该DMA Controller为ARM的一个Coprocessor。按照MicroCode的指令集规则编写指令,存放到指定地址的内存中,ARM处理器只需要告诉DMA Controller汇编指令的起始地址,DMA Controller就可以执行内存中存放的汇编指令,实现独立于处理器的数据搬运工作。
2 裸驱代码使用介绍
目前是第一版裸驱代码,在rk-3588开发板平台验证过Mem2Mem,Mem2Uart_Tx和Uart_Rx2Mem三种情况,在GDP812平台仅验证过Mem2Mem的情形。若实际调试过程中遇到DMA相关问题,请及时沟通。
该裸驱代码共有3个文件
dma-hw.h 用于存放和硬件相关的配置信息
dma-330.h 与硬件无关的驱动代码头文件
dma-330.c 与硬件无关的驱动代码文件
从裸驱代码的使用角度,有如下需要修改的几个地方:
2.1 硬件相关的配置信息
/** * dma-hw.h */ /* DMAC寄存器的Base Address,对于不同的Subsystem这个值是不同的 */ #define PL330_BASE_ADDR DMA0_NS_BASE_ADDR /* MicroCode指令放置的内存地址 */ #define MCODE_CPU_ADDR 0x08001000 /* cpu access desc addr */ #define MCODE_BUS_ADDR 0x08001000 /* bus access desc addr */ /* 数据搬运的源地址和目的地址 */ #define MEM_SRC_ADDR 0x80000000 #define MEM_DST_ADDR 0x800100002.2 SoftReset和Clock配置
需要在测试代码中自行实现软复位和时钟的配置,如下示例,给出了sysctrl DMA的软复位和时钟配置:
static void sys_init(void) { /* sysctrl dma */ writel(0x1, (void*)0x49800104); writel(0x1, (void*)0x49800100); }2.3 配置结构体的填充
需要在测试代码中自行实现配置结构体的填充
2.3.1 配置结构体的成员说明
/* 传输配置结构体 */ struct pl330_trans_cfg { unsigned int src_phy_addr; unsigned int dst_phy_addr; enum __tfr_type tfr_type; int trans_len; unsigned char privileged; unsigned char nonsecure; enum burst_cfg user_cfg_bst; unsigned int tfr_data_width; unsigned int tfr_data_len; unsigned int peri_num; };src_phy_addr :数据传输的源地址;
dst_phy_addr :数据传输的目的地址;
tfr_type :数据传输的类型,有以下三种可选类型;
DMAC_TFR_TYPE_M2M:适用于Mem to Mem的数据传输,Src和Dst地址都递增的情形;
DMAC_TFR_TYPE_M2P :适用于Mem to Peri的数据传输,Src地址递增,Dst地址固定的情形;
DMAC_TFR_TYPE_P2M :适用于Peri to Mem的数据传输,Src地址固定,Dst地址递增的情形;
trans_len :数据传输的总长度;
privileged :AXI总线特权访问配置位;
0:非特权访问AXI总线;
1:特权访问,用于高权限操作;
nonsecure :AXI总线安全访问配置位;
0:安全访问,用于安全模式下的数据访问;
1:非安全访问;
user_cfg_bst :目前只支持两种配置选择:
USE_AXI_MAX_CAP :以硬件配置的AXI总线位宽进行数据传输,Mem to Mem的数据传输时使用;
USE_DEFINED :以用户自定义的burst_size和burst_len进行数据传输,M2P和P2M时使用;
tfr_data_width:用户自定义的burst_size;
tfr_data_len :用户自定义的burst_len;
peri_num :Mem2Mem时无效,用于配置DMAC与硬件握手时的握手编号;
2.3.2 配置结构体的配置示例
针对配置结构体的成员说明,以Mem2Peri(UART_TX)为例,提供如下示例:
static void transfer_cfg(struct pl330_trans_cfg *cfg) { cfg->dst_phy_addr = MEM_SRC_ADDR; cfg->src_phy_addr = MEM_DST_ADDR; cfg->tfr_type = DMAC_TFR_TYPE_M2P; cfg->trans_len = 8; /* 数据传输的总长度 8-byte */ cfg->privileged = 0; /* 非特权访问 */ cfg->nonsecure = 1; /* 非安全访问 */ /** * 以Mem2Uart_Tx为例 * 一个burst内,Memory向UartTx buffer发送1-Byte数据,并等待Uart做出回应后再进行下一次数据发送。 * * 1 burst的数据量大小 = burst_size * burst_len,因此tfr_data_width和tfr_data_len都为1。 */ cfg->user_cfg_bst = USE_DEFINED; cfg->tfr_data_width = 1; /* 用户自定义的burst_size */ cfg->tfr_data_len = 1; /* 用户自定义的burst_len */ cfg->peri_num = UART_TX; /* UART2_TX的设备编号 */ }3 GDP-812与DMA相关的配置
3.1 DMAC Base Address
如下图所示,有些Subsystem中用于DMA IP配置的基地址相对于Memory Map提供的Base Address存在4K的偏移。
3.1.1 SysCtrl
Memory Map中的地址
dmac apb_slv_NS:0x4a002000
dmac apb_slv_S :0x4a005000
实际使用的地址:
DAMC_BASE_ADDR(ns): 0x4a003000
即:dmac apb_slv_NS(0x4a002000) + 0x1000
DMAC_BASE_ADDR(s) :0x4a006000
即:dmac apb_slv_S(0x4a005000) + 0x1000
3.1.2 safety
Memory Map中的地址
Safety DMA sec apb:0x4a800000
Safety DMA apb :0x4ac00000
实际使用的地址:是否偏移0x1000需要IP Owner确认
DMAC_BASE_ADDR(sec apb) : 0x4a801000
DMAC_BASE_ADDR(non-sec) : 0x4ac01000
3.1.3 Memory
Memory Map中的地址:
noc2damc_apb_slv(ns) :0x52628000
noc2dmac_sec_apb_slv:0x52638000
实际使用的地址:是否偏移0x1000需要IP Owner确认
DMAC_BASE_ADDR(non-sec) : 0x52629000
DMAC_BASE_ADDR(sec) : 0x52639000
3.1.4 Audio
Memory Map中的地址:
DMAC_0
audio_noc2dmac0_s_apb_slv :0x5cc50000
audio_noc2dmac0_ns_apb_slv:0x5cc60000
DMAC_1
audio_noc2dmac1_ns_apb_slv:0x5cd10000
audio_noc2dmac0_s_apb_slv :0x5cd20000
实际使用的地址:是否偏移0x1000需要IP Owner确认
DMAC_0
DMAC_BASE_ADDR(sec) :0x5cc51000
DMAC_BASE_ADDR(ns) :0x5cc61000
DMAC_1
DMAC_BASE_ADDR(ns) :0x5cd11000
DMAC_BASE_ADDR(sec) :0x5cd21000
3.2 Periphal Num
根据各Subsystem的Design Spec的描述,在dma-hw.h中列出各Subsystem的DMAC握手信号的Peripheral Number,不保证正确,请各IP Owner自行确认,如下:
3.2.1 SysCtrl
/** * Sysctrl Subsystem DMA-Peripheral Handshake */ enum { SYSCTRL_QSPI_FLASH_TX, SYSCTRL_QSPI_FLASH_RX, SYSCTRL_USI0_TX, SYSCTRL_USI1_TX, SYSCTRL_USI2_TX, SYSCTRL_USI3_TX, SYSCTRL_USI4_TX, SYSCTRL_USI5_TX, SYSCTRL_USI6_TX, SYSCTRL_USI7_TX, SYSCTRL_USI0_RX, SYSCTRL_USI1_RX, SYSCTRL_USI2_RX, SYSCTRL_USI3_RX, SYSCTRL_USI4_RX, SYSCTRL_USI5_RX, SYSCTRL_USI6_RX, SYSCTRL_USI7_RX, };3.2.2 safety
3.2.3 Memory
3.2.4 Audio
3.3 软复位和Clock配置
3.3.1 SysCtrl
0x49800100 = 0x1
0x49800104 = 0x1
3.3.2 safety
(软复位和时钟配置,需要IP Owner确认)
3.3.3 Memory
(软复位和时钟配置,需要IP Owner确认)
3.3.4 Audio
(软复位和时钟配置,需要IP Owner确认)
DMAC_0
DMAC_1