Edit online

数据结构设计

4 Dec 2024
Read time: 3 minute(s)

本节介绍了 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;
    };

struct aic_dma_task

DMA 控制器支持散列 (Scatter Gather) 的描述符参数形式,需要提前将参数分组打包到多个描述符中,一个 Buffer 对应一组散列参数。这些描述符会组成一个链表,然后将这个链表的第一个描述符的物理地址传给 DMA 控制器。描述符组成的链表结构如下图:


dma_task

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;

};