1.7. PL08X _lli _chan_lli pl08x_driver_data

/*
 * 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 _lli1{
	dma_addr_t src;
	dma_addr_t dst;
	dma_addr_t next;2
	union _cctl cctl;
};
struct _chan_lli3 {
	dma_addr_t bus_list;
	void	*va_list;
};
struct pl08x_driver_data {
	void __iomem	*base;4
	struct amba_device5 *dmac;
	struct pl08x_platform_data *pd;
	/*
	 * Single dma_pool for the LLIs
	 */
	struct dma_pool *pool;6
	int pool_ctr;7
	struct work_struct dwork;8
	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_chan9 *chanwrap[MAX_DMA_CHANNELS];
	/* List of descriptors which can be freed */
	spinlock_t 		lock;
};
/*
 * PL08X private data structures  ==== END
 */
        

1

这个就是DMA里面最核心的概念,LLI,Link List Item,包括了

  1. 源地址
  2. 目标地址
  3. 下一个LLI的地址

    如果其为0/NULL/空,说明当前只需要传输一个信息,如果非空,传完当前的LLI,就会跳转到对应的地址,执行下一个LLI的传输

  4. 对应的控制信息cctrl - channel control

这四个值,会分别写入到对应的四个寄存器。

这样配置好了之后,再去启用DMA,DMA就会按照你的要求,把数据从源地址传送到目的地址。

2

next域的值,即下一个LLI的地址,其中的bit0,是bus bit,即指示当前用哪个bus。

现将datasheet中相关解释截图如下:

图 1.1. LLI寄存器的含义

LLI寄存器的含义


对应的bit[0],LM位,就表示了,当前使用哪个AHB master,而真正的LLI的地址,是存放在bit[2-31]

3

LLI结构体,存放LLI的dma地址(供DMA控制器访问的) bus_list,和虚拟地址(普通的地址,CPU可以访问的地址),va_list

4

记录对dma控制器硬件基地址ioremap之后的,驱动中可以直接访问的那个基地址

加上对应寄存器偏移量,就可以访问寄存器了

5

此pl08x的DMA控制也是一个amba设备

6

dma内存池,用于存放之后,每次驱动的LLI

7

记录已使用内存池的数量,当达到足够大一个值的时候,做一次清理动作

8

一个工作队列,后面可以看到,挂了一个函数,作用是清理释放dma pool

9

将DMA 通道相关的信息,打包在这个变量里