You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

i.MX8M Mini fsl_micfil驱动因DMA未就绪启动挂死问题咨询

i.MX8M Mini MICFIL驱动早期启动采集挂死问题修复

问题环境

  • 硬件:基于NXP i.MX8M Mini SoC的定制嵌入式设备
  • 系统:NXP Yocto Hardknott版本构建的Linux发行版,内核采用NXP官方lf-5.10.y分支linux-imx,对应BSP版本为5.10.52-2.1.0
  • 音频外设:板载数字麦克风,使用定制修改的NXP官方fsl_micfil.c驱动,源码路径为sound/soc/fsl/fsl_micfil.c

驱动定制修改点

共对官方驱动做了三处适配调整:

  1. 通道使能逻辑修改(位于fsl_micfil_hw_params函数约1592行)
    原逻辑为按传入的通道数使能对应数量的低位通道:
    ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
                             0xFF, ((1 << channels) - 1));
    
    修改为固定仅使能第6采集通道:
    ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
                             0xFF, 1 << 6);
    
  2. 硬件使能GPIO控制逻辑添加(位于fsl_micfil_probe函数起始位置约2202行)
    探测阶段执行拉低麦克风硬件使能GPIO的操作,若探测时GPIO子系统未完成初始化,直接返回-EPROBE_DEFER延后驱动探测流程。
  3. DMA接收地址匹配修改(位于fsl_micfil_probe函数约2334行)
    原逻辑默认配置DMA接收地址为0通道数据寄存器:
    micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH0;
    
    修改为匹配第6通道的数据寄存器地址:
    micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH6;
    

故障现象

  • 系统启动完成后立刻启动音频采集(可直接通过arecord命令复现)读取麦克风数据时,设备会直接硬挂死,仅能通过断电重启恢复
  • 等待系统启动约60秒,待控制台打印如下SDMA固件加载完成日志后,再启动音频采集,麦克风功能可完全正常工作:
    [   60.386133] imx-sdma 302c0000.dma-controller: firmware found.
    [   60.392010] imx-sdma 302c0000.dma-controller: loaded firmware 4.6
    

根因定位

查阅imx-sdma驱动源码(路径drivers/dma/imx-sdma.c)可确认:

  • SDMA驱动启动时需要加载专属固件,其中firmware found日志在驱动probe流程打印,loaded firmware日志在sdma_resume/sdma_runtime_resume电源管理恢复流程中打印
  • 5.10版本内核的imx-sdma驱动默认启用运行时PM懒初始化机制,系统启动后不会立刻加载固件,直到首次有设备请求SDMA服务时才会触发恢复流程加载固件,实际测试该触发延迟约为60秒
  • 现有fsl_micfil驱动未正确关联SDMA的运行时PM依赖,启动采集时没有主动等待SDMA完成固件加载就绪,直接配置DMA寄存器启动传输,触发SDMA硬件异常导致系统挂死
  • 4.14版本内核的imx-sdma驱动未启用该懒加载机制,驱动probe阶段就会完成固件加载,因此相同定制修改不会触发该故障。

标准修复方案

不需要在fsl_micfil驱动中编写自定义的主动唤醒、轮询SDMA状态的逻辑,直接使用内核通用的运行时PM依赖框架即可解决,具体修改如下:

  1. 建立设备PM依赖:在fsl_micfil_probe函数完成DMA通道配置、调用devm_snd_dmaengine_pcm_register注册PCM设备前,添加如下代码,主动建立MICFIL设备与SDMA控制器的PM依赖,探测阶段就触发一次SDMA的恢复流程提前加载固件:
    struct device *sdma_dev = micfil->dma_params_rx.dev;
    if (sdma_dev) {
        pm_runtime_enable(&pdev->dev);
        /* 触发SDMA上电恢复,完成固件加载 */
        pm_runtime_get_sync(sdma_dev);
        pm_runtime_put_sync(sdma_dev);
        /* 建立父子设备PM依赖,后续runtime PM操作自动联动 */
        pm_runtime_link_init(&pdev->dev, sdma_dev);
    }
    
  2. 采集流程加PM引用保护:在fsl_micfil_trigger函数的SNDRV_PCM_TRIGGER_START分支中,启动MICFIL硬件采集前先调用pm_runtime_get_sync(sdma_dev)持有SDMA的运行时引用,确保SDMA处于工作状态;在SNDRV_PCM_TRIGGER_STOP分支中,停止采集后调用pm_runtime_put_sync(sdma_dev)释放引用,允许SDMA进入低功耗状态。
  3. 注意:不要修改imx-sdma驱动关闭懒加载逻辑,该机制是内核为降低系统待机功耗设计的标准特性,通过PM依赖链路触发设备就绪是框架约定的标准实现,不会引入跨版本兼容性问题。

内容的提问来源于stack exchange,提问作者David C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:27:32