-
DMA 系统总体框架
1. 分析linux audio dma的框架之前, 首先我们需要从物理层面来看linux dma通用的框架。
DMA controller: 用来描述系统中总的DMA硬件的基本信息, 软件层面对应dma controller driver
DMA device:隶属于DMA controller, 表示挂在DMA controller下物理硬件, 一般和slave device通过DMA 物理总线相连。
DMA channel:隶属于DMA devcie, 每个dma slave 外设需要向对应的 DMA device申请一个或多个channel,来进行数据传递。
2. DMA软件框架
去掉大刮 部分就是通用的DMA 软件框架。 audio部分已经有前辈为我们开发了一套衔接DMA engine和 DMA driver的框架(见大刮 ),我们直接乘凉就好了!
-
DMA controller driver流程
1. 定义 struct dma_device, 我这里为方便说明,对内核当中的struct dma_device进行了裁剪,如下所示:
2. 填充 struct dma_device关键的函数
device_alloc_chan_resources // slave driver会通过这个函数来申请channel
device_free_chan_resources // 释放chanel
device_prep_dma_cyclic // 音频使用这个来submit dma buffer
device_config // 配置 src addr/dest addr, src_addr_width, dst_addr_width 等等信息
device_terminate_all // 结束数据传输
device_issue_pending // 等待dma硬件使能
3. 分配 dma device下面的通道个数, 申请struct dma_chan 的资源,注册中断处理程序等等
4. 注册dma_device到 dma engine当中去, 使用函数dmaenginem_async_device_register
- a .为dma_device申请dev_id, 注意每个dma device使用唯一的id, 系统id从0开始自动增加。
- b. 遍历挂在dma_device上的所有channel, 这里的channel属于dma_device的设备, 其命名规则为: dma%dchan%d; 第一个%d表示dma_device申请的dev_id, 第二个%d表示channel的id,channel id 默认也是从0开始自动增加。 假如我们是系统中第一个注册的dma_device,拥有2个channel, 那么此dma devcie下的channel名字应为: dma0chan0 dma0chan1
- c.把dma_device添加到全局链表dma_device_list
5 . of_dma_controller_register 将你的dma_device 节点, 增加到of_dma_list全局链表, 便于dma slave devcie来寻找
-
Audio DMA slave driver 基本流程
audio slave driver的编写我们需要做的事情很少, 因为已经audio domain的maintainer为我们写好了框架, 我们只需要定义一些基本的配置,然后使用Soc-generic-dmaengine-pcm.c 里面的注册函数,就可以让你的dma driver和系统的DMA engine衔接起来。
1. 定义 struct snd_dmaengine_pcm_config
2. 需要把你的slave driver在dts里面指定使用的dma device节点, dmas, dma-names 必须给出来!
audio_slave_driver {
compatible = “xxx, audio_dma_slave0”;
dmas = <&>&> &dmadevice 1 >;
dma-names = “tx”, “rx”;
};
3. 使用snd_dmaengine_pcm_register注册到dma engine当中去。
文章知识点与官方知识档案匹配,可进一步学习相关知识CS入门技能树Linux入门初识Linux25289 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!