显示系统稳定性:Kernel模块加载顺序和i2c漏电导致的花屏问题
背景
研发一个机型的过程中出了点意料之外的问题。在关机状态下,进行电源适配器(DC)连续插拔测试时,在特定操作下会有概率性出现花屏现象,而且花屏现象不一致不统一。
现象如下图所示。图中无关紧要的位置打了马赛克,bug的问题现象是屏幕显示的内容花了。虽然都是关机充电界面花屏,但是花的内容款式有几种不同的。
Failed Rate:每7-8次出现1次;测试未发现与特定屏型号、特定屏单体、特定主板单体有关。与特定操作和场景强相关。
步骤:设备处于关机状态下 → 接入DC电源 →设备因关机充电而自动开机 → 显示开机logo → 显示充电动画 → 如果发现充电动画正常,则立刻拔出DC,然后尽快马上再次插入,再次循环;如果花屏,则问题复现。
平台:CPU → mipi → IT6151 → eDP → TCON→ SOURCE IC → LCD
异常分析
软件出图分析:动画无异常、软件出图无特殊逻辑
分析显示问题的时候,第一步可以先看看我们从CPU出来的画面本身是否正常的。一般花屏可以通过截图和投屏、录屏来确认图源的正常情况,但是我们是在关机充电画面,Android尚未启动,故无法进行这类操作。
从现象上看,出问题的时候开机logo不花,充电动画花了。一般来说,花屏和屏的上下电时序、波形质量有关系,通常喜欢在亮屏就花。但是碰到的问题是亮屏的时候并不花,而是一段时间后才花,看来不能直接去找时序的锅。
因此结合关机充电这个场景,不排除是充电动画解析和显示的异常,包括充电动画对屏和背光的操作有时序异常。因此首先在问题出现后借助串口日志分析动画和屏操作日志。
此外,该机型有引入MTK AAL功能、上层PQ功能,因此SoC端的CABC功能或PQ模式可能有影响,也进行分析。
AAL功能和PQ功能是芯片厂商提供的调节画质的接口。
Action | 小结 | 结论 |
---|---|---|
动画日志分析 | 正常 | 关机充电动画部分没有异常,软件出图没有明显异常,电信号操作没有差异 |
开关、背光日志分析 | 正常 | |
正常、异常日志对比; 新、老版本日志对比; 与drvier only版本对比; | 没有差异 | |
PQ影响 | 确认PQ服务在该阶段不会生效 | |
AAL影响 | AAL没有源码,但根据文档确认在关机充电阶段不会生效。 此外,软件关闭ALL编译开关后,问题仍能复现 |
做实验缩小范围:发现问题不在屏端、TCON端
前面的实验表面CPU出来的画面应该没有问题,而且花屏的时候每次花的内容基本不相同,和正常显示的内容看着也不相干,因此向更底层的方向去分析。
Action | 小结 | 结论 |
---|---|---|
同主板同软件搭配A型屏 | 复现 | 花屏问题和屏、TCON无关 |
同主板同软件搭配B型屏 | 复现 | |
硬件飞线,将TCON Core 1V8接开关,在问题复现后,手动开关该开关,等价重启TCON | 复现后拨动、拨回开关,现象还在 | |
屏单体问题分析 | 测试资源不够、时间紧张,未测 | 结合上面的结论(和屏无关),因此和屏单体也无关 |
6151信号稳定性、电源稳定性和软件逻辑分析:无异常(除eDP和MIPI信号无法分析)
6151是mipi to eDP芯片,CPU出来的画面发送给它,它处理后再发送给屏幕
前面步骤分析认为CPU出图、TCON均没有异常,因此围绕6151进行分析。
保障6151稳定运行的两个条件是:
- 软件下的配置正确
- 时序正确且各电信号稳定
梳理6151几个关键监测点,准备挂示波器和逻辑分析仪:
- 6151可以通过MIPI DSI下发指令、切换模式
- 6151可以通过I2C下发指令、切换模式
- 关键电信号包括几个GPIO、LDO、VDD(1V2、1V8、3V3、eDP使能、RST)的时序及波形
此外,在eDP驱动中初始化完成后dump寄存器,在进入充电界面时再次dump,排查意外没发现的SoC对6151的配置、6151寄存器变化、或6151自己跑飞了。
Action | 小结 | 结论 |
---|---|---|
1V2、1V8、3V3使能、eDP使能、RST的时序、波形(从开机到花屏发生) | 未见异常 | 关键电信号的时序和质量正常 |
review软件配置正确 | 未见异常 | 软件配置符合要求,不涉及屏参 |
开机logo后(屏亮起后)6151 I2C监测,有一次意料之外的Write和Read | 没有挂逻辑分析仪,不能直接简单从示波器看到通信内容,不能排除软件这次通信是否让6151发生了变化,致使花屏 | 没有对6151有重新初始化、切换模式、修改参数等操作 i2c通信没有影响花屏,也不影响概率 |
出新软件,移除掉这个I2C通信 (分析驱动,发现6151驱动确实有个i2c读写,但是这个是状态dump,可以直接去掉不影响功能) | 示波器体现,i2c通信已经去除 花屏现象仍然能保持复现 且少量手工验证下,复现概率没有变化 | |
6151寄存器dump (改动量较大,需要在关机动画那里进行dump。接下来问题有更明确的进展,没来得及做这个实验) | / | / |
是否通过MIPI DSI向6151发出指令 | 软件排查没有走过MIPI DSI通道 无仪器分析 | 如果存在该情况,则问题不应该是概率性的 |
坑:回顾问题分析过程,这里有个漏掉的信号(V3P3A)没有分析到(而是只量取了使能)。因为这个信号,我们有惯性思维,会认为它是稳定常开的,因此没有量它的波形。
我们分析到后面才发现是这个信号有异常掉0,它导致了花屏
花屏伴随着L-Sensor 通信异常;发现前级电源有短暂异常掉电;L-Sensor 通信异常导致前级掉电
截止目前我们并没有发现什么太异常的东西,没有线索去指引分析。但是在串口日志中发现一个奇怪的现象,花屏的时候,都伴随着光感传感器I2C通信异常。
1 | [2024-05-16 10:13:58] [ 4.362148] <5>.(5)[1:swapper/0]i2c_dump_info: ----------------------- |
软件逻辑上光感传感器与显示无关,排查发现光感传感器与6151不在同一路I2C,但是会共用前级电源(V3P3A)。因此两者之间可能有关联,先来看看这个i2c通信失败和花屏有没有关联。
电路图如下,LCM电源会使用V3P3A这路电。它和光感传感器是共用的电源。
Action | 小结 | 结论 |
---|---|---|
日志看花屏现象伴有L-Sensor的I2C通信异常 | 花屏和L-Sensor可能不是巧合,有相关性,要证明是否因果关系,需要用示波器确认时间点 | L-Sensor通信失败,相关或因果地,使V3P3A短暂掉到底 V3P3A会给屏供电,供电的异常有导致花屏的重大嫌疑 |
示波器抓取V3P3A波形、I2C波形 (V3P3A电源来自VPA_PMU,给屏、TP、L-Sensor使用) | 1. 花屏发生时,L-Sensor有三次连续i2c通信(Write,无ACK)后,V3P3A短暂掉电 2. 摄像头录像确认,花屏是紧接着随后发生的 3. 异常掉电波形见下图 | |
查阅L-Sensor驱动,确定会通过Regulator关闭前级电源V3P3A | 驱动代码如下展示 | L-Sensor通信失败,会通过regulator关闭V3P3A的输出 |
拔掉光感后进行实验 | 花屏现象从概率性发生,变成必现 | 花屏现象与光感通信异常情况强相关 |
保持光感装好,软件关闭光感驱动 | 花屏现象不再复现 |
波形图如下所示,可以看到电源有短暂的异常掉到0。
由于这一路电源是PMIC输出的,驱动能力和稳定性都较强,而且每次复现的时候波形都是一致的,因此基本认定异常波形应该是来源于软件的异常逻辑。
既然花屏的时候伴随着光感传感器的通信异常问题,那么直接定位到对应驱动代码的位置,如下。
1 | ...... |
这段代码是光感传感器初始化(probe)过程中,碰到i2c通信失败,即没有与传感器正常通信的情况下,走的失败逻辑。其中的关键代码是regulator_disable(rgb_3v3)
,它通过regulator接口关闭了3.3V的电源供电,因此造成了供电电源的异常波形。
由于这一路电源同时给屏供电,因此这一异常的电源波形使屏端的逻辑出现异常,进一步导致了花屏现象的发生。
L-Sensor概率性通信异常根因:SDA/SCL台阶问题
从前面的分析可以确定,我们发现了事故的直接原因。即光感传感器初始化失败,其驱动代码关闭了前级电源,致使屏的电源异常,导致花屏。
问题的“概率性”来源。实际上花屏不是“概率性”的,只要是V3P3A掉电了,必定会花屏。而“概率性”的来源是L-Sensor概率性的通信异常。因此问题转向为分析光感传感器概率性通信异常的原因。
L-Sensor本身比较简单,其电信号总共只有使能、i2c两根线,加起来3个信号。
Action | 小结 | 结论 |
---|---|---|
示波器量取RGB_PWR_EN | 未见异常 | 光感传感器概率性通信异常不是因为它自己的供电有问题 |
i2c影响(驱动能力) | 检查该路i2c已经配置CPU内部上拉,且L-Sensor本身具备内部上拉 | 与i2c干扰无关,与同一路i2c上的重力传感器无关,i2c链路未见异常 |
i2c影响(其他client) | 该路i2c还插着g-sensor,贴在板上无法拿下,软件关闭驱动后复测,可复现花屏 | |
i2c影响(波形) | 示波器体现,波形健康 | |
示波器量取SDA波形 | SDA进入工作状态前,有0.7V台阶,自CPU IO reset后就存在 | i2c开始工作前有异常电平,有较大嫌疑(异常波形放在“异常根因”小结展示) |
示波器量取SCL波形 | SCL进入工作状态前,有0.7V台阶,自CPU IO reset后就存在 | |
临时措施,将台阶压下去 | i2c启用前,将SDA、SCL的电放掉,让台阶下来 | 异常电平压下去后,i2c不再复现异常通信的情况,花屏不再复现 |
到这里,问题不再复现了,我们从找到花屏的直接诱因,并顺藤摸瓜到找到了根本的原因。
异常根因
在最前面先展示一下异常波形,如下图。
其中,紫色、蓝色线分别代表L-Sensor(光感传感器)的i2c的SDA和SCL两根线。图上有相应标注,特别说明的,这个图是导入了解决措施后抓取的。在图的左半部分有标记出来的“异常的台阶”,它就是异常的电平。中部标记的“放电,压下台阶”是导入了措施后。未导入前的异常情况下,这个台阶没有放电过程,一直有不小的台阶存在。
SDA和SCL一高一低,原因是示波器选取的0基准线的位置的差异,实际上它们电平相等
首先来解释一下在解决措施导入前,L-Sensor会概率性通信失败的原因。
我们通过示波器看到,L-Sensor i2c线上有一些抬起来的电平(台阶)。由于这个台阶不算小,而且这一型号的L-Sensor本身器件设计、制造上带来的电气特性,使得台阶(即i2c线路上的电压),顺着i2c线及L-Sensor芯片内部的电路,对其灌入电流。灌入的电流相当于对芯片进行了半残废的供电,可能会导致其处于半工作状态。
但由于不是正常的正确的供电,因此内部逻辑可能紊乱,就像程序引用空指针一样行为是未定义的,会出现概率性的通信异常。
当然,平时i2c正常工作都是拉高的,这个时候为什么不怕灌电流呢?因为在正常情况下,L-Sensor是有正常电源供电的,i2c上的电流灌不进来,或者是L-Sensor已经正常启动了,不再像灌电流那样跑飞了
至于i2c为什么会出现台阶,分析下电路图可以发现,i2c的两根线是从CPU的引脚上出来的,CPU初始化后,引脚处于悬空态,因此有台阶电平出来。
1 | flowchart LR |
开机过程中,L-Sensor的驱动会尝试与L-Sensor进行i2c通信。当通信失败时,驱动代码逻辑将V3P3A下电了,影响了屏的电源稳定性,导致花屏。
1 | flowchart LR |
解决方案
对于L-Sensor而言,其器件特性决定了无法耐受住i2c上小台阶(0.7V作用)的灌电,使得L-Sensor ic处于半工作半死、没正常运行的阶段。
从SDA/SCL漏进去的电让内部ic错乱了,使得L-Sensor不再正常工作、不能正常启动。换句话说,即使器件没有上电,i2c漏进去的电使得器件实际上不是完全没电的,接下来的启动时序实际上不一定满足要求。
因此,解决这个问题很简单,要么让这个台阶不出现,要么出现后让它消失。
L-Sensor的电路图如下。
查看电路和规格书有如下几个重要的信息,用于决策我们的解决方案。
- L-Sensor有一个电源,用于供电。它是常开的,很前级的电,影响很大,不能想着用它来放电;且它内部连接是PMIC的一个LDO,用于放电可能有其他异常————不能切断漏电路径,也不能用于放电。
就是这路电和屏共用的,被异常放掉了,出了花屏问题
- SCL1直接接CPU I2C1,在RGB_3V3上拉没有使能的情况下,显然SCL和SDA的台阶就是SCL1自己导致的————台阶是CPU输出的
- 漏电路径看————SCL1可以放电下掉台阶
- 漏电路径看————RGB_3V3可以放电下掉台阶,但是有电阻,且属于CPU的两个GPIO之间有电流灌入流出
因此可以看到决策我们处理这个台阶的关键结论如下:
- 台阶是CPU i2c引脚自己输出出来的,它可以想办法不输出出来,或者出来后卸掉
- 漏电通路上,开关漏电路径的VIO18_PMU动不得,因此通过切断传输路径的方式来切断漏电的方案不可行
因此我们尝试再CPU引脚即SDA/SCL两根线上想办法。查看规格和代码配置有一个可行方案——把CPU引脚配置成下拉或输出0————这样可以避免输出台阶,并且就算输出了台阶也可以经CPU内部电路把台阶卸掉。
SCL1内部支持下拉,本事是SCL驱动能力较强————可以灌入电流(请硬件确认过),用SCL1来放电可以达成目标。
因此改法就很清晰了:借助dws将引脚配置为下拉,将台阶电放掉,在i2c使用之前,再切换到i2c模式,接入上拉。(实际上台阶无法完全去掉,因为CPU一旦完成初始化,这个引脚就是悬空的(芯片级默认模式),就会有台阶。CPU初始化完成后一段时间才跑到软件逻辑去下拉放电)
修改如下,只需要把对应引脚拉下去即可。
1 | <gpio84> |
这个修改导入后,量取波形(前面展示过修改后的波形图)。可以看到i2c线的台阶会有一小段拉下来,这个操作可以把i2c线上的电拉下来,把灌入L-Sersor的电放干净,使光感传感器处于正常的状态。
经过压测后问题能成功修复,再也没有复现到L-Sensor i2c通信异常和花屏异常了。
优化措施:Regulator失效了?
熟悉驱动的朋友,应该能看到一个不合理的地方。通常情况下,一些公共使用的资源,在共用这些资源的模块之间,会以特定的协作方式来控制资源的开关,防止互相干扰。比如一个智能指针,会在一个对象的引用计数降低到0的时候再回收它。
对于驱动来说,对共用电源的控制一般采用regulator。当regulator的引用计数降低到0后才真正关闭电源。
那么,在L-Sensor驱动和屏驱动均规范使用了regulator的情况下,为何屏还在用的电,仍然被L-Sensor regulator_disable关掉了呢?
经过分析,添加日志后发现,屏驱动的初始化居然在传感器后面,传感器先初始化,然后才是屏初始化。
用一个表格来说明这个逻辑,以及它是怎么触发花屏问题的。
这个问题中共用的电源来自于PMIC,下表用PMIC输出来表示这个电源,1表示打开,0表示关闭
开机过程顺序 | 跑的逻辑 | PMIC输出状态 | Regulator计数 | 备注 |
---|---|---|---|---|
PMIC初始化 | 根据代码配置,将PMIC输出为高电平 | 1 | 0 | 此时对使用该电的设备供电(屏和L-Sensor) |
初始化L-Sensor | 进入L-Sensor驱动,regulator +1 | 1 | 1 | PMIC本来就输出高电平,这里+1后仍然出高电平,供电正常 |
L-Sensor通信失败 | L-Sensor做异常释放逻辑,将regulator计数-1 | 0 | 0 | Regulator计数掉为0,触发关闭电源的逻辑,使PMIC输出0 |
初始化屏 | 进入屏驱动,regulator +1 | 1 | 1 | regulator不为0,打开PMIC供电 |
regulator正确使用,供电也正常,逻辑没问题,为什么花屏了呢?
原因在于第一步PMIC就已经是输出高电平,开始对L-Sensor和屏供电了。对于屏而言,过早的供电,不仅使屏芯片已经处于工作状态,后面的异常掉电的波形不仅不是让它重启,反而是让它变得紊乱、异常。此外,屏的初始化有时序要求,在屏驱动初始化时,本来上电时序是设计好的,谁曾想驱动逻辑想要控制的电源实际上早在L-Sensor初始化时就上好了电呢?
换句话说,就是屏不一定想要这么早上电,而且上完电后就稳稳地给我电,中间突然来一下掉到零这叫什么?
显而易见的,在屏驱动运行前,屏就已经上电了,这个时候开机亮屏都是正常的,可谓歪打正着,给屏的供电是意料之外的但是却一脸懵逼的。
因此看上去很离谱的“光感传感器通信异常居然能导致我花屏???”是有合理解释的。
我们能看到这个模块初始化顺序不仅导致功能强大的Regulator失去了其作用,而且在体验上,用户觉得开机速度快不快很大程度上就是开机亮屏快不快,居然先给我在屏初始化之前去初始化了传感器这个用户无感的模块。
最后,这个问题也很好处理,我们调整屏的初始化到前面即可。一般调节初始化阶段(initcall)会有效果。但是由于Linux各模块启动顺序有很大牵扯关联,这么改是有风险的。因此我们通过调节模块链接顺序即可实现在同一个initcall阶段内去调节模块的初始化顺序(调节链接顺序即可)。
1 | diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile |
为什么其他项目没有这个问题
- 电路设计差异
其他项目的板子,i2c SCL/SDA那里不使用mos fet,而使用专门的转接芯片。区别是,mos管会被一定的电压打开(本案说的小台阶就是这个“一定的电压”),而转接芯片不会。
一句话说,mos fet会因小台阶而导通,使电漏过去。
- L-Sensor差异
本案涉及的L-Sensor是1.8V的器件,且其内部电路设计和工艺制程会受到SDA/SCL的灌电影响,处于不正常的工作状态和不正常的上电时序。
- CPU IO配置
在开机过程中IO没有配置下拉,会使SDA/SCL存在台阶,产生了灌电流