数据结构设计
DMA 数据类型及其结构描述如下:
- struct aic_dma_dev:记录 DMA
控制器的配置信息
struct aic_dma_dev { void __iomem *base; int irq; u32 num_pchans; u32 num_vchans; u32 max_request; struct clk *clk; struct reset_control *reset; spinlock_t lock; struct dma_pool *pool; struct aic_pchan *pchans; struct aic_vchan *vchans; const struct aic_dma_inf *dma_inf; struct dma_device slave; };
- struct aic_dma_inf:记录 DMA
控制器的一些特性,如通道数、端口数、Burst 长度、地址宽度,这些特性会因不同 SoC 而不同,所以此数据结构会用在 of_device_id 中的私有数据,配合
compatible
来区分不同的 SoC。
struct aic_dma_inf { u8 nr_chans; /* count of dma physical channels */ u8 nr_ports; /* count of dma drq prots */ u8 nr_vchans; /* total valid transfer types */ u32 burst_length; /* burst length capacity */ u32 addr_widths; /* address width support capacity */ };
- DMA 通道信息
DMA 物理通道和 DMA 虚拟通道是一对多的关系,所以在设计中它们互相都需要在记录好对方的数据引用指针。
- DMA 物理通道信息:记录了一个 DMA
物理通道对应的通道号、寄存器基地址、对应的虚拟通道指针等。
struct aic_pchan { u32 id; /* DMA channel number */ void __iomem *base; /* DMA channel control registers */ struct aic_vchan *vchan; /* virtual channel info */ };
- DMA 虚拟通道信息:记录了一个 DMA
虚拟通道对应的 DRQ 端口号、传输类型、对应的物理通道指针等。
struct aic_vchan { u8 port; /* DRQ port number */ u8 irq_type; /* IRQ types */ bool cyclic; /* flag to mark if cyclic transfer one package */ struct aic_pchan *pchan; /* physical DMA channel */ struct aic_desc *desc; /* current transfer */ /* parameter for dmaengine */ struct virt_dma_chan vc; struct dma_slave_config cfg; enum dma_status status; };
- DMA 物理通道信息:记录了一个 DMA
物理通道对应的通道号、寄存器基地址、对应的虚拟通道指针等。
- DMA 描述符
DMA 控制器支持散列(Scatter Gather)的描述符参数形式,需要提前将参数分组(一个 Buffer 对应一组散列参数)打包到多个描述符中,这些描述符会组成一个链表,然后将这个链表的第一个描述符的物理地址传给 DMA 控制器。描述符组成的链表结构如下图所示:
图 1. DMA 描述符链表的结构示意图 提示:End Flag
是 DMA 控制器硬件预先定义好的一个数值:0xfffff800。DMA 描述符的数据结构定义如下:struct aic_dma_task { u32 cfg; /* DMA transfer configuration */ u32 src; /* source address of one transfer package */ u32 dst; /* destination address of one transfer package */ u32 len; /* data length of one transfer package */ u32 delay; /* time delay for period transfer */ u32 p_next; /* next task node for DMA controller */ u32 mode; /* the negotiation mode */ /* * virtual list for driver maintain package list, * not used by DMA controller */ struct aic_dma_task *v_next; };