/* * An LLI struct - see pl08x TRM * Note that next uses bit[0] as a bus bit, * start & end do not - their bus bit info * is in cctl */ struct _lli{ dma_addr_t src; dma_addr_t dst; dma_addr_t next; union _cctl cctl; }; struct _chan_lli { dma_addr_t bus_list; void *va_list; }; struct pl08x_driver_data { void __iomem *base; struct amba_device *dmac; struct pl08x_platform_data *pd; /* * Single dma_pool for the LLIs */ struct dma_pool *pool; int pool_ctr; struct work_struct dwork; wait_queue_head_t *waitq; int max_num_llis; /* * LLI details for each DMA channel */ struct _chan_lli *chanllis; /* Wrappers for the struct dma_chan */ struct pl08x_dma_chan *chanwrap[MAX_DMA_CHANNELS]; /* List of descriptors which can be freed */ spinlock_t lock; }; /* * PL08X private data structures ==== END */
这个就是DMA里面最核心的概念,LLI,Link List Item,包括了
这四个值,会分别写入到对应的四个寄存器。 这样配置好了之后,再去启用DMA,DMA就会按照你的要求,把数据从源地址传送到目的地址。 | |
next域的值,即下一个LLI的地址,其中的bit0,是bus bit,即指示当前用哪个bus。 现将datasheet中相关解释截图如下: 对应的bit[0],LM位,就表示了,当前使用哪个AHB master,而真正的LLI的地址,是存放在bit[2-31] | |
LLI结构体,存放LLI的dma地址(供DMA控制器访问的) bus_list,和虚拟地址(普通的地址,CPU可以访问的地址),va_list | |
记录对dma控制器硬件基地址ioremap之后的,驱动中可以直接访问的那个基地址 加上对应寄存器偏移量,就可以访问寄存器了 | |
此pl08x的DMA控制也是一个amba设备 | |
dma内存池,用于存放之后,每次驱动的LLI | |
记录已使用内存池的数量,当达到足够大一个值的时候,做一次清理动作 | |
一个工作队列,后面可以看到,挂了一个函数,作用是清理释放dma pool | |
将DMA 通道相关的信息,打包在这个变量里 |