第15章:Camera电源管理与功耗优化

各位同学,今天我们来聊一个非常实际的话题——功耗优化。

说实话,做Camera驱动这么多年,我见过太多产品因为功耗问题被客户打回来的案例。你想想看,手机拍着拍着发烫、电池掉电飞快,用户第一反应就是骂厂商。而咱们做底层驱动的,恰恰是解决这个问题的关键环节。

15.1 Sensor上电时序优化(AVDD/DVDD/IOVDD)

先从上电时序说起。Sensor的电源通常有三路:

  • AVDD(模拟电源):给像素阵列和模拟电路供电,通常2.8V
  • DVDD(数字核心电源):给数字逻辑供电,通常1.2V或1.8V
  • IOVDD(IO接口电源):给MIPI和I2C接口供电,通常1.8V

这三路电的时序关系,直接决定了Sensor能否正常启动。我早期做项目时踩过一个坑:某款OV的Sensor,规格书上写的是AVDD先上,DVDD后上,IOVDD最后。结果我为了省事,让PMIC同时上电,Sensor死活不出图。查了两天才发现是时序问题。

避坑指南:我曾经因为忽略Sensor datasheet中的上电时序要求,导致项目延期一周。记住:
1. 严格遵循Sensor厂商给出的时序图
2. 使用PMIC的sequence功能,或者用GPIO+RC延时电路
3. 上电间隔通常要求1ms-10ms,具体看规格书

优化思路其实很简单:在不违反时序要求的前提下,尽量缩短上电到稳定的时间。比如,如果Sensor要求AVDD稳定后5ms才能上DVDD,那我们就精确控制在5ms,而不是留10ms的余量。积少成多,每次上电能省下几毫秒,对于频繁开关Camera的场景(比如扫码),效果很明显。

15.2 MIPI时钟门控(Clock Gating)

MIPI接口的功耗大头在哪?答案是时钟。MIPI的D-PHY在传输数据时,时钟通道是一直在翻转的。即使没有数据传,时钟也在跑,白白耗电。

Clock Gating说白了就是:没数据传的时候,把时钟关掉

具体怎么做?看代码:

// 在驱动中控制MIPI时钟门控
static void mipi_clk_gating_enable(struct camera_device *dev, bool enable)
{
    u32 val;
    
    // 读取MIPI PHY控制寄存器
    val = readl(dev->mmio + MIPI_PHY_CTRL);
    
    if (enable) {
        // 使能时钟门控:无数据时自动关闭时钟
        val |= MIPI_CLK_GATING_EN;
        // 设置门控超时时间,通常设为4-8个UI
        val &= ~MIPI_CLK_GATING_TIMEOUT_MASK;
        val |= (6 << MIPI_CLK_GATING_TIMEOUT_SHIFT);
    } else {
        // 关闭时钟门控,时钟持续运行
        val &= ~MIPI_CLK_GATING_EN;
    }
    
    writel(val, dev->mmio + MIPI_PHY_CTRL);
}

这里有个关键点:门控超时时间不能设得太短,否则频繁开关时钟反而增加功耗。我一般设6个UI(Unit Interval),也就是6个MIPI时钟周期。这个值是我在项目中反复试出来的,太短了容易导致MIPI链路不稳定。

经验之谈:Clock Gating在预览场景下效果最明显。因为预览时Sensor持续输出帧,但帧与帧之间的消隐期(blanking)是没有数据的,这段时间时钟完全可以关掉。实测下来,1080p@30fps的预览,开启Clock Gating能省下约15-20mW。

15.3 ISP DVFS(动态电压频率调整)

ISP的功耗和它的工作频率直接相关。频率越高,处理能力越强,但功耗也越大。DVFS的思路就是:根据负载动态调整ISP的频率和电压

举个例子:

  • 预览1080p@30fps时,ISP负载约40%,频率可以降到400MHz
  • 录制4K@60fps时,ISP负载接近100%,频率需要拉到800MHz
  • 拍照单帧时,ISP瞬间负载很高,但持续时间短,可以用turbo模式

我参与的一个项目中,ISP默认跑在最高频率,功耗高达500mW。后来我们实现了DVFS,根据场景动态调频,平均功耗降到了280mW,降幅接近44%。

实现DVFS的关键是负载预测。不能等到ISP已经满载了才升频,那样会丢帧。也不能提前升频,那样浪费电。我常用的方法是:

// 基于历史帧的负载预测算法
static int isp_predict_load(struct isp_device *isp)
{
    u32 hist_load[5];  // 保存最近5帧的负载
    u32 avg_load = 0;
    u32 max_load = 0;
    int i;
    
    // 计算加权平均,最近帧权重更高
    for (i = 0; i < 5; i++) {
        avg_load += hist_load[i] * (i + 1);
        if (hist_load[i] > max_load)
            max_load = hist_load[i];
    }
    avg_load /= 15;  // 权重总和为1+2+3+4+5=15
    
    // 取平均和最大值的较大者,留有余量
    return max(avg_load, max_load) + 10;  // 加10%余量
}

嗯,这里要注意:负载预测不能只看CPU/GPU的占用率,要看ISP硬件单元的实际利用率。很多SoC的ISP内部有性能计数器,可以直接读出每个模块的忙闲比。

15.4 Camera场景识别与功耗策略

不同的使用场景,功耗策略完全不同。我总结了一个表格:

场景 特点 功耗策略 预期省电
预览(取景器) 持续输出,分辨率低 降频、Clock Gating、降低帧率 30-40%
视频录制 持续输出,分辨率高 DVFS动态调频、MIPI降速 15-25%
拍照单帧 突发高负载,持续时间短 Turbo模式、完成后立即休眠 50%+(相比持续高功耗)
扫码/二维码 低分辨率,间歇性使用 最低分辨率、最低帧率、快速休眠 60-70%
人脸解锁 短时高频触发 预唤醒、快速启动、低分辨率 40-50%

场景识别怎么做?我一般通过以下几个维度来判断:

  1. 应用层Hint:应用调用Camera API时,会传入使用场景(如SCENE_MODE)
  2. 帧率统计:连续多帧的帧率变化,可以判断是预览还是录制
  3. 分辨率变化:突然切换到低分辨率,大概率是扫码或人脸识别
  4. Sensor输出模式:是否开启了HDR、高帧率等特殊模式
核心思路:不要一刀切地给Camera定死一个功耗策略。要根据场景动态切换,该省的时候省,该冲的时候冲。我见过有些方案为了省电,拍照时也降频,结果快门延迟大到用户骂娘——这就本末倒置了。

15.5 实战:将Camera预览功耗降低30%

好了,理论讲完了,咱们来点实际的。下面是我在一个项目中实际用过的优化方案,目标是把1080p@30fps预览的功耗降低30%。

第一步:测量基线功耗

先不优化,跑一遍预览,用功率计测出整机功耗。假设基线是800mW(包含AP、ISP、Sensor、MIPI等全部)。

第二步:逐项优化

  1. Sensor上电时序优化:将AVDD/DVDD/IOVDD的上电间隔从10ms缩短到3ms,节省约7ms的无效等待。这部分对功耗影响不大,但能加快启动速度。
  2. MIPI Clock Gating:在驱动中使能时钟门控,消隐期自动关时钟。实测省电约20mW。
  3. ISP DVFS:预览场景下,ISP频率从800MHz降到400MHz,电压从1.0V降到0.85V。省电约120mW。
  4. Sensor输出模式:将Sensor从10bit输出改为8bit输出(预览不需要10bit精度),MIPI速率从1.2Gbps/lane降到800Mbps/lane。省电约50mW。
  5. 帧率控制:如果预览不需要30fps,可以降到24fps或15fps。省电约30mW。

第三步:验证效果

优化后再次测量,整机功耗降到了540mW。算一下:(800-540)/800 = 32.5%。嗯,超额完成了30%的目标。

注意:降帧率和降分辨率会影响用户体验。一定要和应用层沟通好,确认用户能接受。我有个项目就是因为把预览帧率降到15fps,被产品经理追着骂了一周...

最后,给大家画一张本章的知识体系图,方便理解各个优化点之间的关系:

Camera电源管理与功耗优化知识体系 功耗优化目标 上电时序优化 AVDD/DVDD/IOVDD MIPI时钟门控 消隐期自动关时钟 ISP DVFS 动态电压频率调整 场景识别与策略 预览/录制/拍照/扫码 严格遵循时序图 精确控制间隔 门控超时时间设置 负载预测算法 应用层Hint 帧率/分辨率统计 实战目标:预览功耗降低30%

这张图把咱们今天讲的内容串起来了。从四个方向入手,最终汇聚到实战目标——预览功耗降低30%。

说实话,功耗优化是个细活,没有银弹。每个项目的情况都不一样,Sensor型号不同、SoC不同、使用场景不同,优化的侧重点也不同。但核心思路是不变的:能省则省,该用则用

好了,这一章的内容就到这里。下一章我们会讲Camera的调试与性能分析工具,到时候我会带大家看看怎么用trace、perf等工具定位功耗问题。


公众号:蓝海资料掘金营,微信deep3321