ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

MIPI DSI转HDMI方案:LT9611UXC桥接芯片选型与Linux驱动调试

MIPI DSI转HDMI方案:LT9611UXC桥接芯片选型与Linux驱动调试 做显示方案的工程师八成遇到过这种需求主控平台只有MIPI DSI接口但客户非要HDMI输出接电视、接投影、接广告屏。以前要么换主控要么塞一颗FPGA做协议转换成本和开发周期都兜不住。龙迅LT9611UXC这类芯片就是专门来收拾这个局面的。它把双端口MIPI DSI/CSI输入转换成HDMI 2.0输出内部还带音频嵌入一颗芯片把视频链路和音频链路全打通。这篇文章我把从选型、硬件设计到Linux驱动调试的完整过程捋一遍给后面做方案的朋友做个参照。无论你是硬件工程师在画原理图还是软件工程师在调驱动或是产品经理在评估选型应该都能从里面找到点用得上的东西。1. 这颗芯片到底解决什么问题从一块只有MIPI输出的板子说起1.1 显示链路里的“最后一公里”先看系统架构。现在的应用处理器SoC内部显示链路大致是GPU渲染出画面DPUDisplay Processing Unit做图层合成和图像增强然后交给MIPI DSI控制器最终通过DSI接口输出到屏。这里面的DPU、GPU、VPU、NPU各管一摊显示器这块最后露头的往往就是MIPI DSI或LVDS。问题在于很多产品形态需要的是HDMI输出——接电视、接投影、接视频采集卡。 MIPI DSI是给移动设备面板设计的短距离接口HDMI是消费电子通用的长距离音视频接口两者协议完全不一样没法直接连。LT9611UXC就是中间这颗“翻译管”。它在系统里的位置非常简单直观SoC的MIPI DSI输出接芯片的MIPI接收端芯片的HDMI发送端接显示器或电视的HDMI输入。主控不需要额外增加HDMI控制器也不需要改Linux内核里的显示框架只要把原有DSI输出的像素时钟和时序配好剩下的交给桥接芯片。讲个实际场景。我做过一个投屏盒子主控用的是瑞芯微RK3588S板子本身只设计了MIPI DSI和一个eDP口客户临时要求加一路HDMI 2.0输出用来接电视。重新选带HDMI的主控不现实板子改版也来不及最合理的做法就是加一颗LT9611UXC把其中一路MIPI DSI转成HDMI。整个改动集中在DSI控制器配置、桥接芯片的I2C初始化、设备树三处硬件上也就是一组MIPI差分线加一个HDMI连接器的事。1.2 芯片本身的底子与目标场景LT9611UXC是龙迅半导体推出的一颗桥接芯片核心功能从型号就能看出来Dual-Port MIPI DSI/CSI to HDMI 2.0 with Audio。拆开讲就是三个能力接收侧支持双端口MIPI DSI或MIPI CSI输入每个端口通常是4条data lane合计最多8条data lane具体lane数和速率配置以数据手册为准发送侧输出HDMI 2.0最高到4K60Hz这个级别具体色深和时序组合需要看手册确认音频部分内置I2S和SPDIF输入能把外部音频流嵌入到HDMI输出里实现音视频同步输出。这颗芯片能覆盖的场景我大致列一下应用方向具体形态为什么需要它投屏盒子/电视棒手机或盒子把画面输出到电视主控只有DSI电视只认HDMI广告机/商显各种尺寸信息屏板卡接口单一需要标准化HDMI输出视频会议终端会议平板、摄像头一体机本地显示用DSI屏同时需要HDMI给远端或扩展屏工业HMI工控机、人机交互面板需要稳定可靠的HDMI输出且支持长时间运行机器视觉/医疗影像内窥镜、工业相机预览用CSI接口转HDMI做实时显示FPGA图像采集高帧率视频流显示FPGA输出MIPI CSI转HDMI到监视器这些场景的共同点是视频源一端是MIPI显示终端一端是HDMI。LT9611UXC的定位就是把这个转换做得足够省事一颗芯片搞定视频和音频两条链路。1.3 为什么不直接选带HDMI的主控很多人会问选一颗自带HDMI控制器的SoC不就行了这个问题在方案选型时几乎每次都要解释一遍。带原生HDMI输出的主控当然有比如海思、部分晶晨、部分瑞芯微型号但它们有两个现实问题。第一是型号选择受限为了一个HDMI接口去换整个主控平台意味着重新评估算力、内存带宽、外设接口、供货周期项目风险远大于加一颗桥接芯片。第二是很多主打低功耗或成本敏感的平台上HDMI控制器在硬IP层面就带HDCP、EDID、音频包封装等功能这会让芯片面积和授权成本明显增加逼着你为用不上的功能买单。还有一类情况更典型项目一开始只需要MIPI屏方案已经批量出货了后来客户要HDMI。桥接芯片的插入式设计意味着原有板卡布局可以尽量不动软件上也只需要增量修改这个灵活性是非常值钱的。需要提醒一点桥接芯片不是一根转接线。它内部的MIPI接收端、HDMI发送端、音频嵌入模块、EDID和HDCP逻辑都需要初始化通常通过I2C寄存器配置完成。这也是为什么后面驱动调试部分这么重要——硬件上看似简单软件上还是要认真对待。2. Dual-Port MIPI的真正意义带宽不够才是核心矛盾2.1 MIPI DSI/CSI的带宽账本很多人看到“Dual-Port”第一反应是能接两个屏这个理解不太对。双端口首先是为了带宽不是为了多接一块屏。MIPI DSI和CSI走的是D-PHY物理层高速模式下每条data lane的速率通常在1Gbps到1.5Gbps之间。一个常规的4-lane端口理论可用带宽就是4Gbps到6Gbps。那4K60Hz需要多少带宽我们来算一笔很实在的账。以3840x216060Hz为例按典型的VESA时序水平方向加上blanking大约有4400个像素时钟垂直方向大约2250行像素时钟约594MHz。如果采用RGB888格式每像素24bit纯数据率就是594MHz × 24bit 14.256Gbps单端口4-lane MIPI在1.5Gbps/lane时也就6Gbps连4K30都不太宽裕。就算单端口4-lane跑满1080p60Hz RGB888大约需要3.2Gbps带宽勉强能塞进去但余量很小1440p60Hz一下就超了。所以芯片设计成双端口两个4-lane端口合起来最多能提供12Gbps量级的接收能力。这就是“Dual-Port”存在的根本原因。选型时先看你要输出什么分辨率反推需要几组lane这是第一步目标输出典型像素时钟RGB888数据率4-lane单端口能否满足1080p60148.5MHz3.56Gbps能但余量有限1440p60262.75MHz6.3Gbps不能需要双端口4K30297MHz7.13Gbps不能需要双端口4K60594MHz14.26Gbps必然需要双端口压缩/降色深我一般这样建议只要目标分辨率超过1440p60就直接选双端口方案就算当前项目只用单端口也留出升级空间。2.2 双端口是怎么协同工作的双端口MIPI有两种典型工作模式理解它们对配置寄存器至关重要。第一种是Split模式也就是“左右拼接”。主控的DSI控制器把一帧画面按垂直中线分成左右两半左半幅从端口0传输右半幅从端口1传输芯片内部再把两路数据拼成完整的HDMI帧。这是双端口最常见的用法适合带宽翻倍。第二种是镜像或冗余模式两个端口传完全相同的内容主要用来提高可靠性和兼容性或者配合某些主控DSI控制器的特殊时序。实际产品里大部分用Split模式。Split模式有个关键点两端口的像素时钟必须严格同源行同步时序必须一致。芯片内部的拼接逻辑是靠行同步信号对齐的如果两个端口的时序参数有微小差异轻则拼缝处出现一条竖线重则整屏花掉。所以配设备树时两个DSI端口的display-timing要尽量保持一致的通道参数。还有一个容易忽略的地方不是所有SoC的MIPI DSI控制器都支持split模式。设计之前我强烈建议先确认主控DSI控制器是否支持dual-channel拆分。从瑞芯微、NXP i.MX8M系列到高通的某些平台支持能力差异很大有些平台的DSI控制器本身只有4-lane这就没法拆出两个独立端口必须从硬件上确认主控有两路独立的DSI控制器。2.3 DSI和CSI的双重身份带来的额外好处芯片型号里的“DSI/CSI”是个容易被低估的卖点。DSI是给显示屏用的串行接口CSI是给摄像头用的串行接口两者物理层都是D-PHY但协议层有差别。LT9611UXC同时支持两种意味着它不只是“屏转HDMI”还能做“摄像头/图像传感器转HDMI”。我见过一个很有意思的项目工业内窥镜前端是CMOS sensor通过MIPI CSI输出主控是个不带显示接口的MCU他们直接用LT9611UXC把CSI视频流转成HDMI接到监视器上做实时显示。这种用法避开了主控没有显示控制器的问题也算是一种“野路子”但确实能跑通。对于FPGA开发者来说CSI输入转HDMI也很有用。FPGA内部逻辑做完图像处理后用MIPI CSI TX IP核把数据发出来桥接芯片负责变成HDMI给显示器。这样FPGA侧不用去实现复杂的HDMI物理层和TMDS编码省了很多事。需要留意的是DSI和CSI在帧格式上不一样。DSI是连续的video mode流时钟和同步在数据包里CSI通常有帧起始/帧结束包不同sensor的时序差异更大。用CSI模式时不能照搬DSI的初始化配置寄存器里CSI接收相关的lane数、帧格式、数据类型这几个点要逐一确认。3. 音频是怎么塞进HDMI的I2S、SPDIF与HDA三条路径3.1 HDMI音频的封装逻辑HDMI和传统模拟视频/音频最大的区别之一就是HDMI连接器上没有独立的音频管脚。音频数据在HDMI链路里是被打包成Data Island Packet插在视频信号的blanking区间里通过TMDS数据通道发出去的。接收端电视、显示器再解析这些包还原出音频流。这个机制带来的直接后果就是任何HDMI发送设备都必须有一个模块负责接收外部的I2S、SPDIF这类音频总线数据然后按HDMI规范封装成包。LT9611UXC内置了这个音频接收和封装模块所以你在芯片输入侧看到的是音频总线管脚输出侧则和视频一起走HDMI。这也解释了为什么“audio端口定义”经常被问。在HDMI连接器的物理定义里根本没有单独的音频端口音频就在TMDS的Data Island里。调试的时候别拿着万用表去HDMI连接器上找音频波形那是找不到的。3.2 I2S多声道输入的配置要点I2S是桥接芯片最常见的音频输入方式。它至少需要三根信号线BCLK位时钟、LRCLK声道时钟/帧同步、DATA串行数据再加上MCLK主时钟组成完整的一组。MCLK是音频工作最核心的时钟它必须和采样率保持严格的整数倍关系常见的有256fs、512fs等。这里要非常小心一个坑I2S有标准I2S、Left-Justed、Right-Justed这几种格式区别在于数据位相对于LRCLK边沿的对齐关系。主控的I2S控制器配置成Left-Justed芯片寄存器里却设置成Standard I2S最常见的结果是左右声道颠倒或者出来全是噪声。每次遇到“图像正常但声音不对”的问题我第一个查的就是这个对齐关系。另一个高频问题出现在采样率配置上。芯片需要知道输入音频的采样率32kHz、44.1kHz、48kHz、96kHz、192kHz等然后才能计算出正确的CTS/N值去生成HDMI音频包。如果主控侧音频实际是48kHz但桥接芯片寄存器里配成了44.1kHz输出的音频表现为音调偏高或偏低、严重时直接没声。软件上一定要保证两边采样率设置完全一致。多声道场景下要注意I2S数据线上传输的通道排列。8声道通常需要多条I2S数据线比如4组DATA芯片怎么把这几组数据映射到HDMI的8个声道寄存器里有一张表。配置错位的结果就是声音从错误的音箱出来这类问题用示波器也很难看最好先把声道映射表打印出来对照。3.3 容易被忽略的MCLK与HDA方案牵扯在音频方案选型时主控侧输出音频的路径一般就两种一种是I2S/SPDIF直接给到桥接芯片。另一种是Intel HDAHigh Definition Audio总线常见于x86平台。标题里虽然只写了Audio但实际项目里“音频走哪种方案”直接决定你该怎么接。Intel HDA是Intel主导的高清晰音频规范很多x86主板、迷你主机上的HDMI/DP音频都是从HDA总线出来的。LT9611UXC这种桥接芯片通常接受的是I2S/SPDIF不直接挂在HDA总线上。所以用x86主板做HDMI转接时经常会遇到“明明系统里能看到Intel HDMI Audio设备但就是没有声音输出到转接后的HDMI”这种问题。这里我要说一个比较务实的经验如果你是用x86平台做商显或投屏产品选型时要先确认主板的音频架构。有些主板提供了I2S/SPDIF排针可以直接送给桥接芯片如果没有就得加一颗HDA转I2S的音频Codec或者放弃板载HDA音频走PCIe/USB声卡转I2S。千万不要默认I2S一定有信号这个在项目启动前就要排查完。另外很多工程师会被“Intel High Definition Audio驱动”带偏以为没声音是驱动没装好。实际上在桥接芯片场景里驱动只是让系统枚举出HDMI音频设备物理链路上到底用的是I2S还是HDA、MCLK有没有起振、格式对不对这些才是无声问题的根源。驱动层面能看到的永远只是冰山一角。4. 硬件设计与寄存器配置让芯片先亮起来的关键步骤4.1 电源、时钟、复位供电与上电时序桥接芯片看着不起眼但对电源和时钟的要求一点不含糊。LT9611UXC通常需要多路电源轨常见的有1.8V和3.3V内部有PLL用于恢复MIPI时钟和生成HDMI TMDS时钟。PLL对电源噪声非常敏感电源纹波大最直接的体现就是HDMI输出抖动超标显示器开机偶尔黑屏或闪屏。我画原理图时对这几路电源的要求是主电源纹波控制在30mV以内电源走线先经过磁珠再进芯片电源管脚每个电源管脚旁边放0.1uF和10uF两个电容电容尽量靠近管脚摆放。这个做法看起来简单但能避免很多诡异现象。时钟方面芯片需要参考时钟通常是一个外部晶振或晶振模块常见频率25MHz或27MHz。参考时钟的精度直接影响HDMI的TMDS时钟准确性选择晶振时优先看频率稳定度工业级方案尤其在宽温范围内要特别注意ppm偏差。如果是用外部时钟源走线要短旁边做包地处理避免数字信号耦合。复位和上电时序也要认真对待。典型要求是电源稳定之后时钟建立完成然后释放复位信号。如果复位释放早于电源稳定芯片内部逻辑可能进入未知状态。软件侧I2C初始化必须在复位释放之后才开始操作否则写寄存器可能失败。很多“上电黑屏”问题排查到最后就是复位时序不满足。4.2 I2C控制与寄存器配置链路LT9611UXC本身没有Flash内部逻辑完全靠主控I2C配置。这颗芯片在系统里就是一个标准的I2C从设备从机地址常见在0x2B附近具体看数据手册。整套驱动做的事情其实非常固定我按实际项目流程拆解如下上电后主控通过I2C读取芯片ID寄存器确认I2C通信正常、芯片型号正确配置MIPI接收端设置输入是DSI还是CSI、lane数、lane极性、连续时钟还是非连续时钟、DSI视频模式参数配置HDMI发送端使能HDMI输出、设置输出分辨率时序、HDCP是否开启、HPDHot Plug Detect引脚的工作方式配置音频模块选择I2S还是SPDIF输入、I2S格式、采样率、声道数最后写一个软启动或输出使能寄存器让HDMI开始输出。整个初始化流程看着不长但每个步骤的寄存器值都需要和具体分辨率、具体主控平台匹配。最怕的就是网友从某个论坛复制了一套旧版本的初始化序列直接用在UXC后缀的新型号上。同系列芯片不同后缀之间寄存器定义有差异旧代码写进去要么没反应要么莫名其妙花屏。调试这个阶段最实用的工具就是I2C总线命令。Linux下用i2cdetect扫描设备地址i2cget/i2cset读写寄存器i2cdump批量查看寄存器内容。我习惯先跑一遍i2cdetect确认从机地址然后读芯片版本号确认物理链路通了再去调后面的显示和音频。4.3 PCB Layout高速信号不是堆完线就完事LT9611UXC的PCB Layout有两条关键的高速链路输入侧是MIPI差分对输出侧是HDMI差分对。任何一个接口走线出问题都会表现为显示不稳定或信号质量差。MIPI差分对要求100欧姆差分阻抗HDMI同样是100欧姆差分阻抗。layout时优先保证差分对的阻抗连续性走线尽量少打过孔组内等长通常控制在5mil以内不同lane间的长度差也别拉太大否则会引入时钟和数据之间的skew。ESD防护也是个看不见的坑。HDMI连接器是外露接口必须加TVS管做静电防护但TVS管的结电容会直接影响高速信号的上升沿结电容太大会导致信号劣化。常见做法是选择结电容小于1pF的TVS并把它放在连接器到芯片之间尽可能靠近连接器的位置。还有一点我提过很多次回流路径。高速信号下方要有完整的地平面不要在差分对下方切断地平面。如果板层紧张也要保证MIPI和HDMI走线的参考地是连续完整的。高频信号回流路径一断EMI和信号质量会双双恶化。5. Linux驱动接入与调试避坑我实测中遇到的几个典型问题5.1 DRM Bridge框架下的接入思路在Linux下把LT9611UXC接入显示链路通常的做法是利用DRM子系统的bridge框架。SoC的DSI控制器作为drm_encoder桥接芯片注册成drm_bridge显示面板或HDMI连接器作为最末端。设备树里的连接关系大致是dsi0 { status okay; #address-cells 1; #size-cells 0; ports { #address-cells 1; #size-cells 0; port0 { reg 0; dsi0_out: endpoint { remote-endpoint lt9611uxc_in; }; }; }; }; i2c4 { status okay; lt9611uxc: lt9611uxc2b { compatible lontium,lt9611uxc; reg 0x2b; pinctrl-names default; interrupt-parent gpio1; interrupts 15 IRQ_TYPE_LEVEL_LOW; reset-gpios gpio1 16 GPIO_ACTIVE_LOW; ports { #address-cells 1; #size-cells 0; port0 { reg 0; lt9611uxc_in: endpoint { remote-endpoint dsi0_out; }; }; }; }; };上面这个设备树是示意写法具体字段跟着内核版本走。驱动需要实现的回调一般包括probe里做I2C初始化和GPIO复位attach时把bridge挂到encoder链路上mode set阶段把DSI和HDMI的时序参数配置到寄存器。启动日志里能看到bridge probe成功只代表驱动加载了不代表显示一定正常——这一点要心里有数。Android平台相对更复杂因为音频路由还牵扯到AudioPolicy。如果系统的audio policy把HDMI音频路由到了其他设备即使桥接芯片I2S信号有输出电视端也听不到声音。排查时先用tinyplay/tinyhost直接指定输出设备播放绕过AudioPolicy能快速定位是硬件链路问题还是上层策略问题。5.2 黑屏与花屏的排查链路黑屏是最常见的问题也是最需要按链路一步步查的。我复现一次完整排查过程第一步看HPD电平。用示波器或GPIO读一下芯片的HPD引脚确认HDMI显示器是否被芯片检测到。如果HPD一直是低电平说明显示器没有正确握手问题出在HDMI线缆、连接器或显示器本身。第二步读EDID。通过芯片的I2C寄存器去读显示器的EDID。如果能正常读到EDID说明HDMI物理链路、HPD、DDC通道都是通的。读不到EDID时先量HDMI 5V引脚、DDC上拉电阻很多黑屏其实是DDC引脚虚焊或者TVS管结电容过大把DDC信号搞挂了。第三步看MIPI输入。用示波器量MIPI clock lane有没有波形。如果输入侧没有像素时钟说明SoC的DSI控制器没起来或者DSI配置参数有误。这时候去查内核drm日志看看有没有“failed to enable DSI”之类的报错。第四步确认时序参数。桥接芯片能接受的DSI时序是有范围的需要检查像素时钟频率、Htotal/Vtotal等参数是否在范围内。有时候主控输出的时序在面板上能显示但由于blanking参数不合规桥接芯片或HDMI接收端就锁不住。花屏的排查思路类似但更偏向信号完整性。我整理了一张表按优先级排查现象最可能原因排查方法整个画面有规律的斜纹MIPI lane映射或极性配置错误核对寄存器中lane极性/map设置屏幕上半部分错位两个端口拼接不同步检查两个DSI端口的时序是否完全一致高分辨率下马赛克/丢帧带宽不足或信号质量差降分辨率验证检查差分对阻抗间歇性闪屏电源纹波大、时钟抖动示波器测电源和MIPI eye diagram竖线或色块错位lane间skew过大检查等长约束和过孔数量花屏排查要抱着“从易到难”的思路。先查软件配置把所有和极性、映射相关的寄存器全部核对一遍然后再动示波器看信号质量。不要一上来就怀疑芯片坏了绝大多数情况是配置或布线问题。5.3 无声问题的完整排查过程画面已经出来了但电视没有声音这对HDMI桥接方案是个经典问题。我拿一次实际调试记录说明完整思路这套链路可以复用到类似的芯片上。现象1080p画面正常HDMI输出无声音电视端显示“未检测到音频信号”。排查第一步确认主控端音频驱动是否在跑。用命令查看ALSA声卡设备列表确认I2S声卡设备存在并且没有被mute。很多时候驱动加载了但route没设对音频数据根本没送到I2S引脚。排查第二步示波器测I2S信号。分别量MCLK、BCLK、LRCLK和DATA。如果MCLK没有波形那问题几乎必然在音频主时钟配置上。很多SoC的I2S控制器需要额外使能MCLK输出寄存器不配就永远没有时钟。这次调试的记录里MCLK是存在的所以继续往下查。排查第三步确认I2S格式。用逻辑分析仪抓LRCLK和DATA的关系看是标准I2S还是Left-Justed。抓下来发现主控输出的是Standard I2S芯片寄存器也配的Standard I2S这一项排除。排查第四步确认采样率配置。主控音频输出是48kHz芯片配置也是48kHz排除。排查第五步回到芯片寄存器逐项确认音频使能位、通道数设置。结果发现芯片的音频模块使能寄存器没有写成功。重新读取寄存器发现写入被清掉了再查是I2C写时序问题——初始化音频模块时I2C总线被其他线程占用寄存器写入失败但驱动没有检查返回值。这也是个典型教训驱动里检查I2C写操作的返回值很重要不能只写不看。这个问题修完之后声音正常。经验总结就是HDMI无声问题的排查顺序一定是“主控侧音频输出→I2S物理信号→芯片寄存器配置→HDMI包参数”一层层排除不要一拍脑袋就认为芯片坏了。还有个小提醒在Android平台上如果遇到“多应用同时录音时HDMI音频输出异常”这类并发场景先检查AudioPolicy对音频焦点和录音并发策略的处理这通常和桥接芯片无关纯粹是系统音频策略把低优先级输出给切掉了。动手调试之前先把数据手册里音频这一章完整看一遍。不要对着网上过时的初始化代码抄同样是I2S使能寄存器地址可能完全不同。花半小时看手册能省后面两天查问题的时间。我个人做这类方案的一条原则是先让画面亮起来再补音频先1080p再上4K先单端口再开双端口。一步一步验证每个阶段确认正常再往前走这样出了问题能快速定位。这芯片本身的稳定性在同类产品里算是过关的真正决定项目成败的往往是周边设计和驱动细节。后面如果大家感兴趣我可以再写一篇关于HDCP认证和HDMI CTS测试的实操记录那条路上踩的坑更多。
返回列表