案例定位
这不是一篇“把源码从头读到尾”的笔记,而是一篇用 i.MX6UL fsl-sai 这个真实音频驱动,来拆解 真实 DMA 路径、层次分工、FIFO 节拍与周期流语义 的案例页。
一、先说结论:这个案例为什么值钱
fsl-sai 值钱,不是因为它“能播音频”,而是因为它能让你同时看清:
- CPU DAI 驱动和 Platform DMA 层不是一回事
- 音频这种持续流设备为什么天然适合 cyclic / period 模型
- 真实 DMA 和“软件模拟 DMA”之间到底差了什么
一句话:
这是一个非常适合把“DMA 不是 API,而是工程系统”讲透的案例。
二、先把角色分工钉死
fsl-sai 是什么
fsl-sai 是 Freescale / NXP i.MX6UL 平台上的 SAI(Synchronous Audio Interface)驱动,位于
sound/soc/fsl/fsl_sai.c。它的角色更接近:
- CPU DAI 驱动
- SAI 寄存器配置者
- DMA 参数提供者
它不是那种“自己包办整条数据搬运链”的 Platform DMA 驱动。
Platform DMA 层是谁
真正负责 PCM buffer 与 DMA 数据通路的,通常是:
- i.MX 平台私有 DMA 路径
- 或 DMAEngine / PCM 框架层
这点特别重要,因为很多人看音频驱动时最容易混淆两层:
- 看到了 SAI 驱动,就误以为 DMA 生命周期都在这一个文件里
- 其实这里只负责把 DMA 所需的关键参数交给下一层生态
三、它和“fake DMA / hrtimer 模拟 DMA”本质区别在哪
模拟 DMA 更像什么
- 用 hrtimer 或软件回调推进 hw_ptr
- 由 CPU / 定时器节拍模拟 period 到来
- 适合学习、QEMU、验证上层逻辑
真实 DMA 更像什么
- FIFO watermark 触发 DMA 请求
- DMA 控制器真实搬运数据
- completion/period 节奏跟硬件数据流强绑定
- CPU 主要做配置、完成和状态处理
这两者的差异不是“一个更真实一点”,而是整个系统节奏来源不同:
维度 | 软件模拟 DMA | 真实 DMA |
数据搬运 | CPU / 定时器模拟推进 | DMA 控制器硬件搬运 |
节奏来源 | 软件 tick | FIFO / 硬件请求 |
CPU 占用 | 高 | 低 |
适用场景 | 学习 / 仿真 / 早期验证 | 生产环境 |
四、看这个驱动时,优先看哪几块
1. probe 阶段怎么接上 DMA 世界
重点不是所有细节,而是:
- 它在 probe 里怎么注册 DMA 相关能力
- 是接平台私有 DMA,还是 DMAEngine
- 它把哪些参数准备给下层
2. hw_params 阶段怎么组织 DMA 参数
这里最值得盯的是:
- DMA 数据寄存器地址怎么计算
- burst / maxburst 怎么设
- TX / RX 路径参数如何分开
因为这里反映的不是“某个字段怎么写”,而是:
这条音频数据流,要以什么颗粒度、什么节奏被 DMA 消费。
3. FIFO watermark 怎么决定节拍
这是这个案例最值得学的地方之一。
watermark 决定的是:
- FIFO 剩余多少空间时该发 TX DMA 请求
- FIFO 累积多少数据时该发 RX DMA 请求
- period/completion 节奏如何跟硬件水位耦合
你如果只把它看成“寄存器值”,就等于把整个实时数据节奏看没了。
五、真正应该从这类驱动里学到什么
1. 层次分工
CPU DAI 驱动不一定自己搬数据,但它决定了:
- DMA 应该往哪搬
- 按什么节奏搬
- 在什么格式和时钟条件下搬
2. 音频驱动里的 DMA,不只是吞吐问题
它还关乎:
- period 节拍稳定性
- underrun / overrun
- FIFO 与 DMA 请求的匹配关系
所以音频 DMA 的核心不是“带宽够不够”,而是“节奏是否稳”。
3. 真正的周期流语义
这类驱动最适合理解 cyclic / period 模型,因为它天然就是:
- buffer 不只跑一次
- completion 不是一次性结束,而是周期性推进
- 上层消费必须跟硬件节拍长期对齐
六、把这个案例放回本专题主线
这个案例对应本专题里最关键的几章:
也就是说,它不是一篇孤立旧稿,而是一个很适合被吸纳进主线的真实周期流案例。
七、你读这类源码时应该追的问题
- DMA 参数在哪里被组织出来?
- SAI FIFO 寄存器地址如何交给 DMA 层?
- burst / maxburst 为什么这么配?
- watermark 如何影响 period 节拍?
- stop / suspend / resume 时,数据流如何停住又恢复?
- 哪些职责属于 CPU DAI,哪些属于 Platform DMA 或 DMAEngine?
八、这个案例最容易被误读的点
误读 1:以为所有 DMA 逻辑都在 fsl-sai.c 里
错。这里只是整条通路中的一层。
误读 2:只看寄存器配置,不看数据流节拍
错。音频类驱动里,节拍比静态配置更关键。
误读 3:把真实 DMA 理解成“定时器模拟版的增强版”
错。两者的节奏来源和系统边界完全不同。
九、这页的真正收获
如果你把这个案例读明白,应该得到的不是“记住几个函数名”,而是三条判断:
- 真实 DMA 系统是分层协作的,不是一份源码包办一切。
- 周期流设备里,FIFO watermark、period、completion 节奏比单纯吞吐更关键。
- 真实 DMA 和模拟 DMA 的差距,不在表面写法,而在于谁真正承担了数据搬运责任与时序节拍。






