板子焊好了,FPC排线插上,背光电源打开,屏幕上什么都没有。这是大多数人第一次点屏的真实状态:电压表量了一遍,该有的电压都有,背光也亮着,但屏就是黑的。你翻出面板手册,看到MIPI-DSI、Lane、HS/LP、EoTp、DCS这些词,越翻越懵,最后只能对着设备树里那几个时序参数发呆。
这篇就是给刚接触屏幕点亮的工程师准备的。MIPI-DSI 是现在手机屏、平板屏、车机屏最主流的高速显示接口,不管你是用全志 T113-i、瑞芯微还是其他国产 SoC,只要想把一块 MIPI 屏点亮,就得把它的物理层、协议层和时序计算搞明白。我会结合实际点屏过程中踩过的坑,把 DSI 从走线到协议到 DTS 配置一次讲透,尽量让读完的人能直接上手,而不是只会抄配置。
1. 为什么点屏绕不开MIPI-DSI:一块屏幕从上电到出画面的信号旅途
1.1 从“屏幕为什么亮”说起:显示链路中的DSI角色
我们常说的“点屏”,其实是一整套信号链路的协同工作。以 T113-i 这类 SoC 为例,画面从系统里出来,不是直接把 RGB 数据扔到屏上就行,中间要经过好几道工序:
- 显示控制器(Display Controller / DE)负责把图层合成好,得到一帧完整的画面;
- 时序控制器(TCON)负责按面板需要的行场同步时序,把像素点一个一个排好队;
- DSI Controller 把排好队的 RGB 数据打包成 DSI 协议包,并负责跟面板初始化和握手;
- D-PHY 物理层把协议包变成高速差分信号,经过 PCB 走线和排线送到屏幕;
- 屏幕端的 COG/COF 封装里有一颗驱动 IC,把差分信号解包、恢复成面板内部的 RGB 像素数据,再驱动液晶单元翻转。
所以你会发现,点亮一块 MIPI 屏,本质上是两件事:第一,给屏幕正确的上电和复位时序;第二,通过 DSI 总线把初始化代码(init code)写进面板驱动 IC,并且持续地送像素数据。
很多人第一次点屏失败,就是只关注了设备树里那几个时序参数,根本没理解 HFP、HBP、lane 这些概念在信号链路上的位置。等你吃过几次亏,把这些关系串起来了,配置和排查才会变得有方向。
1.2 MIPI联盟与DSI标准:不是一个公司的私有规约
MIPI(Mobile Industry Processor Interface)不是某个芯片厂的私有协议,而是移动行业处理器接口联盟制定的一整套标准。我们常说的 MIPI-DSI,全称 Display Serial Interface,是这个标准里用于显示屏通信的部分。它下面又分了物理层(D-PHY)、协议层(DSI Protocol)、以及控制命令集(DCS)。
早期手机屏幕多用并行 RGB 接口,数据线多、焊接面积大、干扰问题严重,频率一高就走不远。MIPI-DSI 用一对时钟差分线加若干对数据差分线,就把原来几十根线的活干完了,而且速率可以做到单 lane 几百 Mbps 甚至 1Gbps 级别。这也是为什么手机、平板、车机里的屏幕几乎全是 MIPI 屏,因为只有差分串行接口才能在窄排线里跑高分辨率高刷新率。
T113-i 这颗 SoC 同时保留了 RGB、LVDS、MIPI-DSI 三种显示接口,就是为了兼容不同的面板生态:小尺寸可以直接 RGB,中尺寸工控屏可能更爱 LVDS,而消费类面板和车机中控则几乎都是 DSI。搞清楚 DSI,等于打通了屏幕生态的主流方向。
1.3 RGB、LVDS、eDP、DSI:不同接口的选型逻辑
新手经常分不清这些接口,我简单用一张表把几个常见显示接口的特点放一起:
| 接口类型 | 信号线数量 | 典型速率 | 常见应用场景 |
|---|---|---|---|
| 并行 RGB | 几十根(RGB数据线+时钟+同步) | 几十 MHz 像素时钟 | 4.3 寸以下小屏、低分辨率 |
| LVDS | 4~8 对差分线 | 单通道几百 Mbps | 10~17 寸工控/车载屏 |
| MIPI-DSI | 1 对时钟 + 1~4 对数据 | 单 lane 约 800Mbps~1Gbps | 手机、平板、车机、消费类面板 |
| eDP | 多对差分线 + AUX 辅助通道 | 高速 | 笔记本、2K/4K 高分辨率屏 |
选哪个接口,主要看分辨率、刷新率和面板供应链。MIPI-DSI 的优势是线少、速率高、生态庞大;缺点是需要严格做差分等长和协议初始化,不像 RGB 那样直接给像素时钟画面就能出来。
2. MIPI-DSI物理层到底有哪些线:一组时钟,一到四对数据
2.1 差分对与Lane概念
DSI 物理层的核心是“差分信号”。一对差分线就代表一个 lane,信号线上是两个互为反向的电压,接收端通过比较两条线的差值来判断 0 还是 1。这样抗共模干扰能力很强,适合高速传输。
一个 DSI 接口由两类 lane 组成:
- 时钟 lane:CLK_P / CLK_N,只能是一对,负责给数据 lane 提供双倍速率(DDR)时钟;
- 数据 lane:D0_P / D0_N、D1_P/D1_N,最多四对,负责搬运像素数据和控制命令。
注意这里的“lane”不是“channel”。每个数据 lane 在同一时刻传一套数据流,四 lane 就等于四路并行搬运。时钟 lane 是源同步,面板端必须靠它来采样数据,所以无论如何都不能省。手动焊接排线的时候,最容易踩的坑就是把某个 lane 的正负焊反或者焊短路,这会直接导致通信失败,画面一点都没有。
2.2 选2-lane还是4-lane:先算带宽再定走线
很多人拿到板子才开始想“我的屏是几 lane 的”,这是顺序反了。正确顺序是先看分辨率需要的带宽,再决定 lane 数,最后定 PCB 走线和设备树配置。
- 480x800、540x960 这类分辨率,2 lane 通常就够;
- 720p、768p 以及 1024x600 这类,推荐 4 lane 留足余量;
- 1080p 以上,4 lane 是最低门槛,还要盯紧每 lane 速率别超过物理层规格。
lane 数在通信时必须跟板子实际走线一致。你设备树配了 4 lane,但 FPC 排线实际走了 2 lane,或者反过来,都会出现点不亮或花屏。做硬件时建议把 lane 数和极性核对清楚,软件侧也要有对应的 DTS 配置入口。
2.3 电源、复位、背光、触摸:屏幕要亮的完整引脚清单
只盯着差分线是不够的。屏幕能亮,得先把这些辅助信号理顺:
- VDD / VCI:屏幕主供电,常见 2.8V~3.3V,给驱动 IC 内部逻辑供电;
- IOVCC:IO 电平供电,通常 1.8V 或 3.3V,必须和主控 MIPI IO 电平匹配;
- VLED+ / VLED-:背光 LED 供电,走的是升压背光电路,和逻辑供电完全分开;
- RESET:复位引脚,低有效;必须按屏幕规格书要求的时序拉低再拉高;
- BL_EN / PWM:背光使能和亮度控制,有时在背光驱动芯片上,不在排线里;
- I2C:部分屏幕的触控、ID 读取或部分寄存器回读功能会挂在 I2C 上,点屏时虽然不用它,但联调时常常是因为 I2C 地址冲突翻车。
上电顺序是很多人忽略的硬指标。大多数屏幕要求先上 IOVCC,再上 VDD,等电压稳定后拉 RESET,最后才允许背光亮。如果你背光先亮了,屏可能长时间处于异常工作状态,轻则画面闪烁,重则初始化失败。具体以面板手册的上电时序图(Power On Sequence)为准,别凭感觉拍脑袋。
2.4 排线、阻抗与接地的工程细节
说个实话:很多屏幕点不亮,一半原因是时序,另一半是物理连接。DSI 是高速差分传输,对走线阻抗有明确要求。PCB 上通常做 100Ω 差分阻抗,但开发板到屏幕经常靠 FPC 排线连接,排线长了、折叠了、屏蔽层浮空,信号质量就会下降。
你可以用示波器在屏幕端的排线连接器上抓 HS 波形。如果幅度明显偏低、边沿圆滑、眼图接近关闭,那基本就是走线和接触问题,而不是软件配置问题。另外 GND 不要省,差分线旁边多走地,可以减少串扰。排线插好之后用手压一下,如果画面从花变清晰,那必然是接触不良。
3. 协议层到底怎么传数据:HS/LP、数据包和两种视频模式
3.1 HS与LP两种物理状态
学过 MIPI-DSI 的人都知道,链路上有 High-Speed(HS)和 Low-Power(LP)两种状态。HS 是高速传输状态,摆幅很低、速率很高,用来搬像素数据和大量初始化参数;LP 是低功耗状态,信号幅度接近IO电压,速率很慢,用来做总线协议协商、命令响应等低频操作。
很多时候你拿示波器抓排线,会看到数据 lane 上有很长一段没有波形,然后突然冒出一串高速脉冲,这就是 LP 状态切到 HS 状态的过程。DSI 的数据 lane 在进入 HS 突发传输前,需要一段特定的建立序列(LP-111、LP-001、LP-000、HS-0),接收端靠这个序列完成同步。理解这个状态切换,对调试“为什么初始化命令没生效”很有帮助——比如你把命令发在了一个根本还没建立 HS 链路的阶段,面板当然不会理你。
3.2 数据包与DCS命令:init code在总线上长什么样
DSI 协议层不是把像素裸数据直接扔到线上,而是封装成包。包有短包和长包两种:
- 短包:4 字节,由数据标识符、参数或命令、ECC 校验组成,适合发单参数命令;
- 长包:由 4 字节包头、可变长度负载、2 字节 CRC 校验组成,适合发初始化参数或多字节配置。
我们平时从屏幕厂拿到的 init code,实际上就是一堆 DCS 命令。比如常见的:
| 命令 | 含义 | 说明 |
|---|---|---|
| 0x01 | SOFT_RESET | 软复位,之后必须延时几毫秒 |
| 0x11 | SLEEP_OUT | 睡眠退出,之后必须延时 120ms 左右 |
| 0x36 | SET_ADDRESS_MODE | 设置扫描方向和 RBG 顺序 |
| 0x3A | SET_PIXEL_FORMAT | 设置像素格式,比如 0x77 对应 RGB888 |
| 0x29 | SET_DISPLAY_ON | 打开显示 |
转换到总线上时,0x11 这种无参数命令会以短包发送,0x3A 0x77 这种带参数命令会以短包带参数发送,而一长串厂商私有寄存器配置则是长包。你配置设备树时填的 init sequence,就是这些命令加上延时,驱动会负责打包成 DSI 包发出去。
init code 的顺序和延时非常关键。比如 0x11 睡眠退出后,有些屏要求等 120ms 再发后续命令;你延时写短了,屏幕可能挂起或者白屏。这不是什么高深原理,就是按规格书的时间要求来。
3.3 Video Mode与Command Mode怎么选
DSI 协议层有两种工作模式,对点屏配置影响很大:
- Command Mode(命令模式):屏幕自带 GRAM,主机把一帧数据写进去,面板自己刷新。好处是静态画面功耗小,适合需要省电的场景;但需要防止撕裂(tearing),通常要加 TE 同步信号。
- Video Mode(视频模式):主机像播放电视信号一样,按行和帧的节奏,持续把像素数据推给屏幕,屏幕没有完整帧内存,必须实时显示。
对于 Linux 平台做 Display/KMS 驱动,绝大多数人用的都是 Video Mode。因为它更符合“主机持续刷帧”的模型,时序也好理解:主机按像素时钟把一行行像素推出去,屏幕按行场同步信号拼接出画面。
如果你拿到的是 Command Mode 屏,就要额外处理 TE、刷新区域等逻辑,复杂度高不少,菜鸟不建议一开始就挑战这种屏。
4. 点亮屏幕之前的计算题:时钟频率与时序参数怎么定
4.1 速率怎么算:像素时钟、DSI总带宽与单lane速率
点屏之前,第一道计算题是确定 DSI 时钟跑多快。公式可以拆成三步:
- 先算像素时钟(PCLK):PCLK = (Hactive + HFP + HBP + HSYNC) × (Vactive + VFP + VBP + VSYNC) × 刷新率;
- 再把像素时钟换算成 DSI 总比特率:DSI总速率 = PCLK × 像素位数;
- 最后除以 lane 数,得到单 lane 比特率。
举个 1024x600 60Hz 的例子。假设时序参数为 Hactive=1024、HFP=160、HBP=160、HSYNC=20,Vactive=600、VFP=20、VBP=20、VSYNC=8:
- Htotal = 1024 + 160 + 160 + 20 = 1364;
- Vtotal = 600 + 20 + 20 + 8 = 648;
- PCLK = 1364 × 648 × 60 ≈ 53.0MHz;
- DSI总速率 = 53.0MHz × 24bit = 1.27Gbps;
- 如果走 4 lane,单 lane ≈ 318Mbps。
这个速度在 D-PHY v1.0 的单 lane 1Gbps 上限面前是相当保守的,所以这种分辨率用 4 lane 很稳。
再看 1080p 60Hz 的例子。Hactive=1920、Vactive=1080,加上典型空白区后 Htotal ≈ 2200、Vtotal ≈ 1125:
- PCLK ≈ 148.5MHz;
- DSI总速率 = 148.5MHz × 24bit = 3.56Gbps;
- 4 lane = 890Mbps 单 lane。
890Mbps 已经贴着 1Gbps 的上限了,还要留连接器、排线、PCB 的损耗余量,实际点起来容易出花屏、闪屏。这就是为什么 1080p 屏对 PCB 设计、排线质量要求明显更高。
4.2 屏幕规格书中的时序参数如何映射到设备树
面板规格书最后一页或倒数几页通常有个“Display Timing Table”,里面是 HFP、HBP、HSYNC、VFP、VBP、VSYNC、刷新率这些值。这些参数在设备树里直接填到 display-timings 节点即可。
比较常见的是这种结构:
display-timings { timing0 { clock-frequency = <53000000>; hactive = <1024>; vactive = <600>; hback-porch = <160>; hfront-porch = <160>; hsync-len = <20>; vback-porch = <20>; vfront-porch = <20>; vsync-len = <8>; }; };这里最容易犯的错是把 RGB 接口的时序参数直接抄成 DSI 的。DSI 屏在 Video Mode 下,主机按这些参数产生同步信号和空白区,但两侧的 blanking 会被 MIPI 包的 blanking packet 或者短包替代,不同面板驱动对空白包格式的处理有差异。如果你照搬一套其他平台的 RGB 屏参数而没确认面板支持,很可能会出现画面偏移、右侧切边。
4.3 留余量与时钟源约束:一个“算好却能翻车”的地方
计算只是第一步,实际还要留余量。我自己的习惯是让单 lane 速率不要超过物理层实际稳定能力的 80%。比如 D-PHY 标称 1Gbps,我一般按 800~900Mbps 去规划,因为排线损耗、阻抗偏差、连接器接触电阻都会吃掉余量。
再一个坑是时钟源。主控 DSI 时钟是由外部晶振经过 PLL 分频得到的,不是你想配多少就配多少。T113-i 这类平台通常以 24MHz 晶振为参考,最终 DSI 时钟是 PLL 链路里可整除的值。如果你算出来需要 148.5MHz,但实际 PLL 只能出 145MHz 或者 150MHz,会带来细微的刷新率偏差和轻微闪烁。解决办法是查 SoC 手册里的时钟树,选一个可整除且最接近目标值的配置;全志的 BSP 里一般有对应的时钟计算工具或说明文档。
5. T113-i平台点屏配置链路全流程与DTS写法
5.1 DTS结构:从dsi节点到panel节点的依赖关系
T113-i 的显示子系统里,DSI 控制器、TCON、显示控制器是分层的。对应到设备树,通常是一个 dsi 节点,里面挂 panel 子节点,由 panel 节点描述屏幕参数和初始化序列。
结构大概长这样(不同内核版本属性名会有差异,以你拿到的 BSP 为准):
&dsi { status = "okay"; lanes = <4>; clock-frequency = <500000000>; panel@0 { compatible = "some-vendor,generic-dsi-panel"; reg = <0>; status = "okay"; reset-gpios = <&pio 1 5 GPIO_ACTIVE_HIGH>; backlight = <&backlight>; display-timings { timing0 { clock-frequency = <53000000>; hactive = <1024>; vactive = <600>; hback-porch = <160>; hfront-porch = <160>; hsync-len = <20>; vback-porch = <20>; vfront-porch = <20>; vsync-len = <8>; }; }; }; };注意几个关键点:reset-gpios 要确实是屏幕排线上的 RESET 引脚,别接到无关 GPIO;backlight 节点要确实是控制背光的 PWM 设备。偶尔有人 reset 接错引脚还查半天找不出是通信问题还是电源问题。
5.2 init code的三种来源与转换方式
init code 的获取主要有三种途径:
- 屏幕厂 FAE 直接给:一份 C 数组或 xlsx 表格,这是最省事的;
- 从其他平台 BSP 里抄:比如瑞芯微或全志其他芯片的 dts/dtsi,系统里已经有了现成命令序列;
- 自己根据规格书写:针对少见屏,需要一点点根据手册里的寄存器描述和厂商建议来拼命令。
不管是哪种来源,最终都要编程平台能识别的格式。比如厂商给的是这种序列:
0x01, 0x00 // 软复位 dlay 20 0x11, 0x00 // 睡眠退出 dlay 120 0x3A, 0x77 // RGB888 0x36, 0x00 // 扫描方向你就得在 DTS 或平台的 lcd 配置里对应写成带延时的序列。不同平台格式不同,有的用数组,有的用宏展开。转换时最容易丢的就是延时,很多人只抄命令没抄延时,屏幕死活初始化不起来。
平台驱动发这些命令时,会自动把命令封装成 DSI 包,你不需要手动算包尾 CRC。但要注意,命令表里的 0x00 有时是“不关心”字节,有时表示 8bit 长度,必须按屏幕手册区分。
5.3 驱动侧的几个关键时序:复位、背光与init顺序
复位时序是高频翻车点。常见面板要求 RESET 拉低至少 10us,然后拉高,等待 120ms 左右再发命令。如果你的驱动没有按照这个顺序做,或者复位信号跟电源上电重叠,面板可能一直处于复位状态,命令发不进去。
背光 PWM 频率也要留个心眼。太低的 PWM(比如 200Hz)在部分人耳下能听到电感啸叫,太高又有可能干扰触摸采样。T113-i 这类平台的背光 PWM 一般可配,我常用 1kHz 到 20kHz 之间,具体取决于背光芯片的工作模式。
init 顺序上有个经验:上电后先等电源稳定,再复位,再发 sleep_out 并等够延时,最后打开显示。这条链路别乱顺序,否则可能出现“点亮一瞬间然后灭掉”的诡异现象。
5.4 T113-i上实测时的“小脾气”
全志平台点屏时有三点值得注意:
- 启动阶段和内核阶段要一致:uboot 阶段也会初始化显示,如果 uboot 和内核里配置的时序、时钟不一致,会出现启动 logo 正常,进入内核后屏幕闪一下黑掉的情况。排查时务必把两个阶段的配置都检查一遍。
- 别热插拔排线:DSI 通信中拔插排线,链路直接挂死是家常便饭,很多面板热插拔后必须整机断电才能恢复。
- 回读功能能帮你验证:部分面板支持 BTA,可以回读寄存器判断命令是否生效。虽然很多屏不支持,但支持的话这是排查 initial code 是否写进去的利器。
6. 屏幕点不亮的高频问题和排查路径
6.1 黑屏:把信号链分四段量一遍
如果整机都亮了,只有屏幕黑屏,不要急着猜,按下面顺序一段一段查:
- 供电段:万用表测 VDD、IOVCC 电压是否正常、纹波是否大;再查背光电压有没有起来;
- 背光段:BL_EN 有没有信号,PWM 有没有频率输出;背光亮不代表屏已经开始工作,只代表背光电路正常;
- 通信段:示波器抓 CLK 和 D0~D3,看有没有高速 burst 波形。CLK 有波形但数据 lane 没有,多半是 lane 配置或初始化命令没发出来;
- 配置段:内核日志看 DSI panel 是否 probe 成功,显示控制器是不是在持续刷帧。
有个经常被忽视的点:屏幕背光正常、电压正常,但 DSI 总线上完全没波形。这时候优先查 reset 引脚和手写 init code 里的延时,很多情况是面板还没 ready,主机已经往下走了,所以总线上啥都没有。
6.2 花屏、条纹、缺色和闪屏的定位思路
不同故障现象对应不同的根因,我整理了一张表方便对照:
| 故障现象 | 可能原因 | 优先检查项 |
|---|---|---|
| 全屏花屏、乱码 | lane 数不匹配、时钟频率不够 | DTS 里的 lanes 与硬件是否一致;降低 PCLK 试试 |
| 水平条纹或滚动 | 行同步或时序参数不对 | 逐一核对 HFP/HBP/HSYNC |
| 屏幕偏色、缺红色或蓝色 | 像素格式不匹配 | RGB888/RGB666 是否和面板一致;0x36 方向和 RGB 顺序 |
| 画面闪、水波纹 | 刷新率不够、时钟余量不足 | 提高 PCLK 或降低屏参里的空白区 |
| 屏幕亮一下马上灭 | 复位时序或 init sequence 延时不够 | 检查 reset 和 sleep_out 延时 |
| 右侧画面被切掉 | HFP/HBP 配错或 DSI blanking 处理不对 | 对照面板手册微调 HBP |
如果你是一帧像花屏,一帧像正常,那大概率不是时序而是 DDR 带宽不足。预留显示缓存带宽被其他任务抢走时,TCON 取不到数据就会出现偶发花屏,这在 1080p 屏上更容易发生。
6.3 给新人的点屏检查清单
最后把流程整理成一张实操清单,按顺序执行可以省掉大量盲目排查时间:
- 确认屏幕供电电压和极性,万用表逐脚量一遍,不要只看灯亮就以为供电正常;
- 确认 RESET 引脚接到主控上,并且驱动在 init 前完成了正确的复位时序;
- 核对 DSI lane 数:板子实际几对线,DTS 就配几个;
- 核对时序表:每个数值写在规格书里就有出处,不要凭感觉改大;
- 降低时钟余量:如果按计算值点不亮,先降到 70%~80% 速率试试,排除高速损耗问题;
- 从 uboot 阶段试点亮:绕开内核框架问题,先确任裸机阶段画面能不能出来;
- 换一块确认正常的屏幕排除面板坏点;
- 做好备份:每调一版参数都保存现场,不然改乱了没法回退。
我在 T113-i 上点过各式各样的屏,最深的体会永远是:屏幕手册里的时序表和初始化命令才是唯一的“事实来源”。厂家给的参考平台代码可以帮你省时间,但落到你手头的主控平台时,时钟树、lane 数、复位引脚这些都变了,照抄一把梭多半要翻车。老老实实逐项核对,花不了多少时间,但能让你少开除一块“假坏”的屏幕。希望这篇能把你的第一块 DSI 屏点起来。