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

相关推荐
Android系统攻城狮9 分钟前
Linux Gstreamer深度解析之gst_audio_ring_buffer_prepare_read调用流程与实战(七十四)
linux·运维·服务器·gstreamer音视频·音视频进阶
我科绝伦(Huanhuan Zhou)40 分钟前
Linux 通用压力测试脚本合集:磁盘 + 网络
linux·网络·压力测试
Soneswy3 小时前
Linux系统篇--重定向与文件操作命令
linux
有毒的教程3 小时前
Linux底层存储路由配
linux·运维·网络
Linux系统运维工程师_郭主任4 小时前
运维人还在被拒offer?现在能考的,只有 RHCE 10.0。
linux
自养Agent4 小时前
MCP Server Boundary Audit Report
linux·服务器·人工智能·windows·大模型·llm
Coisinier5 小时前
docker命令管理镜像及容器
linux·运维·nginx·docker·容器·操作系统
A心有千千结6 小时前
通过 SSH 反向代理让服务器借用本机网络访问 GitHub 的最佳实践
linux·服务器·网络·git·ssh·github
书生执笔画浮沉6 小时前
Linux 内核模块为什么不能自己解决兼容性问题?
linux·c·kernel·update·灵感
15Moonlight6 小时前
Linux网络(03):Socket 编程 TCP
linux·网络·tcp/ip