ARTICLE DETAIL

资讯详情

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

MTK平台LT9611桥接芯片驱动调试实战:时序与初始化避坑指南

MTK平台LT9611桥接芯片驱动调试实战:时序与初始化避坑指南 简介面向联发科平台的LT9611芯片驱动源码与配置文件包适用于嵌入式显示及驱动开发人员解决在MTK方案上实现DSI转HDMI并默认输出1080p高清显示的问题。压缩包共5个文件包含3个C语言源文件和2个dws工程配置文件整体仅21KB轻量精简。目前已有974人学习下载。除驱动源码外还附带板级配置工程C代码覆盖芯片的初始化流程、寄存器操作和视频时序dws文件则提供硬件管脚与项目配置的适配入口便于在驱动移植、编译调试时迅速定位问题减少重复查阅寄存器手册的时间。这套资源对需要在MTK平台快速实现1080p HDMI输出的工程师有直接参考价值适合具备一定C语言与显示驱动基础的开发人员也可作为初次接触联发科显示子系统的入门参考资源虽小但聚焦点明确适合作为MTK显示驱动开发和调试的参考样例。1. mtk-lt9611_stomachhcc_lt9611_mtk先看懂这块板子的数据流向第一次看到mtk-lt9611_stomachhcc_lt9611_mtk这个工程名大概都能猜到这是 MTK 平台主控搭了一颗 LT9611 桥接芯片的项目stomachhcc是这块板子的内部代号大概率是一台带 HDMI 输入或者 HDMI 输出的显示类设备比如内窥镜主机、工业一体机或者医疗显示终端。核心矛盾不是主控性能而是 MTK 的 MIPI DSI 显示通路和 HDMI 外部接口之间隔着一颗 LT9611数据流看似简单实际调起来一堆时序、供电、休眠的坑。这篇文章面向正在调这块板子的驱动工程师、方案选型人员和产线支持讲清楚桥接芯片在 MTK 平台上的角色、最小可用的初始化序列以及最容易让人翻车的那几个边界条件。2. LT9611 在 MTK 平台上的接线方式I2C、复位与电源时序2.1 先确认 LT9611 工作在哪个方向LT9611 是一颗双向或者成对出现的高速桥接芯片常见两种形态MIPI DSI 转 HDMI 输出以及 HDMI 输入转 MIPI CSI/DSI 给主控。lt9611_mtk这个写法通常意味着 LT9611 挂在 MTK 的显示输出侧也就是把主控的 MIPI DSI 信号变成 HDMI 接到外部显示器但也存在另一种接法外部 HDMI 信号进到 LT9611转成并口或者 MIPI 后给 MTK 做采集处理。调错方向是最尴尬的开局因为两套初始化序列完全不一样芯片虽然能 ACK但寄存器配置一上就花屏。拿到板子先做三件事看原理图标注的数据流向量 LT9611 的 I2C 地址线、复位引脚连接的主控 GPIO 编号再开机抓一次 LT9611 的 chip id 寄存器。LT9611 的 chip id 一般能读到固定值如果读回来是全 FF 或者全 00说明 I2C 地址不对、芯片没上电或者复位脚被主控一直按着。我手上这颗板子规格是 MT6765 平台也就是常说的 p22t 那一档显示输出是 4-lane MIPI DSILT9611 挂在 I2C1 总线上。这种 MTK 平台配 LT9611 是典型的低成本显示桥接方案主控负责跑系统和图像处理桥接芯片只做协议转换不参与渲染所以调的时候只要把主控的 DSI 面板配置当成一块 虚拟面板 来写就行。2.2 设备树里怎么挂 LT9611MTK 平台一般不走标准 DRM bridge 驱动很多方案直接在panel节点里把 LT9611 当成一块特殊面板或者单独写一个i2c子设备驱动。先看设备树挂法i2c1 { lt96113b { compatible lontium,lt9611; reg 0x3b; reset-gpios pio 42 0; interrupt-parent pio; interrupts 43 IRQ_TYPE_LEVEL_LOW; pinctrl-names default, sleep; pinctrl-0 lt9611_pins_default; pinctrl-1 lt9611_pins_sleep; hpd-gpios pio 44 GPIO_ACTIVE_HIGH; status okay; }; };最关键的三个字段是reg、reset-gpios和hpd-gpios。reg是 I2C 地址LT9611 常见地址是 0x3b 或者 0x39以板端原理图为准不要照抄别人项目的地址reset-gpios对应 LT9611 复位引脚MTK 平台 GPIO 默认方向要确认否则驱动 probe 时拉一下复位芯片直接进入异常状态hpd-gpios是 HDMI 热插拔检测脚有些板子直接拉高不接主控那就别在设备树里塞这个属性否则中断一直触发。还有一个容易忽略的是 pinctrl。MTK 平台的 I2C 引脚和 GPIO 复用关系在pinctrl里定义如果sleep状态把 I2C 引脚切到 GPIO 模式系统 suspend 后 LT9611 就彻底失联了唤醒后驱动重试 I2C 也会失败。建议 sleep 状态保留 I2C 功能只把复位脚改成输出低。2.3 电源域和上电顺序不是给电就行LT9611 的供电通常有 VCC、VDDIO、AVDD 好几路分别给数字核心、I2C 接口和高速收发器供电。MTK 平台用 PMIC 的 LDO 供电时要注意 LDO 的上下电顺序。常见翻车现象是冷启动 30% 概率读不到 I2C重新触发一次软复位就恢复。这类问题大多是复位脉宽不够或者 VDDIO 起来前主控已经访问 I2C。我一般会在驱动里做强约束先等 VCC 稳定延时 10ms再把复位脚拉高再延时 5ms然后才开始读 chip id。如果硬件上复位脚和主控 GPIO 之间有 RC 延时驱动里的延时可以缩短但不要图省事把延时删掉。另一个点是 VDDIO 的水平要和 MTK 平台的 I2C 电平匹配常见是 1.8V如果板端用了 3.3V 而主控 I2C 是 1.8V 域就需要电平转换否则读回来的寄存器值偶发错乱排查起来非常玄学。3. 跑通 LT9611 的初始化序列从 I2C 裸写开始3.1 最小验证集不加载驱动先确认总线通在 LT9611 起来之前先把 I2C 总线摸一遍。MTK 平台允许在串口 console 里直接用i2ctransfer工具这是调试桥接芯片的后悔药比反复重编内核快得多。#!/bin/bash # 手动探测 LT9611确认 I2C 通路 # 假设总线是 i2c-1地址是 0x3b8-bit 地址是 0x76 # 读 chip id 寄存器正常返回 0x96 开头的数据 BUS1 ADDR0x3b # 先探测设备是否存在 i2ctransfer -y $BUS w1$ADDR 0x00 r1 # 如果上面返回数据读版本寄存器并打印 value$(i2ctransfer -y $BUS w1$ADDR 0x00 r1) printf LT9611 chip id: 0x%02x\n 0x$value如果读不到不要急着查硬件。先检查i2c-detect能不能枚举到设备再确认内核是否已经加载了 LT9611 的驱动把总线占住。很多 MTK 方案会把 I2C 子系统的i2c-transfer报文日志关掉可以在/proc/i2c或平台的自测节点里看有没有 NACK 计数。3.2 标准初始化序列的三个阶段LT9611 的初始化序列分成三段系统配置、显示通路配置、输出配置。系统配置包括软复位、时钟源选择、中断使能显示通路配置包括输入端口选择、DSI 输入 lane 数、像素格式输出配置包括 HDMI 分辨率、TMDS 时钟、音频以及 HDCP。对应到 MTK 平台驱动里一般会在probe时把整段序列写进去但这容易把问题放大一旦某次写入顺序不对后续寄存器全错乱而且很难定位是哪个寄存器导致花屏。正确做法是把初始化序列拆成三个函数每个函数对应一段然后通过一个全局状态来标记当前走到哪一步。比如lt9611_system_init只做软复位、读版本、配时钟源lt9611_video_init只在面板分辨率确定后才调用lt9611_output_init放在 HDMI 插入中断里触发。这样热插拔时不用重新初始化整个芯片只需要重配输出段。LT9611 支持在保持 DSI 输入不变的情况下单独重新建立 HDMI 输出这个特性在信号源切换场景里非常关键。3.3 MIPI 参数必须和时序联动MTK 平台的 DSI 输出侧有独立的时钟寄存器和 lane 数配置LT9611 这侧要一致。我见过最经常的配置错误是主控配了 4-laneLT9611 配了 2-lane结果画面只有一半是正常的另一半全是雪花。# 计算 1080p60 RGB888 4-lane 的最低 lane rate h_active 1920 hfp 88 hbp 148 hsync 44 v_active 1080 vfp 4 vbp 36 vsync 5 fps 60 htotal h_active hfp hbp hsync vtotal v_active vfp vbp vsync pixel_clock htotal * vtotal * fps bpp 24 lane_num 4 lane_rate pixel_clock * bpp / lane_num print(pixel clock: %.2f MHz % (pixel_clock / 1e6)) print(minimum lane rate: %.2f Mbps % (lane_rate / 1e6))这里算出来的 lane rate 是理论最低值实际初始化要留 10%~20% 余量。LT9611 的 HDMI 侧输出时钟由输入像素时钟决定如果输入的 lane rate 不够TMDS 时钟会被芯片内部 PLL 强行提升容易引入高频抖动画面表现为水平方向轻微横纹。参数说明hfp/hbp是水平前后肩vfp/vbp是垂直前后肩这些值必须从目标 HDMI 显示器的 EDID 或者设定好的时序表里抄不能随意改。MTK 平台里这些参数分布在mtkfb的panel_params结构体中LT9611 驱动侧只使用 htotal/vtotal 的乘积来计算 PLL 分频。3.4 中断和热插拔处理LT9611 的 HPD 脚在 HDMI 线插入时会产生中断。MTK 平台的写法一般是注册一个 GPIO 中断在线插入时重新读取 EDID、再走一遍lt9611_output_init。要注意中断触发类型有些板子 HPD 是低有效有些是高有效配错会导致系统一开机就疯狂触发中断然后整机卡死。我在平台驱动里加了中断防抖延时 50ms 再读 HPD 状态同时加了一个互斥锁防止在dsi_panel的显示流尚未 ready 时 HDMI 中断进来造成竞态。实际量产中热插拔异常多半出在同时切换分辨率那一瞬间处理原则是先让 LT9611 输出端静默再切换输入侧时序最后重新使能输出。4. 时序表和像素时钟把屏参填对才能看到开机 Logo4.1 从屏规格书到 MTK panel_params 的映射LT9611 不只是桥接信号它还负责从输入的 DSI 信号里提取时序参数并生成 HDMI 输出时序。一旦输入侧时序不标准HDMI 接收端会直接拒收。所以 MTK 平台里那块 虚拟面板 的时序参数必须按照实际的 HDMI 显示器或者接收芯片的 EDID 来填而不是照着某个 LCD 屏的手册随便填。分辨率H_ACTIVEHFPHBPHSYNCV_ACTIVEVFPVBPVSYNCPixel Clock720p60128011022040720520574.25 MHz1080p601920881484410804365148.50 MHz1080p5019205281484410804365148.50 MHz注意 1080p50 的 pixel clock 和 1080p60 一样但水平消隐区更大这是 HDMI 标准里的规定。MTK 平台如果按 1080p60 的时序去推 50Hz会导致画面右侧有压缩感。LT9611 驱动里如果写了固定的 htotal/vtotal它会把输入的时序直接透传到 HDMI这时候不能靠驱动去改时序只能回 MTK 的mtkfb里调。4.2 用开机 Logo 验证时序对错MTK 平台有一个天然优势开机 Logo 阶段不加载完整 Android 显示栈只用mtkfb的简单路径输出画面。调 LT9611 时我建议把 Logo 当成第一道验证工具不要急着进系统看桌面。# 替换 MTK 平台的 logo 分区并整包烧录的常用流程 # 先把目标分辨率对应的 logo.bin 放到 release 包的 image 目录下 cp logo_1080.bin $MTK_SDK_PATH/out/target/product/p22t/logo/logo.bin # 重新打包 logo 分区镜像 ./build_ota.sh --include-logo # 用 mtk 的刷机工具把整包烧进板子 # 烧完后观察串口日志确认 logo 阶段有没有 DSI 报错如果 Logo 能正常显示说明 MTK 的 DSI 输出时序已经正确LT9611 的输入侧也匹配。如果 Logo 花屏或者不出画面先不要进系统直接在 Logo 阶段就抓串口。logo.bin的替换是个非常快的回归手段每个分辨率准备一张专用测试图比如纯红、纯绿、渐变色然后把对应的logo.bin烧进去。以后每改一次时序参数烧一次logo.bin再看一遍十分钟就能确认新参数是否破坏显示通路。很多开发机上线后OTA 升级logo.bin的需求也是从这里来的产线上换面板型号时可以只换 logo 分区不重烧整个系统。4.3 在 MTKfb 里打时序日志时序不对的另一个典型表现是Logo 阶段正常进系统后桌面边缘被裁剪。这通常是 LCD 驱动和 GPU 合成层的时序配置不一致。在lk阶段的显示配置和 kernel 的mtkfb配置存在两套参数LT9611 作为外接桥接时两套都要同步改。我一般在mtkfb的panel_params初始化函数后面加一段打印// 打印当前使用的时序参数确认模式和屏参一致 pr_info(lt9611 debug: hs%d hbp%d hfp%d vs%d vbp%d vfp%d fps%d\n, panel-hsc, panel-hbp, panel-hfp, panel-vsc, panel-vbp, panel-vfp, panel-fps);这些打印在长期调试里价值很大。因为 MTK 平台多个项目共用一套 BSP经常出现屏参在别的项目里被改动编译出来时序跟着变光看代码很难发现。在 lk 和 kernel 各打一条对比两边的htotal*vtotal*fps是否一致这是最快定位 进系统后黑屏 的方法。5. LT9611 调试避坑专区休眠、I2C 掉线、花屏与黑屏5.1 冷启动概率性 I2C 读不到设备现象同一台机器冷启动 100 次里大约有 20 次读不到 LT9611正常运行中一切正常。原因LT9611 的复位时间不够主控 I2C 在芯片未退出复位状态时发起访问芯片不 ACK外观上偶尔表现为芯片根本没有起来。解决在驱动 probe 开始时先保证复位时序正确复位拉低后延时至少 20ms再拉高拉高后读 chip id。如果和 PMIC 的 LDO 使能顺序耦合就把 LDO 使能提前。这类问题不建议靠重试 I2C 掩盖因为重试会导致系统启动时间不稳定产线测试会偶尔卡在开机阶段。5.2 开机有 Logo进系统后 HDMI 黑屏现象预加载阶段画面正常安卓系统起来后就黑屏串口没有报致命错误LT9611 I2C 仍能正常访问。原因MTK 平台在进系统后显示路径从lk切换到 kernel display再到 SurfaceFlinger显示时钟会被重新配置。LT9611 检测到 DSI 信号中断后进入省电模式但驱动的resume回调没有重新补偿视频通路。解决在mtkfb的dsi_enable回调里把 LT9611 的视频通路重新初始化不要只依赖 I2C 子系统的恢复。这个函数的调用时机一般在显示时钟稳定之后用任务延后 100ms 执行再写寄存器会比在回调里直接写更稳。5.3 画面色彩发红/发绿或者有规律横纹现象色彩的色温整体偏移或者屏幕上有一条条水平干涉条纹。原因LT9611 输入的 DSI 数据格式和 MTK 输出格式不一致例如平台输出 RGB888而 LT9611 被配置成 YUV420另一种可能是 lane rate 余量不够TMDS 时钟在高速翻转时产生串扰。解决先确认panel_params里的data_format然后在 LT9611 驱动寄存器里核对输入格式。参数表里常见的组合是RGB888_4_LANE_DDR和RGB888_4_LANE_SDR不要混淆。MTK 平台里还遇到过摄像头驱动和显示驱动共用资源导致带宽挤压的情况那属于MTK 相机插值和显示通路抢 DPI 时钟的问题锅不在 LT9611要调平台时钟分配。5.4 休眠唤醒后 LT9611 配置丢失现象整机 suspend 再 resume画面能回来但热插拔失效或者 HDMI 显示分辨率变成 640x480。原因MTK 平台在 suspend 阶段会把整条 DSI 显示链路的电源断掉LT9611 内部寄存器在掉电后全部复位。唤醒时平台没有把初始化序列完整重放一遍只恢复了 I2C 通信。解决把初始化序列做成一个幂等的整体在 resume 里强制全量重写而不是只恢复中断。可以顺手读一次chip id确认芯片内核没连供电都断掉。部分平台还涉及 DRAM 自刷新如果 DDR 进入自刷新以后显示控制器还挂着 DSI 访问唤醒会卡死需要保证先退出自刷新再初始化 LT9611这个顺序在mtk_dsi的suspend/resume回调里要有明确依赖。5.5 同一份代码在不同板卡上表现不一致现象软件版本不变换一张主板后画面出现轻微偏移或者没声音。原因LT9611 周边的晶振频率、I2C 上拉电阻阻值、HDMI 座子的 ESD 器件寄生电容都会影响高速信号质量。很多项目里硬件换料后没有人同步更新软件里的tx_clk参数。解决每一批硬件变更都要重新测量 LT9611 输入的 DSI 信号质量和 HDMI 输出信号的眼图。不要因为软件看起来正常就忽略硬件参数漂移。时序余量少的板子往往在温度升高后才暴露问题表现为长时间播放后偶发闪屏。给每块新板子做一次 24 小时老化测试比调一万行驱动代码都管用。6. 进阶调试寄存器快照对比和串口日志分级LT9611 这类桥接芯片本质上是个黑匣子驱动代码写得再完整寄存器行为不验证照样踩坑。我最常用的手段是寄存器快照在初始化前后各抓一份全寄存器 dump然后做 diff。正常启动下只有几十个寄存器会变化如果上百个寄存器都在跳说明芯片处于异常状态或者驱动里写了冲突的配置。#!/bin/bash # 抓取 LT9611 全部寄存器快照用于对比上电状态和驱动初始化后的状态 BUS1 ADDR0x3b for i in $(seq 0 255); do reg$(printf 0x%02x $i) val$(i2ctransfer -y $BUS w1$ADDR $reg r1) printf %s: %s\n $reg $val done /tmp/lt9611_reg_before.txt把这份快照保存下来每调一个功能就重新抓一次做 diff。比如 HDMI 热插拔失效对比插拔前后 HPD 状态寄存器的变化就能知道是芯片没收到信号还是收到信号后没上报中断。这个习惯帮我省了大量反复重构驱动的时间。串口日志也要分级。MTK 平台开CONFIG_MTK_FB_DEBUG前后日志量差很多日常调试别开全量日志否则海量重复信息会淹没有用的 DSI 时序报错。我一般只开lcm和dsi两个模块的调试打印等到热插拔或休眠唤醒问题出现时再临时开全量抓一次抓到现场就立刻关掉。对于 MTK OTA 升级logo.bin或整包升级后的回归测试不要只在 Android 桌面确认显示正常要在 lk 阶段、kernel 阶段、Android 显示服务起来三个阶段分别截屏。LT9611 桥接方案里三个阶段的显示驱动配置可能由不同组件持有任何一套配置不对都会在后续阶段暴露问题。先跑通 lk 到 kernel 的显示迁移再优化 HDMI 画质。拿到 LT9611 这类项目先别急着写驱动花半天时间把 I2C 通路、复位、电源时序、HPD 中断四件事全部摸一遍再来写初始化序列后面会顺畅得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表