Edit online

数据结构设计

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

    ../../images/dma_task1.png

    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;
    
    };