s3c6410 linux DMA驱动分析

转自: http://blog.chinaunix.net/uid-21074389-id-3195991.html
  s3c6410 linux DMA驱动分析  2012-05-04 10:13:51

分类: LINUX

最近准备开发DMA驱动,先对s3c6410驱动做了一些分析。

代码路径:arch\arm\plat-s3c64xx\Dma.c

1.              static void dbg_showchan(struct s3c2410_dma_chan *chan)

通过读寄存器查看channel信息

2. static void show_lli(struct pl080s_lli *lli)

查看 dma 通道数据buffer的列表链

3.dbg_showbuffs(struct s3c2410_dma_chan *chan)

打印dma通道号,该通道下一个传输的数据buffer,当前传输数据buffer,最后要传输的数据buffer,dma地址,传输数据的源地址,目的地址,使用的dma控制器等信息;

4.s3c64xx_dma_map_channel(unsigned int channel)

channel: DMA 通道源(范围0-31)

将channel映射到数组s3c2410_dma_chan[]中,该数据每个成员是一个结构体s3c2410_dma_chan,表示一个dma通道

5.s3c2410_dma_config(unsigned int channel, int xferunit)

channel: DMA 通道源(范围0-31)

配置相应dma通道的width(可以为0,1,2字节)

6.s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,

                struct pl080s_lli *lli,

                dma_addr_t data, int size)

根据dma传输源(存储器,还是外设)配置dma源地址,目的地址,控制变量(control0,control1,该变量控制传输size),并将其保存在结构体pl080s_lli中

注:该函数配置的是设备到存储器,存储器到设备传输

7. void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,

                struct pl080s_lli *lli)

将结构体pl080s_lli里的要进行dma信息写到相应寄存器中

8.int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)

清除dmac中断,使能dma

9.int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)

关闭dma传输通道

10.void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,

                    struct s3c64xx_dma_buff *buf,

                    enum s3c2410_dma_buffresult result)

11 void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)

释放dma数据buffer

12.s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)

停止dma,清除通道的所有buffer

13. s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)

根据操作需要(START,STOP,FLUSH)控制dma通道

14. s3c2410_dma_enqueue(unsigned int channel, void *id,

            dma_addr_t data, int size)

将dma_buffer插入队列中

(1)调用函数s3c_dma_lookup_channel找到与通道相关的结构体s3c2410_dma_chan;

(2)为s3c64xx_dma_buff结构体申请内存,保存该结构体;

(3)调用函数dma_pool_alloc为s3c64xx_dma_buff指定的buffer地址处为buffer申请一段连续地址的dma池;

(4)调用函数s3c64xx_dma_fill_lli(chan, lli, data, size)填充chan的成员lli;

(5)如果该s3c64xx_dma_buff还有下一个dma_buffer,则将dma_buffer队列的最后一个成员的下一个buffer指针next指向该buffer,next_lli指向该buffer的成员lli_dma,形成环形队列;

(6)如果没有,则该dma_buffer是独立的,配置s3c2410_dma_chan相关成员curr,next,end;

15.int s3c2410_dma_devconfig(int channel,

            enum s3c2410_dmasrc source,

            unsigned long devaddr)

配置dma相关寄存器ConfigurationExp

(1)调用函数s3c_dma_lookup_channel找到与通道相关的结构体s3c2410_dma_chan;

(2)给s3c2410_dma_chan相关成员peripheral(dma要传输的外设设备号),source,dev_addr;

(3)根据source配置dma相应通道的源地址或目的地址,中断等寄存器;

16.int s3c2410_dma_getposition(unsigned int channel,

                dma_addr_t *src, dma_addr_t *dst)

从PL080_CH_SRC_ADDR和PL080_CH_DST_ADDR寄存器中读出源地址和目的地址,保存在变量src和dst中

17.int s3c2410_dma_request(unsigned int channel,

            struct s3c2410_dma_client *client,

            void *dev)

获取dma通道相应结构体s3c2410_dma_chan,将client(dma name),通道号赋值给s3c2410_dma_chan成员client,peripheral

18.int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)

获取dma通道相应结构体s3c2410_dma_chan,将s3c2410_dma_chan成员client赋值为null,in_use赋值为0,将映射的结构体dma数组相应channel成员赋值为null;

19. static int __init s3c64xx_dma_init(void)

DMA模块初始化

(1)       调用函数dma_pool_create创建dma池,

(2)       初始化两个DMA控制器


http://hi.baidu.com/percy_place/blog/item/68546dec40e67d2d2797916d.html

你可能感兴趣的:(ARM)