简介:面向视频处理与硬件接口设计学习者的一份 DisplayPort 技术整理文档,围绕 DP 接口介绍及原理图、PCB layout 资料汇总需求,适合需要系统了解协议、接口形态与硬件设计要点的工程师及学生参考。文档从接口简介与标准、Mini-DP 分类切入,逐项梳理 DP 1.0 至 2.0 的带宽演进与版本差异,并解释 MST 多流传输、DSC 压缩、HDR、微报文与多通道传输等关键概念,帮助读者理解 4K/8K 高分辨率显示背后的协议机制。设计部分覆盖 DP 输出与接收链路、信号发生、均衡解码及时钟恢复,测试部分提到眼图、I2C、兼容性与性能验证,便于把协议知识与硬件实现、调试场景对应起来。压缩包内为 1 个 docx 文件,大小约 1.93MB,目录层级清晰,可作为接口知识速查和设计测试入门笔记。已有 5737 人学习,说明其在显示接口学习场景中具有一定参考价值。
1. 一根时钟线都没有的显示接口,凭什么越做越快
把一根 DP 线插上、屏幕亮起来,这件事平淡得像呼吸,但它底下踩着一个反直觉的设计:DisplayPort 的 20 个引脚里,一根专用时钟线都没有。四对差分对全是数据,像素时钟是接收端自己从比特流里“抠”出来的。更反直觉的是插上显示器之后的那两三百毫秒——源端和屏之间已经通过一条 1 Mbit/s 的半双工 AUX 通道来回读写上百次寄存器,把 lane 数、链路速率、电压摆幅、预加重一档档试出来。我整理这份 DP 接口介绍加原理图与 PCB layout 资料的过程里,版本对照表反而是最不值钱的部分,真正难的是把这些看不见的握手摊开:为什么隔直电容必须落在驱动端,为什么 AUX 幅值差一点整条链路就训练不过,为什么视频处理链路里宁可多贴一颗链路调理芯片。搞懂这些,layout 时才知道哪些线不能将就。
2. 微报文主链路:DP 为什么敢不给你一根时钟线
早期的数字显示接口把“时序”当成物理层的事来处理:每个通道在固定的时隙里塞固定的东西,像素来了就发像素,行场同步来了就发同步码,彼此靠一根额外的时钟线对齐。这套做法简单、硬件便宜,代价是通道的用途被焊死了——你没法在同一个连接器上,既不换线又不换座子地塞进新东西。DisplayPort 从 2006 年第一版就把这个前提拆了,它赌的是另一条路:把定时信号也变成数据。
2.1 从固定时隙到微报文:定时信号怎么被塞进数据流
DP 的主链路传的是“微报文”(micro-packet)。源端把视频像素、行场定时信息、音频样本、附加数据统统切成小包,按流的方式发出去,接收端再按包头里的时间戳把它们重新拼回一条连续的像素流。这一步看起来只是软件层面的封装,实际影响的是整条链路的物理结构:既然定时信息在包里面,物理层就不需要为它留专用通道,四对差分线可以全部用来搬数据。
这个选择带来三个连锁好处,理解它们比记住版本号有用得多。
第一是引脚数。标准 DP 连接器 20 个引脚,主链路占 4 对差分(8 根),AUX 占 1 对(2 根),HPD 一根,电源和地若干,剩下的留给配置引脚。对比同代需要独立时钟通道的接口,省下来的引脚可以换成更多的数据 lane,或者干脆把连接器做小——Mini-DP 就是这么来的,2008 年由某消费电子厂商推上笔记本,外形缩了一圈,电气规格和标准 DP 完全一致。
第二是可扩展。因为功能是靠“包”承载的,新增能力只要定义新的包类型,物理连接器本身不用动。DP 从 1.0 一路加到 2.0,连接器形状和引脚定义基本没变,这在消费电子里是极罕见的稳定性。
第三是 lane 数量可裁剪。主链路可以是 1、2 或 4 对差分,源端和接收端在握手阶段协商。这意味着一颗低成本芯片可以只做 2 lane,用一半的引脚和一半的功耗去驱动一块 1080p 屏;高端显卡插满 4 lane 跑 8K。同一个协议,从嵌入式模组到桌面显卡都能覆盖。
代价也很实在:接收端必须自己恢复时钟。这就是后面 8b/10b 和 128b/132b 存在的理由。
2.2 8b/10b 的自定时机制与 20% 开销去了哪
差分线上跑的是一串比特,接收端要从中提取时钟,前提是信号里有足够密的电平跳变,而且长期来看直流分量要平衡——否则耦合电容会被单向的电荷顶偏,眼图直接闭合。8b/10b 编码解决的就是这两件事:每 8 位有效数据映射成 10 位符号,映射表保证任意符号流里 0 和 1 的数量大致均衡,同时不会出现太长的连续相同电平。接收端的 CDR(时钟数据恢复)电路就靠这些跳变沿锁相,把时钟“榨”出来。DP 规范里明确写了时钟从 8b/10b 编码的数据流中提取,主链路没有专用时钟通道。
这笔账很好算:每 lane 每个符号周期传 8 位有效数据,占用 10 个比特时间,效率 80%。原始码率 1.62、2.7、5.4 Gbit/s 对应到有效数据率就是 1.296、2.16、4.32 Gbit/s。4 lane 全开,DP 1.0 的 10.8 Gbps 总带宽能落下 8.64 Gbit/s 的有效载荷;DP 1.2 的 21.6 Gbps 落下 17.28 Gbit/s。
# 反推一条 DP 链路够不够跑某个显示模式 # 单位统一用 Gbit/s,避免在计算里来回换数量级 LANE_RATE = {"RBR": 1.62, "HBR": 2.70, "HBR2": 5.40, "HBR3": 8.10} # 单 lane 原始码率 ENC_8B10B = 10 / 8 # 8b/10b 编码开销:8 bit 有效数据要占 10 bit 带宽 def usable(lane_rate_name, lanes): """返回有效数据率(Gbit/s),已扣掉编码开销""" return LANE_RATE[lane_rate_name] * lanes / ENC_8B10B def check(width, height, refresh, bpp=24, blanking=1.15, rate="HBR2", lanes=4): # blanking 是行场消隐带来的额外开销,CVT-RB 时序大约 1.05~1.10, # 传统 CVT 能到 1.25 以上,这里取 1.15 做保守估计 pixel_clk = width * height * refresh * blanking # 像素率,单位 Hz payload = pixel_clk * bpp / 1e9 # 需要的有效数据率 capacity = usable(rate, lanes) return round(pixel_clk / 1e6, 1), round(payload, 2), round(capacity, 2), capacity >= payload for mode in [(1920, 1080, 60), (2560, 1440, 60), (3840, 2160, 60), (3840, 2160, 144)]: print(mode, check(*mode))上面这段只做一件事:把“分辨率 + 刷新率 + 色深”翻译成带宽需求,再和链路能力对撞。参数里最容易被忽略的是blanking,它不是常数,取决于时序标准;同一块 4K 屏,按 CVT-RB 算出来的像素率比传统 CVT 低两成,链路等级可能差一档。bpp也要按实际色深填,10 bpc 就是 30 位,不是 24。跑出来的结果里 4K60 8bpc 大约需要 13.7 Gbit/s 有效带宽,4 lane HBR2 的 17.28 Gbit/s 刚好留出余量给音频包和次级数据包——这也是 DP 1.2 被称作“4K 起步版本”的原因,它的 HBR2 相比 1.1a 把单 lane 速率翻了一倍。
2.3 128b/132b 与 FEC:DP 2.0 换编码换的是什么
8b/10b 的 20% 开销在低速率时代可以接受,到了要冲 80 Gbps 的时候,它就成了最大的浪费。DP 2.0 把编码换成 128b/132b,每 128 位有效数据只占 132 个比特时间,开销降到约 3.03%。总带宽 80 Gbps 落地成 77.37 Gbps 有效,这个数字和 8b/10b 时代“打八折”的直觉完全不同。
配套的还有两件事。一是 lane 速率档位扩到 UHBR 10 / 13.5 / 20,每 lane 10、13.5、20 Gbps,四档往下兼容 RBR 到 HBR3。二是前向错误纠正(FEC)——它在 DP 1.4 就随 DSC 一起进来了,逻辑是:一旦你开始用显示流压缩把 8K 塞进有限的带宽里,一个比特错误解压之后会扩散成一片马赛克,靠重传来不及,只能靠纠错码在接收端就地修。DP 1.4 的另一层思路是“带宽不变,靠压缩顶上”:总带宽还是 32.4 Gbps,但加了 DSC 1.2 之后能推 8K60,加 HDR meta 数据包之后能带高动态范围元数据,音频通道从 8 声道 192 kHz 扩到 32 声道 1536 kHz。
两条路线放在一起看就很清楚:1.4 是“在既有物理层上抠效率”,2.0 是“换物理层 + 换编码”。版本迭代表里那些分辨率数字只是结果,真正决定它们的是编码效率和 lane 速率这两根杠杆。
| 版本 | 单 lane 最高速率 | 最大总带宽 | 编码 | 有效数据率 | 典型能力 |
|---|---|---|---|---|---|
| 1.0 / 1.1a | 2.70 Gbit/s (HBR) | 10.80 Gbps | 8b/10b | 8.64 Gbps | 2560×1600 级 |
| 1.2 / 1.2a | 5.40 Gbit/s (HBR2) | 21.60 Gbps | 8b/10b | 17.28 Gbps | 4K60、MST、Adaptive-Sync |
| 1.3 | 8.10 Gbit/s (HBR3) | 32.40 Gbps | 8b/10b | 25.92 Gbps | 4K120、5K60、8K30 |
| 1.4 / 1.4a | 8.10 Gbit/s (HBR3) | 32.40 Gbps | 8b/10b | 25.92 Gbps | 加 DSC、FEC、HDR 元数据 |
| 2.0 | 20.0 Gbit/s (UHBR20) | 80.00 Gbps | 128b/132b | 77.37 Gbps | 16K60(DSC)、双屏 4K144 |
注意:DP 信号在电气层不兼容 DVI 和 HDMI。所谓“双模式 DP”是靠外部无源转接头,把 DP 的 LVDS 电平转成 TMDS,只支持单链路 DVI 或 HDMI 1.2/1.4;VGA 和双链路 DVI 必须有源转换器。设计时如果看到有人直接在连接器上飞线转 HDMI,那大概率是不懂这一层。
3. AUX 与链路训练:插上显示器的那 200 毫秒里发生了什么
主链路负责搬像素,但它什么时候开始搬、用几条 lane 搬、每条 lane 跑多快、摆幅多大,全部由一条慢得多的小通道决定。AUX 通道速率只有约 1 Mbit/s、半双工、交流耦合差分,却是整个 DP 体系里最不能出错的地方——它一挂,后面所有事都不用谈。早期版本的 AUX 用 Manchester II 编码,DP 1.2 之后改成 8b/10b,最大数据率从 1 Mbps 提到 576 Mbps 量级,本质上是为了让 EDID 和 DPCD 的批量读写别太磨人。
3.1 HPD 的三种电平语义与两个时间常数
热插拔检测(HPD)是 sink 到 source 的单向信号,方向一定不能画反。它的电平不是简单的“插上/拔掉”二值,而是三态语义,靠持续时间区分:
- 拉到 3.3V 或保持高电平:sink 存在且就绪。
- 拉低超过 2 ms:sink 不存在,即拔出。这个 2 ms 是去抖窗口,防止插拔瞬间的机械抖动被误判成一次真实事件。
- 拉低 0.5 ms 到 1 ms 之间:这是一次中断请求(IRQ_HPD),sink 在告诉 source“我这边状态变了,你来读一下”。source 收到之后通过 AUX 去读 DPCD 里的 IRQ 向量寄存器,才知道具体是分辨率变了、链路丢了还是别的。
这两个时间常数是排查时的第一把尺子。如果一个板子插拔时好时坏,先拿示波器看 HPD 的低电平宽度:如果掉到 1.5 ms 左右,既不够 2 ms 的拔出判据、又远超 1 ms 的中断窗口,source 就会进入一个语义模糊的状态,表现成“识别到设备但不显示”。这种情况十有八九是 HPD 的上拉电阻太大、或者走线电容太大,导致边沿被拉缓。
3.2 DPCD 与 EDID:source 靠什么问出 sink 的底细
握手过程可以拆成两个阶段,读的东西不一样。
DPCD(DisplayPort Configuration Data)是 sink 侧的配置寄存器集合,source 通过 AUX 读写它。读的时候拿到的是 sink 的能力:支持几条 lane、支持哪些链路速率、接收端的均衡能力、时钟恢复范围。写的时候下发的是训练参数:目标 lane 数、目标速率、电压摆幅等级、预加重等级。链路训练期间,sink 会把每个阶段的训练结果写回 DPCD,source 再读回来判断成败。所以 DPCD 是双向的,既是能力表也是状态机。
EDID(扩展显示标识数据)描述的是“这块屏能显示什么”:制造商信息、EDID 版本、屏幕物理尺寸、支持的颜色空间、原生分辨率和时序列表、音频格式。source 拿到 EDID 才知道该给屏送什么格式的内容。EDID 是通过 DDC 通道读的,在 DP 上就是 AUX 之上跑 I2C 协议。
两者的分工很清晰:DPCD 决定“怎么连”,EDID 决定“送什么”。调试时如果 AUX 能通但读 DPCD 失败,问题在链路层;如果能读 DPCD 但 EDID 是空的,问题在 DDC 映射或者屏的 EDID 烧录。
3.3 链路训练的迭代:为什么它必须“试”
链路训练不是一次配置到位,而是一个搜索过程。原因是通道质量未知——线材长短、连接器接触、PCB 走线的阻抗连续性,都会影响高频衰减。source 手里有四个可调旋钮:lane 数、链路速率、电压摆幅(决定信号幅度)、预加重(补偿高频损失)。接收端还有一个均衡器可以调。
流程大致是这样:source 用自己偏好的配置起步,通常是“能跑的最高速率 + 4 lane”,但电压摆幅和预加重从保守值开始。每一轮它把参数写进 DPCD,然后等 sink 回报时钟恢复是否锁定、通道间是否对齐、符号边界是否找到。某一档不成功就换下一档,速率往下退、摆幅往上加、预加重往上加。整个过程可能包含上百次 AUX 读写,这也是为什么一对支持多流的 source 和 sink 之间,训练日志抓下来会很长。
# 链路训练的搜索逻辑,用伪代码还原“为什么它要试” # 真实实现里每一步都是 AUX 上的 DPCD 读写,这里省略时序细节 LINK_RATES = ["UHBR20", "UHBR13.5", "UHBR10", "HBR3", "HBR2", "HBR", "RBR"] # 从高到低尝试 SWING_LEVELS = [0, 1, 2, 3] # 电压摆幅档位,0 最保守 PREEMPH_LEVELS = [0, 1, 2, 3] # 预加重档位 def train(sink_caps, channel_quality, lanes): # 只尝试 sink 声明支持的速率,避免无效轮次 for rate in [r for r in LINK_RATES if r in sink_caps["rates"]]: for swing in SWING_LEVELS: for pre in PREEMPH_LEVELS: # 通道越差,需要的摆幅和预加重越高;这里用简单的衰减模型代替实测 if channel_quality < 0.3 and swing < 2: continue # 差通道上低摆幅基本没戏,跳过省时间 ok = simulate_eye(rate, swing, pre, channel_quality) if ok: return {"rate": rate, "lanes": lanes, "swing": swing, "pre": pre} return None # 全部档位试完仍失败,只能降 lane 数重来 def simulate_eye(rate, swing, pre, quality): # 眼高随摆幅增加、随速率下降;眼宽随预加重先增后减 margin = (swing + 1) * quality * 2 - LINK_RATES.index(rate) * 0.4 return margin > 1.0这段代码的重点不是模型准不准,而是展示训练的三个特征:速率优先从高往低退(保住带宽)、摆幅和预加重是嵌套的两层循环(先加幅度再加高频补偿,因为预加重会抬高功耗和 EMI)、失败后回到上一层降 lane 数。实际调试时,如果日志显示它在某一档反复重试却不往下走,通常是 DPCD 写入没生效——比如 CTL 总线的上拉不对,导致 I2C 应答丢失,source 以为写成功了,实际寄存器没变。
3.4 MSA 与 Mvid/Nvid:像素时钟是怎么被重建出来的
链路速率和像素率是解耦的,这是微报文架构的核心。链路侧跑的是固定的符号时钟(比如 HBR2 下每 lane 540 MHz),像素侧需要的节拍则取决于显示模式(4K60 是 594 MHz 左右)。两者不是整数倍关系,怎么办?
答案是主数据流属性(MSA)。源端在每个视频帧的起始处发送 MSA,里面带两个时间戳值:Mvid 和 Nvid。接收端用它们算出链路符号时钟和像素时钟的比例关系,再配合流里的时间戳,把像素节拍“再生”出来。这两个值取的是一对整数,让比例尽量接近真实值,同时长期平均误差趋近于零——单帧算下来可能有极小的小数误差,但因为它是个累加的时间戳机制,不会漂移。
from math import gcd def m_n_ratio(pixel_clk_khz, link_sym_clk_khz, lanes, bpp=24): # 链路侧每秒能提供的有效比特数(8b/10b 之后每符号每 lane 8 bit) link_bps = link_sym_clk_khz * 1e3 * lanes * 8 # 像素侧每秒需要的比特数 pixel_bps = pixel_clk_khz * 1e3 * bpp # 用 24 位定点数表示比例,这是 Mvid/Nvid 常见的位宽 scaled = link_bps / pixel_bps * (2 ** 24) mvid = int(round(scaled)) g = gcd(mvid, 2 ** 24) return mvid // g, (2 ** 24) // g # 例:4K60 8bpc,像素率约 594 MHz,4 lane HBR2(符号时钟 540 MHz) print(m_n_ratio(594000, 540000, 4)) # 输出约简后的 M/Nlanes和bpp两个参数直接决定比例;改显示模式时这两个值会变,Mvid/Nvid 也跟着变,所以它不是一个固定常数,而是每套时序都要重算。实际调试中如果画面出现周期性撕裂或垂直方向缓慢滚动,大概率是 M/N 配错或者时间戳没对齐——这不是 lane 的问题,是 MSA 的问题。
MSA 之外还有次级数据包(SDP),承载音频和 INFOFRAME。INFOFRAME 定义了视频和音频的结构,接收端靠它解释后续数据。多流场景下再叠一层边带消息,用来枚举下游设备拓扑、下发命令。这些包全部挤在主链路的空隙里传,所以带宽计算时要把它们的那一份留出来。
4. 原理图上的 DP:隔直电容、上下拉和那颗链路调理芯片
从协议走到原理图,最典型的场景是 FPGA 侧出来的 serdes 直接接 DP 连接器。FPGA 内部集成 DP 模块之后,信号可以直接送进链路调理芯片做预加重,再转给连接器;接收方向则反过来,连接器进来的信号先过均衡再进 FPGA。下面按输出和接收两个方向拆,用的例子是某半导体厂商的一颗链路调理芯片,手册上的短标号是 DP130,支持到 DP 1.4b,同时集成预加重和均衡,因此既能当输出驱动器也能当输入均衡器,双向都能用。
4.1 隔直电容为什么必须落在驱动端
DP 主链路是交流耦合的差分对,双端接。AC 耦合的作用是隔离两端的共模电压——源端和接收端可能是不同工艺的硅片,共模电平根本对不上,直连会把其中一端的输入级顶死。规范里明确写了 AC 耦合的目的就是让 DPTX 和 DPRX 可以有不同的共模电压。
电容放哪一端,是个有物理后果的选择。放在驱动端(靠近发送芯片)的意思是:电容之后的整段走线、连接器、线缆,直流电平由接收端来定。这样做的实际好处有三个。第一,插拔瞬间连接器上不会带着源端的直流偏置去和屏的外壳地打架,减少打火和浪涌。第二,接收端的共模建立电路只需要驱动自己这一侧的容性负载,不受源端影响,上电时序更好控制。第三,测试时探头的接入点相对固定,眼图测量的可复现性好。
提示:原文在输出和接收两处都写“隔直电容要放在驱动芯片端”,这不是笔误。输出方向上驱动芯片是 DP130,电容在 DP130 和连接器之间;接收方向上驱动芯片是屏那一侧的发送器,电容应该在连接器进来的位置附近,而不是贴着 FPGA。判断标准只有一条:谁在驱动这条差分对。
容值不是随便挑的。它和接收端的终端电阻构成一个高通滤波器,容值太小会让低频成分(长连零或长连一之后的直流恢复)衰减,表现为基线漂移、眼图上下不对称。经验上按链路速率和终端阻抗算转折频率,把它压到远低于数据流最低频成分的位置。
4.2 输出链路:FPGA 到连接器的四对差分
输出方向的信号路径是 FPGA serdes → DP130 → DP 连接器。原理图上有五组东西要盯。
差分输入。FPGA 给的 DP 信号本身就是 serdes 输出,需要小电容隔直,电容放在 DP130 这一端。这一段的阻抗控制是 100Ω 差分,走线尽量短,因为它在芯片和电容之间,没有连接器做缓冲,任何 stub 都直接变成反射。
差分输出。DP130 输出给连接器的同样是 serdes 信号,同样要小电容隔直,但电容要靠近接口摆放。原因是这段走线要经过连接器,接口处的 ESD 器件会带来额外的容性负载,电容放在接口侧可以把 ESD 器件的容抗纳入匹配考虑。
辅助通道。AUX 是 100Ω 差分,源端接 FPGA,中间用小电容隔直,sink 端接连接器。这里最容易翻车的是上下拉:AUX 是双向半双工,两端的偏置必须配合,上拉或者下拉配错会直接导致读不到 EDID。
串行总线。DDC 那条 I2C 负责传 EDID,也就是屏的性能参数;CTL 那条是标准 I2C,传 DDC 之外的控制信号,比如读芯片状态、配寄存器。两条都要 3.3V 上拉。输出侧的上拉电阻按手册给的值取,典型是 10 kΩ 量级。ADDR 引脚在多芯片共用一条 I2C 时用来错开地址,地址不冲突的话可以挂同一条总线。
接口与防护。DP 连接器是金属座,金属外壳的接地要和系统地进行隔离——不是随便连一起,而是通过合适的路径处理,避免整条线缆的共模噪声直接灌进板内地。同时因为它是外接设备,信号线和电源线上都要加 ESD 防护,防护器件要放在连接器入口、隔直电容之前,让静电在进入芯片之前就被泄放掉。
4.3 接收链路:AUX 为什么可以绕过调理芯片
接收方向的路径是 DP 连接器 → DP130(均衡)→ FPGA,但 AUX 不走这颗芯片。原因是 DP130 作为接收端时,AUX 的作用变成了“源端来问我”,而这条链路上没有下游显示器需要被枚举——本板就是 sink。所以 AUX 从连接器进来之后,一边直接进 DP130 参与链路管理,一边通过小电容隔直送给 FPGA,让 FPGA 侧的控制器能直接处理握手。
DDC 那条 I2C 在这里可以直接 NC,因为作为接收端没有“读别人 EDID”的需求。CTL 那条仍然要接,3.3V 上拉,阻值按手册取,典型是 2 kΩ 量级。注意这个 2 kΩ 和输出侧的 10 kΩ 不是随手写的,下一节会算。
HPD 在接收侧有两种接法可选,取决于这颗芯片是否要参与 HPD 的整形。一种是把连接器的 HPD 直接送给 FPGA,由 FPGA 产生中断;另一种是经过 DP130,由芯片在内部处理插入检测和中断脉冲,再输出给 FPGA。选哪种要看系统对中断延迟和去抖的要求,以及 FPGA 侧有没有现成的 HPD 检测逻辑。
4.4 I2C 上拉 10K 还是 2K,取决于总线电容
上拉电阻的取值被两个边界夹住:上限由上升时间决定,下限由器件的灌电流能力决定。
总线上的上升沿是指数充电,从 0 到 0.3 VDD 的时间约等于 0.8473×R×C(3.3V 供电时)。标准模式 100 kHz 允许的上升时间上限是 1000 ns,快速模式 400 kHz 是 300 ns。总线电容 C 包含走线、连接器、器件引脚和 ESD 器件的寄生电容,实际板子上 100~300 pF 很常见。
# 按上升时间和灌电流两个约束,算 I2C 上拉的合理区间 C_BUS = 200e-12 # 总线电容,200 pF,含走线、连接器、ESD 器件 T_RISE = 300e-9 # 快速模式 400 kHz 的上升时间上限 VDD, V_OL, I_OL = 3.3, 0.4, 3e-3 r_max = T_RISE / (0.8473 * C_BUS) # 上升时间上限推出的最大阻值 r_min = (VDD - V_OL) / I_OL # 灌电流上限推出的最小阻值 print("R 的合法区间: %.2f kΩ ~ %.2f kΩ" % (r_min / 1e3, r_max / 1e3)) # 换成标准模式 100 kHz(上升时间 1000 ns)再看一次 r_max_std = 1000e-9 / (0.8473 * C_BUS) print("标准模式下上限放宽到: %.2f kΩ" % (r_max_std / 1e3))在 200 pF、快速模式下算出来的上限只有 1.77 kΩ 左右,下限约 0.97 kΩ,窗口很窄。这就解释了为什么接收侧用 2 kΩ——它的总线电容更小、或者速率要求更高,必须用强上拉把边沿拉陡。而输出侧的 DDC/CTL 走线短、器件少、速率低,10 kΩ 在标准模式下(上限放宽到 5.9 kΩ 以上)是能过的,功耗还低。
注意:上拉不是越小越好。阻值下去之后,器件拉低时的灌电流上升,长期工作在极限附近会让 IO 口发热甚至失效。手册给的值通常是算过的,改动之前先按上面的公式核一遍自己的总线电容。
5. 排查:链路训练失败、眼图不过、EDID 读空的五个现场
DP 调试最难受的地方在于,同一个现象背后可能是物理层、协议层、配置层三个层面的问题,而它们的表现高度相似——都是“不亮”。下面五条是踩过之后总结出来的分辨方法,每条都按现象、原因、解决三步走。
5.1 训练停在时钟恢复:AUX 通,lane 不通
现象:AUX 读写正常,DPCD 能读能写,EDID 也能读出来,但训练日志显示在时钟恢复阶段反复失败,帧率上不去或者直接黑屏。
原因:AUX 是低速差分对,主链路是高速差分对,两者的通道要求差一个数量级。AUX 能通只说明连接器的低速引脚和基本的差分连接没问题,完全不能证明高速 lane 的阻抗、长度匹配、隔直电容位置是对的。常见的是 lane 之间的长度偏差别太大,导致通道间偏斜超出接收端对齐窗口;或者隔直电容放在了接收端,源端的共模没被隔离。
解决:先用 AUX Channel Monitor 类的工具把训练日志抓下来,看它卡在哪一轮、用的是哪档速率和摆幅。如果它一路退到 RBR 才成功,基本可以确定是通道问题而不是配置问题。然后量 lane 间的长度差,把它压到规范允许的偏斜以内;检查电容位置;确认连接器侧的 ESD 器件没有把差分对的对内平衡破坏掉。降 lane 数能过、4 lane 不过,是最典型的对内偏斜症状。
5.2 EDID 读回全 0 或校验错
现象:链路能训练成功,但 source 拿到的 EDID 是 0xFF 填充或者校验和错误,导致分辨率退回默认值。
原因:DDC 那条 I2C 的物理层问题。三个高频原因:上拉阻值不对导致边沿太缓、AUX 到 DDC 的映射关系配错、CTL 总线的地址冲突让器件不应答。还有一种隐蔽情况是 ESD 器件的寄生电容太大,把 DDC 的上升沿吃掉,读时序勉强能过但在某些字节上出错。
解决:先用示波器看 DDC 的 SCL/SDA 波形,重点看上升时间。如果上升沿是明显的圆弧而不是陡沿,就是上拉不够,按上一节的公式重算阻值。然后确认 AUX 转 DDC 的映射逻辑——DP 的 EDID 读取是 AUX 上跑 I2C-over-AUX,映射错了会读到空。最后查地址,多个器件挂在同一条总线上时,ADDR 引脚没配好会互相打架。
5.3 眼图模板差一点点过不去
现象:功能全正常,出图也正常,但眼图测试的余量很小,某些测试点刚好卡在模板边缘。
原因:眼图判据是分测试点的。输入端和输出端用的是不同模板——输入端(TTP2)看的是接收芯片看到的信号质量,输出端(TTP4)看的是连接器处发出的信号质量。两个模板的张度和容限不一样,在输入端过、在输出端不过是很常见的。另一个原因是预加重和摆幅的组合不是最优:预加重加太多会让上升沿过冲,眼高被削;加太少高频损失补偿不够,眼宽不够。
解决:先确认测的是哪个点,别拿输入模板去判输出。然后在芯片的配置寄存器里扫一遍预加重和摆幅的组合,找出余量最大的那组,而不是用默认值。如果所有组合都贴着模板,说明通道本身的损耗已经接近极限,考虑缩短走线、换更低损耗的板材,或者把链路速率降一档换取余量。
5.4 插拔不识别、反复重连
现象:冷启动能识别,热插拔时灵时不灵;或者系统日志里反复出现设备上线、下线。
原因:HPD 信号的时间常数不对。前面说过,拉低超过 2 ms
本文还有配套的精品资源,点击获取