LT9611EX双端口MIPI DSI转HDMI 1.4实战:从寄存器配置到驱动适配

发布时间:2026/9/21 2:37:20
LT9611EX双端口MIPI DSI转HDMI 1.4实战:从寄存器配置到驱动适配 1. 从一块芯片说起LT9611EX到底能干什么第一次拿到LT9611EX这颗芯片的时候我盯着它的datasheet看了整整一个下午。原因很简单——手头有个高清播放器项目主控输出的只有MIPI DSI信号但客户要求必须出标准HDMI 1.4接口还得支持双屏异显。市面上常见的转换方案要么只支持单端口输入要么分辨率上不去要么对音频支持一塌糊涂。LT9611EX算是少数几个能把双端口MIPI DSI输入转HDMI 1.4输出这件事做利索的芯片。先把这颗芯片的定位说清楚。LT9611EX是Lontium龙迅推出的一款MIPI DSI/CSI到HDMI 1.4的桥接芯片支持两路独立的MIPI DSI输入端口可以配置成单端口高分辨率模式也可以配置成双端口模式做画面拼接或者双屏输出。HDMI输出端最高支持到1080p60Hz符合HDMI 1.4标准支持TMDS时钟最高148.5MHz。音频方面支持I2S和SPDIF输入可以嵌入到HDMI的音频通道里。这颗芯片适合谁用我总结下来主要是三类人一是做高清播放器、电视盒子、广告机这类产品的硬件工程师主控往往只有MIPI输出需要转成HDMI去驱动大屏二是做FPGA视频处理的开发者FPGA输出MIPI DSI信号后需要转成HDMI做显示验证三是做嵌入式Linux驱动适配的软件工程师需要在系统层面把MIPI DSI的显示通路打通到HDMI。我这次的项目背景是一个基于Linux的高清播放器主控输出双路MIPI DSI一路接本地LCD屏做UI显示另一路通过LT9611EX转成HDMI输出到电视。整个链路涉及硬件设计、设备树配置、驱动适配、时序调试几个环节踩过的坑不少下面把完整的过程拆开来讲。2. 方案选型与整体架构设计2.1 为什么选LT9611EX而不是其他方案市面上做MIPI转HDMI的方案其实有好几种我大致对比过几类方案类型典型芯片优势劣势MIPI DSI转HDMILT9611EX双端口输入、支持音频、配置灵活需要I2C配置、时序调试有门槛MIPI DSI转RGB再转HDMI分离方案成本低链路长、信号质量差、占用PCB面积大主控直接输出HDMI换主控最简单主控选型受限、成本高FPGA做协议转换纯FPGA方案灵活开发周期长、功耗高选LT9611EX的核心理由有三个。第一它原生支持双端口MIPI DSI输入这意味着我可以用一颗芯片同时处理两路视频流不需要额外加一颗MIPI switch。第二它内置了HDMI 1.4的TMDS发送器不需要外挂HDMI编码芯片BOM成本可控。第三Lontium提供了比较完整的配置工具和参考代码虽然文档写得不算友好但至少能跑通。2.2 双端口MIPI的两种工作模式LT9611EX的双端口MIPI输入有两种典型用法这个在选型阶段就要想清楚模式一单端口高分辨率模式。把两路MIPI DSI的lane合并使用比如每路4 lane合并成8 lane来传输更高分辨率或者更高帧率的画面。这种模式适合需要4K输入但输出还是1080p的场景实际上是在输入端做带宽扩展。模式二双端口独立模式。两路MIPI DSI各自独立工作芯片内部做画面拼接或者选择其中一路输出到HDMI。我这次用的是这种模式因为主控的两路MIPI一路给LCD一路给HDMI互不干扰。这里有个关键点要注意双端口独立模式下两路MIPI的时序参数像素时钟、H/V同步、前后肩必须分别配置不能共用一套参数。我在初期调试时就犯过这个错误把LCD那路的时序参数直接复制到HDMI那路结果HDMI输出花屏查了两天才发现是时序不匹配。2.3 整体硬件链路整个链路的信号流向是这样的主控Linux平台→ MIPI DSI TX → LT9611EX MIPI RX → 内部视频处理 → HDMI TX → 电视/显示器控制通路是主控 I2C → LT9611EX 寄存器配置音频通路是主控 I2S → LT9611EX I2S RX → 嵌入HDMI音频通道电源部分需要三路1.2V核心电压、1.8V MIPI IO电压、3.3V HDMI IO电压。这里提醒一句LT9611EX对电源上电顺序有要求一般是1.2V先上然后1.8V最后3.3V。如果顺序反了芯片可能不工作或者I2C通信异常。我在第一版硬件上就吃了这个亏后来加了一颗电源时序控制芯片才解决。3. 核心寄存器配置与时序参数计算3.1 LT9611EX的寄存器架构LT9611EX的寄存器空间通过I2C访问7位从机地址默认是0x3B具体以datasheet为准不同批次可能有差异。寄存器大致分几个区域系统控制区芯片复位、时钟使能、电源管理MIPI RX配置区lane数、数据速率、时序参数视频处理区色彩空间转换、缩放、拼接HDMI TX配置区TMDS时钟、音频嵌入、HDCP中断与状态区热插拔检测、信号锁定状态配置的基本流程是先复位芯片然后配置MIPI RX参数再配置视频通路最后配置HDMI TX并启动输出。3.2 MIPI DSI时序参数的计算这是整个项目里最容易出错的地方。MIPI DSI的时序参数包括像素时钟、水平同步、垂直同步、前后肩这些参数必须和主控输出的时序完全一致否则LT9611EX锁不住信号。以1080p60Hz为例标准时序参数是像素时钟148.5MHz水平总周期2200像素有效1920 前肩88 同步44 后肩148垂直总周期1125行有效1080 前肩4 同步5 后肩36但MIPI DSI传输的不是像素时钟而是以lane速率传输的字节流。计算lane速率的公式是lane速率 像素时钟 × 每像素bit数 / lane数对于RGB88824bit每像素4 lane配置lane速率 148.5MHz × 24 / 4 891Mbps这个891Mbps就是每lane的数据速率配置LT9611EX的MIPI RX时需要把这个值写进对应的寄存器。实际配置时还要考虑MIPI DSI的协议开销一般会留10%到20%的余量。3.3 关键配置代码解析下面是我实际使用的初始化代码片段基于I2C接口用C语言写的。这段代码在Linux内核态和用户态都能跑我是在驱动probe阶段调用的。#include linux/i2c.h #include linux/delay.h #define LT9611EX_I2C_ADDR 0x3B /* 寄存器地址定义 */ #define REG_SYS_CTRL 0x0000 #define REG_MIPI_RX_CTRL 0x0100 #define REG_VIDEO_CTRL 0x0200 #define REG_HDMI_TX_CTRL 0x0300 static int lt9611ex_write_reg(struct i2c_client *client, u16 reg, u8 val) { u8 buf[3]; buf[0] (reg 8) 0xFF; buf[1] reg 0xFF; buf[2] val; return i2c_master_send(client, buf, 3); } static int lt9611ex_init(struct i2c_client *client) { int ret; /* 1. 软复位 */ ret lt9611ex_write_reg(client, REG_SYS_CTRL, 0x01); if (ret 0) return ret; msleep(10); /* 2. 配置MIPI RX4 lane891Mbps */ lt9611ex_write_reg(client, REG_MIPI_RX_CTRL 0x00, 0x04); /* lane数 */ lt9611ex_write_reg(client, REG_MIPI_RX_CTRL 0x01, 0x03); /* 速率档位 */ lt9611ex_write_reg(client, REG_MIPI_RX_CTRL 0x02, 0x01); /* 连续时钟模式 */ /* 3. 配置视频通路RGB8881080p */ lt9611ex_write_reg(client, REG_VIDEO_CTRL 0x00, 0x18); /* 24bit */ lt9611ex_write_reg(client, REG_VIDEO_CTRL 0x01, 0x01); /* 端口选择 */ /* 4. 配置HDMI TX */ lt9611ex_write_reg(client, REG_HDMI_TX_CTRL 0x00, 0x01); /* 使能输出 */ lt9611ex_write_reg(client, REG_HDMI_TX_CTRL 0x01, 0x00); /* 音频关闭 */ /* 5. 等待信号锁定 */ msleep(100); return 0; }这段代码看起来简单但有几个细节值得展开说。第一寄存器地址是16位的I2C传输时需要先发高字节再发低字节。我见过有人只发8位地址结果配置全部写到错误的寄存器上芯片完全没反应。第二软复位后必须延时至少10ms等内部PLL稳定。这个延时不能省我试过用1ms结果后续配置偶尔失败改成10ms后就稳定了。第三MIPI RX的速率档位寄存器不是直接写速率值而是写一个档位编码。具体编码对应关系要查datasheet的表格不同版本的datasheet可能不一样。3.4 双端口配置的差异点双端口模式下两路MIPI RX需要分别配置。LT9611EX的寄存器设计是端口0和端口1各有一套配置寄存器地址偏移不同。我在代码里用了一个结构体来管理两路配置struct lt9611ex_port_cfg { u8 lane_num; u8 speed_level; u16 h_active; u16 h_front_porch; u16 h_sync; u16 h_back_porch; u16 v_active; u16 v_front_porch; u16 v_sync; u16 v_back_porch; }; static struct lt9611ex_port_cfg port_cfg[2] { { /* 端口0接LCD */ .lane_num 4, .speed_level 0x03, .h_active 1920, .h_front_porch 88, .h_sync 44, .h_back_porch 148, .v_active 1080, .v_front_porch 4, .v_sync 5, .v_back_porch 36, }, { /* 端口1接HDMI */ .lane_num 4, .speed_level 0x03, .h_active 1920, .h_front_porch 88, .h_sync 44, .h_back_porch 148, .v_active 1080, .v_front_porch 4, .v_sync 5, .v_back_porch 36, }, };实际项目中两路时序可能不同比如LCD是竖屏1080x1920HDMI是横屏1920x1080这时候两套参数就要分别计算。我遇到过一个坑主控输出的MIPI DSI在竖屏模式下H/V参数是互换的配置LT9611EX时如果直接按横屏参数写画面会旋转90度。解决办法是在视频处理区做旋转配置或者让主控输出时就做好旋转。4. 实操过程从硬件上电到画面点亮4.1 硬件检查清单在写代码之前硬件层面必须先确认几件事否则软件调死也出不来画面电源电压和上电顺序用示波器确认1.2V、1.8V、3.3V的上电顺序和上升时间。LT9611EX要求1.2V先于1.8V1.8V先于3.3V间隔至少1ms。I2C通信用i2c-tools扫描总线确认能读到0x3B地址。如果读不到先查上拉电阻一般4.7kΩ和电源。MIPI差分线用示波器看MIPI时钟lane的波形确认有信号输出。MIPI是差分信号幅度一般在200mV左右共模电压1.2V。HDMI热插拔检测确认HPD信号能正常拉高否则LT9611EX不会启动HDMI输出。我第一版硬件上I2C死活读不到芯片查了半天发现是1.8V电源的上电时间比1.2V早了芯片内部逻辑锁死。后来加了一颗简单的RC延时电路把1.8V的使能信号延后了5ms问题解决。4.2 设备树配置在Linux平台下LT9611EX通常作为I2C从设备挂在总线上同时它的HDMI输出端可能需要一个GPIO来控制使能。设备树节点大概长这样i2c1 { status okay; clock-frequency 400000; lt9611ex: lt9611ex3b { compatible lontium,lt9611ex; reg 0x3b; reset-gpios gpio1 12 GPIO_ACTIVE_LOW; enable-gpios gpio1 13 GPIO_ACTIVE_HIGH; interrupt-parent gpio1; interrupts 14 IRQ_TYPE_EDGE_FALLING; status okay; port { lt9611ex_in: endpoint { remote-endpoint mipi_dsi_out; >