dw_axi_dmac总结

3.7 DW_axi_dmac

3.7.1 设计特点

​ DW_axi_dmac是Synopsys公司设计的一款高性能、可配置的DMA(直接内存访问)控制器IP核,专为基于AMBA AXI总线‌的SoC系统打造。它旨在卸载CPU的数据搬运任务,通过硬件加速实现外设与内存之间的高效数据传输,显著提升系统吞吐量和实时性。‌‌

1. 架构与接口特性

  • 总线接口:提供 AXI 主接口(用于高速数据读写)和 AXI/AXI-Lite/APB 从接口(用于 CPU 对控制/状态寄存器的配置与访问),支持 32/64 位数据宽度。
  • 通道架构:支持多通道(最多可配置 8 个或 16 个独立通道),各通道可独立配置、并行工作,支持通道优先级管理。
  • 硬件握手:提供硬件握手接口(DMA_REQ/DMA_ACK/DMA_FINISH),支持硬件/软件握手,提供细粒度(单事务)和粗粒度(块传输)的握手机制,满足不同外设的流控需求。

2. 传输模式与机制

  • 传输类型:支持内存到内存(M2M)、内存到外设(M2P)、外设到内存(P2M)及外设到外设(P2P)传输,支持多种传输粒度(单事务、突发传输)。

  • 多块传输(Multi-Block)

    :支持三种多块传输机制,以适应不同的连续数据传输需求:

    • 链表传输(Linked List):通过链表项(LLI)自动读取下一块传输参数,支持 scatter-gather(分散-聚集)传输,适合处理物理不连续的数据块。
    • 自动重载(Auto-Reloading):在块传输完成后,自动将预设的初始值重新加载到通道寄存器,适合周期性、重复性的数据传输(如刷新缓冲区)。
    • 连续地址传输(Contiguous Address):块传输完成后,自动将地址递加作为下一块的起始地址,适合处理物理连续的大数据块。
  • 突发传输(Burst):支持可配置的突发长度(如 1、4、8、16、32、64、128 等),通过合并连续传输减少总线请求次数,提升传输效率。

3. 传输控制与配置

  • 灵活的配置:支持可配置的传输宽度(8/16/32/64 位)和地址递增/递减模式,支持通道控制寄存器(CH_CTL)和配置寄存器(CH_CFG)的独立配置,支持影子寄存器机制,实现无缝的连续传输。
  • 流控与仲裁:支持多种流控模式(DMA 控制器控制、外设控制),支持通道锁定与仲裁,保证高优先级通道的实时性。

4. 中断与状态管理

  • 中断机制:提供全局中断和通道独立中断,支持块传输完成中断、错误中断等,支持中断屏蔽与清除,便于CPU进行传输状态监控和异常处理。
  • 状态反馈:提供丰富的状态寄存器(如传输状态、中断状态),支持状态写回机制,便于软件进行传输结果确认和调试。
3.7.2 核心寄存器总览

​ dw_axi-dmac的寄存器主要分为两个大的部分,一部分为全局寄存器 ,另一部分为每个传输通道私有寄存器

  • Common registers
偏移量 寄存器名称 功能概述
0x000 DMAC_ID Component ID Register
0x008 DMAC_COMPVER Component Version Register
0x010 DMAC_CFG Global Configuration Register (配置寄存器)
0x018 DMAC_CHEN Channel Enable Register (使能寄存器,一个bit使能一个通道)
0x020 DMAC_CHSUSPREG Channel Suspend Register
0x028 DMAC_CHABORTREG Channel Abort Register
0x030 DMAC_INTSTATUS Combined Interrupt Status Register
0x038 DMAC_COMMON_INTCLEAR Common Register Space Interrupt Clear Register
0x040 DMAC_COMMON_INTSTATUS_ENA Common Register Space Interrupt Enable Register
0x048 DMAC_COMMON_INTSIGNAL_ENA Common Register Space Interrupt Signal Enable Register
0x050 DMAC_COMMON_INTSTATUS Common Register Space Interrupt Status Register
0x058 DMAC_RESET Software Reset Register
  • DMA channel registers
偏移量 寄存器名称 功能描述
0x000 CH_SAR Channel x Source Address Register(数据源地址寄存器)
0x008 CH_DAR Channel x Destination Address Register(目的地址寄存器)
0x010 CH_BLOCK_TS Channel x Block Transfer Size Register (这个地址的值根据传输长度和数据宽度得出)
0x018 CH_CTL Channel x Control Register (控制寄存器)
0x020 CH_CFG Channel x Configuration Register (配置寄存器)
0x028 CH_LLP Channel x Linked List Pointer Register (链表模式下使用该寄存器)
0x030 CH_STATUS Channel x Status Register
0x038 CH_SWHSSRC Channel x Software Handshake Source Register
0x040 CH_SWHSDST Channel x Software Handshake Destination Register
0x048 CH_BLK_TFR_RESUMEREQ Channel x Block Transfer Resume Request Register
0x50 CH_AXI_ID Channel x AXI ID Register
0x58 CH_AXI_QOS Channel x AXI QoS Register
0x60 CH_SSTAT Channel x Source Status Register
0x68 CH_DSTAT Channel x Destination Status Register
0x70 CH_SSTATAR Channel x Source Status Fetch Register
0x78 CH_DSTATAR Channel x Destination Status Fetch Register
0x080 CH_INTSTATUS_ENA Channel x Interrupt Status Enable Register
0x088 CH_INTSTATUS Channel x Interrupt Status Register(可以查询bit2判断传输是否完成)
0x090 CH_INTSIGNAL_ENA Channel x Interrupt Signal Enable Register(需要使能才会有中断信号)
0x098 CH_INTCLEAR Channel x Interrupt Status Clear Register(传输完成时清中断)
3.7.3 核心寄存器详解

**CH_SAR和CH_DAR:**数据的源地址寄存器和目的寄存器,即数据从哪搬运到哪。

CH_BLOCK_TS:需要配置bit0-bit21,寄存器的值等于CHx_CTL.SRC_TR_WIDTH的数据总数,假设src的位宽是16,len为64字节,那么block_ts就等于32。

DMAC_CFG:DMA控制器初始化时,需要使能bit0和bit1

bit 字段名 功能描述
0 DMAC_EN 全局dma功能使能位
1 INT_EN 全局中断使能位
2-63 RSVD_DMAC_CFGREG 保留

**CH_CTL:**通道的控制寄存器主要配置以下几个字段,验证时可以配置不同的值,根据不同的值和传输的数据长度计算得出block_ts的值。

bit 字段名 功能描述
8-10 SRC_TR_WIDTH Source Transfer Width.
11-13 DST_TR_WIDTH Destination Transfer Width
14-17 SRC_MSIZE Source Burst Transaction Length.
18-21 DST_MSIZE Destination Burst Transaction Length.

CH_CFG:配置为单块传输时,bit0-bit3配置为0x00,配置为链表传输时,bit0-bit3配置为0xff,bit32-bit34配置传输类型,bit35-bit36配置为软件握手,即模拟dma搬运数据由软件写寄存器触发。

bit 字段名 功能描述
0-1 SRC_MULTBLK_TYPE 00: Contiguous 01:Reload 10: Shadow Register 11:11: Linked List
2-3 DST_MULTBLK_TYPE 00: Contiguous 01:Reload 10: Shadow Register 11:11: Linked List
32-34 TT_FC Transfer Type and Flow Control.(00是mem,01是m2d,03是d2m,04是d2d)
35 HS_SEL_SRC Source Software or Hardware Handshaking Select.
36 HS_SEL_DST Destination Software or Hardware Handshaking Select

CH_INTSIGNAL_ENA: 该寄存器主要配置bit1,当一次dma传输完成时,生成一个中断信号。

CH_LLP:

​ 当使用链表传输模式时,需要配置该寄存器,写入该寄存器的值为Link List的起始地址,地址的解析如下:

通常会用一个结构体进行表示:

复制代码
struct axi_dma_llp {
	u64 sar; 
	u64 dar;
	u32 block_ts_lo; 
	u32 block_ts_hi; 
	u64 llp;
	u32 ctl_lo;
	u32 ctl_hi;
	u32 sstat;
	u32 dstat;
	u32 status_lo;
	u32 ststus_hi;
	u32 reserved_lo;
	u32 reserved_hi;
};
3.7.4 编程概要
  • 单块传输

    • 全局配置寄存器配置,使能dma和int项。
    • 配置通道源地址寄存器和目的寄存器。
    • 根据传输的数据长度和src_width计算block_n,并配置CH_BLOCK_TS寄存器。
    • 通道配置寄存器配置,配置传输模式,软件握手,传输方向等。
    • 通道控制寄存器配置,配置Burst Transaction Length和Transfer Width。
    • 使能通道等中断信号。
    • 使能通道的使能信号开始传输。
    • 检测通道的中断状态寄存器,判断传输是否完成。
    • 清中断,关闭通道使能位,并关闭全局寄存器的dma,int使能位。
    • 数据对比判断是否传输成功。
  • 链表传输

    • 链表传输模式配置过程和单块传输模式类似,需要在配置传输模式时,配置为链表传输,以下是示例:

      复制代码
      void AXI_DMA_TRAN_INIT_LLI(struct axi_dma_info axi, TEQ_UINT32 src_addr, TEQ_UINT32 dst_addr, TEQ_UINT32 length)
      {
      	unsigned long axi_data;
      
      	AXI_DMA_INIT();
      	axi_data = CHx_CONFIG(axi, TYPE_LLI); //lli模式下控制寄存器的配置
      
      	struct axi_dma_lli* head = (void *)LLI_ADDR;
      	struct axi_dma_lli* tmp = head;
      	TEQ_UINT32 num = 1;
      
      	//这一步过后num等于2,链表里有2个元素
      	while (tmp->llp != (long)NULL) {
      		tmp = (struct axi_dma_lli*)(TEQ_INT32)tmp->llp;
      		num++;
      	}
      	tmp = head; //到这里tmp又指向head,即LLI_ADDR
      
      	TEQ_UINT32 cnt;
      	TEQ_UINT32 increment = length / num; //两个元素,一个搬一半?
      	TEQ_UINT32 block_ts = cal_block_ts(axi.src_width, increment); //这个值要写到寄存器里
      
      	for (cnt = 0; cnt < num; cnt++) {
      		tmp->sar = src_addr + increment * cnt;
      		tmp->dar = dst_addr + increment * cnt;
      		tmp->block_ts_lo = block_ts;
      		tmp->ctl_lo = axi_data;
      		if (tmp->llp == (long)NULL)
      			tmp->ctl_hi = LAST_ITEM | VALID;//last & valid
      		else
      			tmp->ctl_hi = NOT_LAST_ITEM | VALID;
      		tmp = (struct axi_dma_lli*)(TEQ_INT32)tmp->llp;
      	}
      
      	//Configure CHx_LLP(x0128) Starting Address Memory of LLI block
      	write_mreg32(CHx_LLP(axi.channel), LLI_ADDR);
      }

​ 参考:

​ 1:DW_axi_dmac_databook.pdf

​ 2:linux/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c

相关推荐
神奇霸王龙1 小时前
Agent 准入门控屠夫:5 旗舰 4 维度评估
linux·运维·数据库·ai·ai作画·agent·ai编程
小绫网络安全4 小时前
Kali Linux渗透测试入门教程:从零搭建到实战攻防
linux·运维·服务器
西安景驰电子4 小时前
《PTP精确时间协议系列》第一篇:从原理到应用,全面解读IEEE 1588
linux·运维·服务器·开发语言·网络·windows·php
猫吃了源码4 小时前
k9s简介和安装
linux·docker·kubernetes
小马同学-6 小时前
高可用-Keepalived全解析
linux·运维
Forever Nore6 小时前
LeetCode 13 罗马数字转整数 - 按规则处理
linux·服务器·leetcode
我不会插花弄玉6 小时前
2.Linux基础指令下【由浅入深-Linux】
linux·服务器
雯宝8 小时前
3. 驱动框架(块设备)
linux
静止了 所有的花开8 小时前
Ubuntu 26.04 静态 IP 配置不生效解决方法
linux·ubuntu·静态ip