ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RK806S PMIC调试实战:从I2C寄存器到DVFS与功耗验证

RK806S PMIC调试实战:从I2C寄存器到DVFS与功耗验证 上个月在调一个RK3588平台的时候系统反复出现启动到一半就掉电重启的怪问题。原理图看了三遍DTS改了无数版最后定位到RK806S这颗PMIC上某路BUCK的默认寄存器值被bootloader改写导致CPU大核电压在负载上来之后撑不住。类似这种问题如果你对RK806S不熟很容易在硬件和软件之间来回甩锅绕上一整天。这篇就把我这段时间调试RK806S PMIC电源管理芯片的完整过程、工具链和踩坑记录整理出来给正在跟PMIC较劲的同学一个可以直接参考的路径。先说清楚RK806S是一颗多路DC-DCLDO的电源管理芯片常见于RK3588、RK3568等平台的参考设计里。它通过I2C接口与主控通信负责给CPU、GPU、DDR、NPU等核心供电并且支持动态调压也就是DVFS能生效的关键底层硬件。芯片本身不复杂但调试它涉及硬件上电验证、设备树配置、内核驱动加载、系统级功耗验证好几个层面任何一个环节出问题都会表现为“系统不稳定”这种很隐蔽的故障。这篇文章适合三类人看正在做RK平台硬件BringUp的嵌入式工程师、需要排查系统异常掉电或重启问题的驱动开发人员以及想搞懂PMIC整体工作原理的入门学习者。我会按实际调试顺序来讲从硬件准备到I2C寄存器操作再到DVFS与功耗验证最后附上排查速查表。1. RK806S这颗PMIC到底管了哪些事1.1 从一次“起不来机”的故障说起先把场景还原一下。我手上是一块RK3588的核心板加底板的组合板子回来后第一次上电系统起来到内核启动阶段就会黑掉从串口日志看没有任何panic信息就是突然断电一样的表现。用万用表量各路电压待机状态下全部正常但只要一跑起负载就掉电。这种情况大多数人和我一样第一时间会怀疑是电源输入功率不够但换了更大功率的适配器后问题依旧。后来把示波器挂到各路BUCK输出上才发现CPU大核那一路在启动瞬间电压掉到1.0V以下远低于目标电压。顺着这个线索往回查才知道是bootloader阶段对RK806S的某路输出做了DVP预配置但内核起来后没有按预期覆盖回来两边配置冲突导致电压偏低。这里就引出一个很重要的事实RK806S的工作状态不是纯硬件决定的它从上电那一刻起就处于软件控制之下所以调试它必须同时懂硬件测量和寄存器配置。1.2 PMIC调试到底是什么层面的工作PMIC调试不像普通LDO那样焊上去就有输出它是一个典型的软硬结合问题。从硬件层面说你要确认输入电压、使能引脚、I2C上拉、输出电容、电感选型都没有问题从软件层面说你要确认设备树节点匹配、驱动加载成功、寄存器配置符合预期、DVFS联动正常。这两个层面只要有一个不对系统就会以各种奇怪的方式表现出来。举个例子如果PMIC的I2C总线通信失败系统不一定完全起不来因为PMIC内部有OTP默认配置各路输出会按默认值工作。但默认值通常不是平台最合适的电压于是你会看到系统能开机但高负载时死机、休眠后唤不醒、功耗异常偏高等随机问题。RK806S调试最麻烦的地方就在这里出问题时不会直接报PMIC错误而是表现为各种系统级疑难杂症。2. 调试前的硬件准备原理图、焊接与首轮上电2.1 引脚和I2C地址先对着原理图逐一确认别急着写代码先把原理图相关部分看明白。RK806S的输入电压范围一般在2.7V到5.5V之间实际板子上常见的是5V或者直接从电池供电这直接影响BUCK的降压比例和工作效率。另一个关键点是各路输出的目标电压和最大电流比如CPU大核那路BUCK可能要支持到3A以上选电感的时候饱和电流必须留有足够余量。I2C地址这块我要单独强调一下因为我自己就在这里栽过跟头。RK806S的默认7位I2C地址常用的是0x20但不同封装版本或通过地址引脚配置的不同实际地址可能不同我甚至见过0x0D的版本。而且注意数据手册里很多时候写的是8位地址0x40换算成i2cdetect显示的7位地址就变成了0x20。如果你拿8位地址去扫描总线那永远都扫不到设备白白排查半天硬件。还有RESET引脚、PWRON引脚、INT中断引脚都要确认接到了主控的哪个GPIO上。PWRON如果没拉对会出现按开机键没反应的问题INT中断脚如果没接或者没配设备树驱动可能感知不到PMIC的异常状态比如过温、过压报警。这些引脚状态用万用表量一下高电平是否正常能排除掉一大半硬件问题。2.2 焊接检查与首次上电的基本测量RK806S通常是QFN封装手工焊接或者样板贴片都容易出现连锡、虚焊的问题。很多人一上来就插电测试结果芯片发烫或者某路无输出然后怀疑芯片坏了。实际上QFN底部的散热焊盘如果没焊好芯片可能工作异常但外观上完全看不出来。建议的检查流程是先目检引脚有没有连锡再用万用表二极管档量相邻引脚是否存在短路特别是电源输入引脚对地是否短路。然后不急着上电先量各路输出电容两端的对地阻抗如果某一路接近0欧姆很可能是输出电容焊短路或者后端负载有问题这时候上电就会触发PMIC的过流保护。首次上电时我习惯用限流电源先把电流限制在500mA左右确认没有异常后逐步提高限制。如果上电瞬间电流飙升立刻断电检查。这一步很关键限流电源可能会因为PMIC上电瞬间的大电容充电电流而误判但总比直接烧板子好。实测中很多PMIC损坏都是因为输出短路未被发现就强行上电导致的。2.3 用示波器看一眼上电时序PMIC和普通电源一个很大的区别在于它讲究时序。SoC内部的各个电源域有严格的上下电顺序要求比如内核电压要先于IO电压稳定DDR电压要先于CPU电压如果顺序反了轻则系统不稳定重则损坏芯片。RK806S内部有状态机来管理时序但前提是各路输出和使能信号都正常。多通道示波器在这里派上用场。把输入电源、PWRON/EN引脚、关键的几路BUCK输出分别接到不同通道上用上升沿触发然后上电记录时序波形。对照数据手册里的时序图看确认各路输出的启动顺序、间隔时间、爬升斜率是否符合要求。这一步看的是硬件设计的合理性不是寄存器能补回来的。如果时序不对优先检查原理图和电容电感参数而不是去调软件。3. 软件侧配置驱动、设备树与寄存器基础3.1 RK806S驱动在内核里是怎么工作的软件层面RK806S在内核中通常以MFD多功能设备驱动的方式注册。简单理解就是一个I2C设备驱动先通过regmap建立寄存器读写通道然后分别注册出regulator、RTC、电源键等子设备。regulator子系统负责管理各路BUCK/LDO的电压状态cpufreq通过regulator接口来请求调整CPU供电电压。驱动加载成功后你会在/sys/class/regulator/下面看到一串regulator设备每个对应一路输出。这里的设备命名一般跟设备树里的节点名对应比如DCDC_REG1、LDO_REG3这种。如果某一路没有出现说明设备树里对应的regulator节点没有正确注册或者驱动根本没有枚举出这个子设备。RK806S内部寄存器空间不算大常见版本是0x00到0xFF但芯片版本不同寄存器分布差异很大。像SLEW_RATE电压爬升速率、BUCK工作模式PWM/PFM、DVS配置、睡眠模式配置这些寄存器都分散在不同地址块里。关键是要明白芯片出厂时的OTP默认配置只是一个保守的可用配置真正适配平台的是内核驱动在初始化时写入的那套值。3.2 设备树中PMIC节点的标准写法以RK3588平台为例RK806S一般挂在I2C0上设备树里长这样i2c0 { status okay; clock-frequency 400000; pinctrl-names default; pinctrl-0 i2c0_xfer; pmic20 { compatible rockchip,rk806; reg 0x20; interrupt-parent gpio0; interrupts 10 IRQ_TYPE_LEVEL_LOW; pinctrl-names default; pinctrl-0 pmic_pins; vdd_cpu_big: DCDC_REG1 { regulator-name vdd_cpu_big; regulator-min-microvolt 750000; regulator-max-microvolt 1500000; regulator-always-on; regulator-boot-on; }; vdd_cpu_lit: DCDC_REG2 { regulator-name vdd_cpu_lit; regulator-min-microvolt 750000; regulator-max-microvolt 1500000; regulator-always-on; regulator-boot-on; }; }; };写设备树时有几个细节容易被忽略。一是compatible字符串必须和内核驱动里匹配表一致写错一个字符驱动就直接不加载。二是reg属性是7位I2C地址很多人会误写成8位地址0x40这会导致驱动去0x40找设备而失败。三是interrupts必须和实际连接的GPIO对应否则PMIC的异常中断上报不到内核很多电源问题就变成了随机死机。regulator节点里的min/max电压范围也不是随便写的要参考对应SoC的DVFS电压表范围设置过窄会导致调频调压失败范围设置过宽又可能在异常情况下写到危险的电压值。一般参考厂商SDK里的默认配置就行除非有特殊功耗需求否则不要去动这个范围。3.3 怎么确认驱动加载成功设备树配好之后内核起来先看日志dmesg | grep -i rk806正常会看到类似“rk806 0-0020: device found”之类的信息。如果没有任何输出说明设备树和驱动匹配就有问题驱动根本没跑起来。再看I2C总线上能不能扫到设备i2cdetect -y -r 0这里有个需要区分的情况如果看到0x20地址显示为“UU”说明地址被内核驱动占用了这是正常状态如果显示“20”说明总线上有设备但没有任何驱动认领它代表驱动没加载成功如果连“20”都没有那就是硬件链路或者设备树I2C节点本身有问题得回头查硬件了。这三种状态对应三种完全不同的排查方向很多人看到0x20就以为驱动没问题了其实“20”和“UU”差别很大。想确认驱动注册了哪些regulator可以看ls /sys/class/regulator/如果regulator设备数量比预期的少说明某些节点没有注册成功通常是设备树写法问题。4. 动手实操I2C读写寄存器定位问题4.1 调试工具清单与选用思路PMIC调试最核心的手段就是I2C读写寄存器工具方面我常用的有几种各有适用场景。i2c-tools是Linux下最通用的包含i2cdetect、i2cget、i2cset、i2cdump等命令适合在板子上直接操作灵活但需要自己记住寄存器含义。Rockchip平台的BSP里通常还会带一个regdbg小工具专用于寄存器读写命令更简短适合批量操作。另外还有一个非常好用的路径是内核的debugfs regmap接口可以同时看到驱动缓存的寄存器值和硬件实际值这对排查缓存不一致问题特别有效。这几套工具不是互相替代的关系我实际使用时经常来回切换先用i2cdetect确认链路用regdbg或i2cget读怀疑的寄存器最后用regmap debugfs确认驱动侧状态。调试过程中板子上的串口输出也不要关一边改寄存器一边看内核有没有报错这种联动排查效率最高。4.2 用i2cdetect扫描总线判断链路是否通把板子启动到Linux shell之后第一步永远是扫描总线确认PMIC在不在i2cdetect -y -r 0执行结果我前面已经说了这里再补充一个细节如果扫描结果出现一堆乱码地址比如0x30、0x50、0x70等同时出现而且每次扫描都不一样这通常是SDA或SCL被拉死导致的。最常见的原因是I2C上拉电阻虚焊、上拉电阻阻值不对、或者PMIC处于异常状态。遇到这种情况先不要怀疑驱动用示波器量一下SCL和SDA波形看看是否满足I2C协议的电平和时序要求。如果总线干干净净什么都扫不到也先不要急着怪芯片查一下PWRON引脚有没有被拉高、输入电源有没有到位。我遇到过好几次“扫描不到设备”最后都是因为PWRON没拉高导致PMIC整个处于关闭状态。先把电源、使能、上拉这些基础条件排除干净再怀疑芯片本身。4.3 用i2cget/i2cset/i2cdump读写寄存器总线通了之后就可以开始操作寄存器了。先用i2cdump把整个寄存器空间拉出来看看i2cdump -y 0 0x20这一步相当于给PMIC做一次全身体检把所有寄存器的当前值都记录下来。强烈建议在系统刚启动完、还没有任何负载的情况下做一次备份后面修改出错时可以用来恢复现场。需要修改某个寄存器时用i2cset写入i2cset -y 0 0x20 0x00 0x2f这个命令的含义是I2C总线0上设备地址0x20向寄存器0x00写入0x2f。写完之后再用i2cget读回来确认i2cget -y 0 0x20 0x00这里必须说一个安全提醒千万不要在没看数据手册的情况下乱写寄存器。RK806S的BUCK输出电压寄存器你把电压调高0.1V可能看起来没影响但如果调得过高并且后端是CPU内核那真的可能烧芯片。我自己的习惯是凡是涉及修改电压的寄存器操作旁边一定摆着万用表和示波器边写边观察实际输出电压确认没有超限。另外还要注意寄存器写入后是否立即生效。有些寄存器是立即生效的有些需要额外置位一个更新锁存位才生效而且不同版本芯片的寄存器偏移地址差异很大。同一份调试笔记在另一块板子上未必能直接套用必须以芯片丝印对应的数据手册为准。4.4 结合debugfs regmap核对寄存器缓存i2c工具读写的是硬件寄存器但内核驱动的regmap有自己的一套缓存机制。有时候你通过I2C直接改了某个寄存器值驱动不知道之后驱动为了“恢复”自己的状态又把它改回去反过来驱动以为自己写成功了实际I2C通信失败硬件寄存器的值根本没变。这两种情况靠i2cget是无法发现的必须用debugfs来看内核视角的状态cat /sys/kernel/debug/regmap/0-0020/registers这个文件会列出驱动缓存的寄存器值和从硬件读回的实际值。如果同一地址的缓存值和硬件值不一致就说明存在某方未经另一方同意修改了寄存器。我记得当时定位bootloader覆盖寄存器配置的问题就是靠这一招发现的bootloader阶段写的值与内核缓存的值对不上顺着差异找到了被覆盖的寄存器。这个对比思路很通用不局限于PMIC调试。凡是I2C设备出现“软件配了但硬件没生效”或者“量出来电压和配的不一样”的情况都可以用regmap debugfs做一次缓存对比往往能快速定位是通信问题还是逻辑问题。5. 动态调压与整体状态验证5.1 验证DVFS链路是否真的打通RK806S之所以重要很大程度上是因为DVFS需要靠它来实现动态调压。简单说就是CPU频率提高时内核通过cpufreq框架向regulator请求提高电压CPU频率降低时请求降低电压。如果这个链路没打通高频低电压的情况就会出现跑高负载任务时系统直接死机或重启。验证DVFS链路是否正常最直接的方法是人为改变CPU频率观察电压是否跟着变cat /sys/kernel/debug/regulator/regulator_summary | grep vdd_cpu cpupower frequency-set -f 1800000 cat /sys/kernel/debug/regulator/regulator_summary | grep vdd_cpu执行完第一条命令记下当前电压值然后把CPU频率调到1.8GHz再执行一次看电压是否相应提高。如果电压纹丝不动说明regulator没有正确联动cpufreq需要检查设备树中regulator节点是否被cpufreq驱动使用或者cpufreq驱动是否正常注册。这里要特别注意regulator名称和节点的匹配关系。regulator_summary里显示的consumer信息会告诉你是哪个设备在请求电压调整如果consumer为空说明没有驱动在用这路regulator调压自然不会生效。5.2 电源域耦合配置与睡眠唤醒检查在RK3588这类多核平台上CPU大核和小核的供电电压往往还有耦合关系设备树里会有regulator-coupled-with、regulator-coupled-max-spread这样的属性。比如大核电压和小核电压之间要求最大偏差不能超过某个值或者要求电压同步调整。如果这个配置缺失可能出现大核频率拉满、电压升高但小核没有同步升高导致跨核调度时某些核电压不足直接崩溃。睡眠唤醒这块是另一个容易出问题的地方。系统休眠时PMIC会切换到低功耗模式某些输出会被关断或者降电压唤醒时再恢复。如果设备树里没配置正确的睡眠模式行为可能出现休眠后无法唤醒、唤醒后某路电压不对、待机功耗异常偏高等问题。排查睡眠问题时先把系统手动休眠然后用示波器测量各路输出在休眠期间的实际状态再对比数据手册里的sleep设置是否符合预期。也可以记录休眠前后的寄存器差异逐个确认哪些寄存器被内核修改了。这里的坑在于很多PMIC的sleep配置不是在初始化阶段写的而是在休眠流程中由驱动动态写入的所以静态看设备树不够必须看实际运行时的寄存器状态。5.3 纹波、带载与功耗实测寄存器配置正确并不代表硬件品质没问题PMIC最终还是要用实际的输出质量来说话。示波器测量纹波时探头要设成AC耦合带宽限制开到20MHz这样才能滤掉高频噪声看到真实的开关纹波。如果纹波过大超出SoC供电要求高负载时就会出现数据错乱、系统重启等随机问题。带载测试更贴近实际使用场景。找一台电子负载接到关键输出上从空载逐步加大电流观察电压跌落情况。如果电压跌落超出规格优先怀疑电感饱和电流选得不够、输出电容容量不足、反馈采样点布线不合理这几类问题。我还遇到过一种情况空载时电压都正常带上负载后纹波飙升最后发现是输出电容的ESR偏大换了一颗低ESR陶瓷电容后问题消失。功耗优化方面先看整体待机功耗是否异常。RK806S支持PWM和PFM两种工作模式轻负载下PFM模式能明显降低开关损耗。如果发现待机功耗偏高可以检查相关BUCK是否固定在PWM模式下以及休眠时各路输出是否真正进入低功耗状态。这里有一点要提醒PFM模式下的纹波通常比PWM大一些对纹波敏感的负载反而需要强制PWM模式不能一味追求低功耗而牺牲稳定性。6. 常见问题速查表与调试心得6.1 把坑按现象分类一张表快速定位调试过程中遇到的现象五花八门整理成表格方便以后快速定位。现象可能原因排查手段i2cdetect扫描不到PMIC地址电源/使能脚异常、I2C上拉异常、地址配置错误万用表量电源与上拉示波器看波形确认地址位数地址显示为“20”而非“UU”设备树compatible或reg与驱动不匹配确认dts节点与内核驱动匹配表一致读回寄存器全部为0xFF芯片未正常上电或处于复位状态检查PWRON量输入电压确认复位引脚状态输出电压与配置值不符寄存器未更新锁存、驱动缓存覆盖i2cdump比对硬件值regmap debugfs对比缓存高负载时系统掉电重启BUCK输出跌落、电感饱和、时序异常示波器测带载电压检查电感电流能力调频时电压不变cpufreq与regulator耦合未配置regulator_summary看consumer检查DTS耦合属性休眠后无法唤醒sleep配置错误、唤醒源未配置对比休眠前后寄存器量各路输出状态待机功耗偏高BUCK未进入PFM、休眠关断策略不对检查工作模式寄存器逐路确认关断情况某路输出纹波异常大输出电容ESR高、反馈走线差示波器20MHz带宽测纹波检查PCB Layout这张表不能解决所有问题但它至少能帮你把问题从“系统随机故障”收敛到“PMIC某一个具体环节”上后面再深入定位就有方向了。6.2 几条掏心窝子的调试建议第一I2C地址的7位和8位问题是我见过最多人卡住的地方。所有I2C工具里显示的地址都是7位而数据手册和原理图里经常标注8位地址两者相差一倍。换算规则很简单8位地址右移一位就是7位地址。0x40变成0x200x1A变成0x0D。排查不到设备时先算一下是不是这个原因别一头扎进硬件排查。第二改寄存器之前必须备份改完之后必须回读。这两步看似多花几秒钟关键时刻能救命。我曾经为了临时调电压直接改了一个BUCK的配置寄存器没有备份结果系统表现异常后想恢复现场只能对着数据手册一个一个算默认值折腾了很久。从那以后凡是动PMIC寄存器我都是先i2cdump保存再修改再i2cget确认。第三PMIC调试一定要“眼见为实”。寄存器说1.1V不算数万用表和示波器量到1.1V才算数。很多问题看起来是寄存器配置错了实际是某个硬件参数没达标反过来看起来是硬件毛病的实际是软件初始化顺序不对。不要坐在屏幕前猜把测量仪器架上去波形和数据会直接告诉你答案。第四不要把RK806S当成一个简单的电源芯片来看待它是一个和主控深度绑定的多功能设备。寄存器值影响的不只是电压高低还有上电时序、睡眠状态、DVFS联动、功耗表现甚至SoC能否正确识别电源状态。调试它的过程实际上是把整套平台电源方案理清的过程一通百通。以后你再遇到平台掉电、休眠唤不醒、高负载死机这类问题可以先想想是不是PMIC在某个环节默默背了锅。拿着这块芯片的数据手册结合今天说的排查思路大概率能少走不少弯路。
返回列表