eDP 1.5a 工程手册:MSO、ALPM、PSR 与 HBR3 链路调试实战

发布时间:2026/10/14 9:08:27
eDP 1.5a 工程手册:MSO、ALPM、PSR 与 HBR3 链路调试实战
简介这份资源是VESA发布的嵌入式DisplayPorteDP标准1.5a版官方PDF文档面向笔记本、一体机等嵌入式显示接口的硬件工程师、驱动开发者与系统集成人员。eDP标准基于DisplayPort 2.1制定针对内部显示面板互连场景给出实现选项与推荐配置可帮助读者理解嵌入式显示链路的设计约束与兼容性要求。压缩包内共1个PDF文件约12.69MB内容涵盖目的说明、修订历史、知识产权声明及正文各章节从背景目标、文档组织到具体规范逐层展开便于按章节检索查阅。目前已有766人学习下载适合需要对照官方规范进行eDP接口设计、调试或方案选型的从业者作为案头参考也可用于梳理eDP与外部DisplayPort在应用定位上的差异。1. eDP 1.5a 标准文档拆解从笔电屏到 MSO 多屏拼接一份能直接翻的工程手册如果你拆过笔记本的屏线或者调过 4K 120Hz 内屏的链路训练大概率在某个深夜被 eDP 的 DPCD 寄存器折腾过。这份 VESA Embedded DisplayPort Standard Version 1.5a2023 年 2 月 27 日发布就是干这个用的——它基于 DP 2.1 主干把嵌入式场景里那些“外接显示器用不上、但笔电和一体机必须抠”的细节单独拎出来定死。适合谁做屏驱动、做 BIOS 显示初始化、做面板时序验证、做 MSO 拼接方案的嵌入式工程师。它不是科普读物是一本你遇到 PSR 进不去、ALPM 唤醒失败、HBR3 眼图不过时能直接翻到对应章节找寄存器定义和时序参数的手册。全文 700 多页我按实际调试路径把它拆成能落地的几块。2. eDP 1.5a 的架构底座MSO、ALPM 与 PSR 到底改了什么2.1 从 DP 2.1 到 eDP 1.5a 的裁剪逻辑eDP 不是另起炉灶它是 DP 标准的一个“嵌入式 profile”。DP 2.1 面向外接线缆和系统厂商互操作强调热插拔、长线缆均衡、多流传输eDP 则把重点放在板级短距离、低功耗、面板自刷新这些内嵌场景。1.5a 版本的核心变化集中在三块Multi-SST OperationMSO把一条链路拆成多个独立 SST 流去驱动分段面板Advanced Link Power ManagementALPM把 AUX 通道的唤醒机制细分成 AUX-wake 和 AUX-less 两种Panel Self RefreshPSR从 PSR1 的整帧缓存进化到 PSR2 的 Selective Update 局部刷新。这三块直接决定了你调出来的机器是续航多两小时还是少两小时是能点亮 4K 120Hz 还是只能降到 60Hz。文档结构上Section 1 是背景和约定Section 2 是 eDP 总览和特性偏差表Section 3 专讲 MSOSection 4 是电气规格扩展Section 5 是 ALPMSection 6 是 PSRSection 7 是 AUX 通道上的源端到宿端视频时序同步。真正干活时翻得最多的是 Section 3 到 Section 6因为寄存器定义、状态机、时序参数全在里面。2.2 MSO 多屏拼接的链路拆分方式MSO 的本质是把一条 eDP 主链路在逻辑上切成多条独立的 SST 链路每条链路驱动面板的一个物理分段。文档里给了三种典型配置2×1两条链路各一条 lane、2×2两条链路各两条 lane、4×1四条链路各一条 lane。以 2×1 为例源端需要配置 DPCD 寄存器 0x1110 到 0x111F 这一段来定义每条 SST 链路的 lane 映射和像素分段边界。实际操作中你会在源端驱动里做这么几件事先读 sink 端的 MSO capability 寄存器确认支持哪种配置然后写 MSO link count 和 lane assignment最后在 VSC SDP 里带上分段信息。文档 Section 3.4 给了每种配置的源端设备配置流程Section 3.5 专门讲像素跨相邻分段重叠时的处理——这个坑很隐蔽如果分段边界像素没有正确 overlap拼接处会出现一条亮线或暗线。# 以 Linux 内核 drm 调试为例读取 eDP sink 的 MSO 能力 # 先确认 AUX 通道可访问 ls /sys/kernel/debug/dri/*/DP-*/edp_aux # 通过 debugfs 读 DPCD 0x1110 区域MSO 配置寄存器 cat /sys/kernel/debug/dri/0/DP-1/dpcd_dump | grep -A 16 0x1110 # 典型输出解读 # 0x1110: MSO link count (bit[3:0])0x02 表示 2 条 SST 链路 # 0x1111: lane assignment0x01 表示每条链路 1 lane # 0x1112-0x111F: 各分段像素起止边界上面这段调试路径不是文档里直接写的是实际 bring-up 时常用的手段。DPCD 0x1110 的 bit[3:0] 读出来是 MSO link count写 0 关闭 MSO写 2 或 4 开启对应数量的 SST 链路。lane assignment 寄存器决定每条链路分到几条 lane2×1 配置下每条链路只有 1 lane所以总带宽是固定的分段后每段的刷新率会受限于单 lane 速率。如果你在 2×1 下强行跑 HBR3 8.1Gbps 单 lane理论带宽够 4K 60Hz 但不够 4K 120Hz这时候要么改 2×2 要么降分辨率。2.3 ALPM 的两种唤醒路径与寄存器配置ALPM 是 eDP 1.5a 里对续航影响最直接的特性。传统 eDP 在空闲时主链路可以进低功耗态但 AUX 通道还得保持活跃来监听唤醒事件这部分功耗在待机时占比不小。ALPM 把唤醒机制分成 AUX-wake 和 AUX-less 两种AUX-wake 保留 AUX 通道的监听能力但把主链路彻底关断AUX-less 则连 AUX 通道都关掉靠 HPD 或专用侧带信号唤醒。文档 Section 5.2 列出了 ALPM 相关的 DPCD 寄存器核心是 0x000Eh 的 ALPM capability 和 0x0010h 的 ALPM configuration。源端要先读 capability 确认 sink 支持哪种模式然后写 configuration 使能。Section 5.4 分别给了 AUX-wake 和 AUX-less 的信令流程Section 5.5 是发现、使能和禁用的配置步骤。# 伪代码ALPM 使能流程 def enable_alpm(aux_dev): # 1. 读 sink ALPM capability cap dpcd_read(aux_dev, 0x000E, 1) aux_wake_support cap 0x01 aux_less_support (cap 1) 0x01 # 2. 选择模式并写 configuration if aux_less_support: # AUX-less 模式主链路和 AUX 都可关断 dpcd_write(aux_dev, 0x0010, 0x02) elif aux_wake_support: # AUX-wake 模式保留 AUX 监听 dpcd_write(aux_dev, 0x0010, 0x01) else: return -1 # sink 不支持 ALPM # 3. 等待 sink 确认进入 ALPM 态 # 读 0x0020 状态寄存器bit[0] 为 1 表示已进入 timeout 100 # ms while timeout 0: status dpcd_read(aux_dev, 0x0020, 1) if status 0x01: return 0 timeout - 1 sleep(1) return -2 # 超时这段流程的关键参数0x000E 的 bit0 是 AUX-wake 支持bit1 是 AUX-less 支持0x0010 写 1 使能 AUX-wake写 2 使能 AUX-less0x0020 的 bit0 是 ALPM 状态确认。实际调试时最常见的翻车是 sink 端固件没正确实现 capability 寄存器读出来全是 0这时候别急着改源端代码先用示波器抓 AUX 通道看 sink 有没有回 NACK。2.4 PSR1 与 PSR2 的状态机差异PSR 是面板自刷新核心思想是当画面静止时源端把主链路关掉让面板自己从本地缓存里刷。PSR1 只能缓存整帧PSR2 支持 Selective Update只更新变化区域。文档 Section 6.2 讲 PSR1Section 6.3 讲 PSR2两者都有完整的状态机定义Entry、Active、Exit 三个主状态外加 Error Management 和 Recovery。PSR1 的 Entry 流程是源端先确认 sink 的 PSR capabilityDPCD 0x0700然后写 PSR configuration0x0701最后发 VSC SDP 通知 sink 进入 PSR。PSR2 多了 Selective Update 的配置需要额外写 0x0702 到 0x070F 这一段来定义更新区域。Section 6.3.7 专门讲 Partial Video Image Update里面有个关键参数是 SU granularity决定了最小更新区域的像素粒度。# 读取 PSR capability 和配置状态 # DPCD 0x0700: PSR capability # bit[0]: PSR1 支持 # bit[1]: PSR2 支持 # bit[3:2]: SU granularity (01x1, 14x4, 28x8, 316x16) cat /sys/kernel/debug/dri/0/DP-1/dpcd_dump | grep -A 4 0x0700 # 典型输出 # 0x0700: 0x0B - PSR1 PSR2 SU granularity 8x8 # 0x0701: 0x01 - PSR enabled # 0x0702: 0x00 - Selective Update region startSU granularity 这个参数很关键。如果读出来是 8x8意味着你告诉 sink 更新区域时坐标必须按 8 像素对齐否则 sink 会忽略这次更新或者刷出花屏。我见过一个案例源端驱动按 1x1 粒度算更新区域但 sink 实际是 16x16结果每次局部刷新都变成整帧刷新功耗根本没降下来。3. 电气规格与链路训练HBR3 眼图不过时先查这几个寄存器3.1 链路速率发现与 VDIFF 训练表eDP 1.5a 的电气规格扩展在 Section 4。链路速率支持从 RBR 1.62Gbps 到 HBR3 8.1Gbps文档 Section 4.6.1 给了推荐链路速率表。实际 bring-up 时源端要先读 sink 的 DPCD 0x0000 到 0x0003 确认最大链路速率和 lane 数然后从最高速率往下试直到链路训练通过。链路训练的核心是 VDIFF差分电压和预加重/去加重参数的调整。Section 4.4.2 给了 VDIFF Training Table列出了不同链路速率下推荐的电压摆幅和预加重等级。以 HBR3 为例TP3_EQ 眼图模板要求比 HBR2 严格得多Section 4.7.1 定义了 TP3_EQ 的 EYE 模板Section 4.7.2 给了参考接收机均衡器的参数。# 链路训练状态检查 # DPCD 0x0202: LANE0_1_STATUS # bit[0]: lane0 CR 完成 # bit[1]: lane0 EQ 完成 # bit[2]: lane1 CR 完成 # bit[3]: lane1 EQ 完成 cat /sys/kernel/debug/dri/0/DP-1/dpcd_dump | grep -A 2 0x0202 # 如果 CR 完成但 EQ 没过通常是预加重不够 # 读 0x0203 看 lane2_3 状态 # 读 0x0204 看 sink 端调整请求链路训练失败时先看 0x0202 和 0x0203 的 CR/EQ 完成位。CR 过了 EQ 没过说明电压摆幅够但高频补偿不足需要加预加重。Section 4.4.2 的表里HBR3 在长 PCB 走线下推荐预加重等级 2 或 3。如果 CR 都过不了先降速率到 HBR2 试试确认是走线问题还是 sink 端均衡器配置问题。3.2 AUX_CH 电气子块与 HPD 信号AUX 通道是 eDP 的控制通道所有 DPCD 读写都走它。Section 4.9 定义了 AUX_CH 的电气子块和拓扑Section 4.10 定义了 HPD热插拔检测信号。eDP 的 HPD 和外部 DP 不一样它通常是 LV-HPD低电压 HPDSection 4.10.1 给了 LV-HPD 子块的具体参数。实际调试中AUX 通道的常见问题是时序不满足。AUX 事务有严格的超时要求如果源端驱动在 AUX 请求后等待时间不够sink 还没回就把通道释放了就会读到全 0 或全 F。文档 Section 4.9.1 给了 AUX_CH 的电气参数包括差分电压和终端匹配要求。我一般会在驱动里把 AUX 超时设成 3ms 以上给 sink 留足响应时间。// AUX 事务超时设置示例Linux drm_dp_helper #define DP_AUX_TIMEOUT_MS 3000 // 默认 3ms长线缆场景可加到 5ms static int edp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { // 发送 AUX 请求 ret aux-transfer(aux, msg); if (ret 0) { // 超时或 NACK重试一次 usleep_range(1000, 2000); ret aux-transfer(aux, msg); } return ret; }这段代码的关键参数是超时时间。eDP 板级走线通常很短3ms 足够但如果你的屏线超过 30cm 或者经过转接板建议加到 5ms。另外 AUX 重试次数不要超过 2 次否则会影响启动速度。3.3 抖动预算与差分噪声预算Section 4.6.2 和 4.6.3 分别给了 HBR2 及以下和 HBR3 的差分噪声预算。HBR3 的抖动预算比 HBR2 紧了一倍多这也是为什么很多老屏线跑 HBR3 会翻车。Section 4.6.4 给了系统抖动预算的分配方法源端、线缆、sink 端各占多少都有推荐值。实际排查眼图问题时我会先确认三件事源端 TX 的预加重和电压摆幅是否按 Section 4.4.2 的表配了线缆的差分阻抗是否控制在 85Ω 到 115Ω 之间sink 端的终端匹配电阻是否焊了。这三样里最容易出问题的是线缆阻抗尤其是那些便宜的 FPC 屏线阻抗偏差能到 20% 以上HBR2 能跑但 HBR3 必挂。4. 避坑与排查PSR 进不去、ALPM 唤醒失败、MSO 拼接亮线4.1 PSR 状态机卡在 Entry 态现象源端发了 PSR Entry 的 VSC SDP但读 DPCD 0x0020 状态寄存器一直不返回 PSR Active 确认超时后回退到正常刷新。原因最常见的是 sink 端 PSR 缓存还没准备好。PSR Entry 需要 sink 先把当前帧写入本地缓存这个写入时间取决于面板分辨率和缓存带宽。文档 Section 6.2.3 给了 PSR1 Entry 的时序要求但没有给具体的缓存写入时间这个参数在面板规格书里。解决在发 PSR Entry 之前先读 sink 的 PSR 状态寄存器确认缓存就绪。如果面板规格书没给这个时间按经验值设 20ms 到 50ms 之间4K 面板取上限。另外检查 VSC SDP 的 CRC 校验是否使能有些 sink 端固件在 CRC 校验失败时会静默丢弃 PSR Entry 请求。4.2 ALPM AUX-less 模式下无法唤醒现象系统进入 ALPM AUX-less 态后按键盘或动鼠标无法唤醒屏幕只能强制重启。原因AUX-less 模式下 AUX 通道和主链路都关断了唤醒靠 HPD 或专用侧带信号。如果源端没有正确配置 HPD 唤醒使能或者 sink 端的 HPD 驱动能力不足唤醒信号就到不了源端。解决先确认 DPCD 0x0010 写的是 0x02AUX-less然后检查源端 HPD 中断是否使能。Section 5.4.2 给了 AUX-less 的信令流程里面提到 HPD 脉冲宽度至少 1ms。如果 HPD 信号太窄源端中断控制器可能采不到。用示波器抓 HPD 线确认脉冲宽度和电平是否符合 LV-HPD 规范。4.3 MSO 2×1 配置下拼接处出现亮线现象2×1 MSO 配置点亮后两块面板分段之间有一条 1 到 2 像素宽的亮线或暗线。原因分段边界像素没有正确 overlap。文档 Section 3.5 专门讲了这个MSO 分段时相邻分段的边界像素需要重叠至少 1 个像素否则拼接处会出现缝隙。如果源端驱动算分段边界时直接按分辨率除以 2没有做 overlap就会出这个问题。解决在源端配置 MSO 分段边界时把每段的结束像素往后延 1 到 2 个像素让相邻分段有重叠。具体 overlap 像素数看面板规格书一般 1 像素够用高 PPI 面板可能需要 2 像素。改完边界后重新算 VSC SDP 里的分段信息确保源端和 sink 端的分段定义一致。4.4 HBR3 链路训练 EQ 阶段失败现象链路训练 CR 阶段通过EQ 阶段失败DPCD 0x0202 的 EQ 完成位一直是 0。原因HBR3 的 EQ 阶段对预加重和接收端均衡器要求很高。如果源端预加重等级不够或者 sink 端均衡器配置不对EQ 就过不了。Section 4.7.2 给了参考接收机均衡器的参数但实际面板的均衡器可能和参考设计有偏差。解决先把预加重等级往上调一档Section 4.4.2 的表里 HBR3 推荐等级 2 到 3可以试到 4。如果还不行降速率到 HBR2 确认链路本身没问题。然后检查 sink 端均衡器配置有些面板的均衡器需要源端通过 AUX 写特定寄存器来使能这个寄存器地址在面板规格书里不在 eDP 标准文档里。4.5 PSR2 Selective Update 区域不生效现象PSR2 使能后局部刷新区域没有按预期更新要么整帧刷新要么更新区域错位。原因SU granularity 不匹配。源端按 1x1 粒度算更新区域但 sink 实际是 8x8 或 16x16导致坐标不对齐sink 忽略更新请求。另外 Selective Update 的坐标是相对面板左上角的如果源端用了相对窗口的坐标也会错位。解决先读 DPCD 0x0700 的 bit[3:2] 确认 SU granularity然后源端算更新区域时按这个粒度对齐。坐标原点确认是面板左上角不是窗口左上角。Section 6.3.7 给了 Selective Update 的坐标定义建议在驱动里加一个对齐检查坐标不对齐时自动扩展到最近的粒度边界。5. 从寄存器到实测用 DPCD dump 和眼图验证 eDP 1.5a 链路5.1 DPCD dump 的完整读取流程验证 eDP 链路状态最直接的手段是读 DPCD 寄存器。Linux 下可以通过 debugfs 读Windows 下可以用厂商提供的工具或者自己写一个 AUX 读写工具。下面是一个完整的 DPCD dump 脚本覆盖了 eDP 1.5a 最关键的几段寄存器。#!/usr/bin/env python3 # eDP 1.5a 关键 DPCD 寄存器 dump 脚本 # 依赖i2c-tools 或厂商 AUX 驱动 import subprocess import sys # 关键寄存器段定义 DPCD_SEGMENTS { 链路能力: (0x0000, 0x000F), 链路状态: (0x0200, 0x020F), PSR 配置: (0x0700, 0x070F), ALPM 配置: (0x000E, 0x0010), MSO 配置: (0x1110, 0x111F), } def dpcd_read(addr, length): 通过 i2c 读 DPCD实际使用时替换为厂商 AUX 接口 # 这里用 i2cget 模拟实际 eDP 走 AUX 通道 result subprocess.run( [i2cget, -y, 0, 0x50, f0x{addr:02x}, w], capture_outputTrue, textTrue ) return result.stdout.strip() def dump_segment(name, start, end): print(f\n {name} (0x{start:04X} - 0x{end:04X}) ) for addr in range(start, end 1, 4): val dpcd_read(addr, 4) print(f0x{addr:04X}: {val}) if __name__ __main__: for name, (start, end) in DPCD_SEGMENTS.items(): dump_segment(name, start, end)这段脚本的关键在于 dpcd_read 函数实际 eDP 不走 i2c走 AUX 通道需要替换成厂商提供的 AUX 读写接口。寄存器段的选择覆盖了链路能力0x0000 到 0x000F、链路状态0x0200 到 0x020F、PSR 配置0x0700 到 0x070F、ALPM 配置0x000E 到 0x0010、MSO 配置0x1110 到 0x111F。读出来之后对照文档 Section 1.3.4 的 DPCD 寄存器表解读。5.2 眼图测试的 TP3_EQ 模板对照HBR3 眼图测试用 TP3_EQ 模板Section 4.7.1 给了模板的详细定义。实际测试时示波器要设成差分探头带宽至少是链路速率的 1.5 倍HBR3 8.1Gbps 需要 12GHz 以上带宽。眼图模板的关键参数是眼高和眼宽TP3_EQ 的眼高要求比 TP2 严具体数值在 Section 4.7.1 的表里。我一般会先跑 TP2 眼图确认源端 TX 本身没问题再跑 TP3_EQ 看经过通道后的眼图。如果 TP2 过不了先查源端预加重和电压摆幅配置如果 TP2 过了 TP3_EQ 没过查线缆和 sink 端均衡器。Section 4.7.2 给了参考接收机均衡器的参数可以对照调整示波器的均衡设置。5.3 链路训练日志的解读方法链路训练过程中源端和 sink 端会通过 AUX 交换一系列 DPCD 读写。把这段 AUX 事务抓下来对照文档 Section 4.4.1 的链路训练流程能快速定位失败在哪一步。关键节点包括读 sink 能力0x0000 到 0x0003、写链路配置0x0100 到 0x0103、读训练状态0x0202 到 0x0204、调整电压摆幅和预加重0x0103 的 bit[1:0] 和 bit[3:2]。如果 CR 阶段反复重试看 0x0204 的 sink 调整请求里面会告诉源端往哪个方向调。如果 EQ 阶段失败看 0x0202 的 EQ 完成位和 0x0203 的 lane2_3 状态。Section 4.4.2 的 VDIFF Training Table 给了不同速率下的推荐值可以对照日志里的实际值看偏差。5.4 一个我踩过的坑PSR 和 ALPM 同时使能的顺序问题最后说一个血泪经验。PSR 和 ALPM 都能省电但两者同时使能时进入顺序有讲究。如果先使能 ALPM 再使能 PSRPSR Entry 的 VSC SDP 可能因为主链路已经进低功耗态而发不出去。正确的顺序是先使能 PSR等 PSR 稳定进入 Active 态后再使能 ALPM。退出时反过来先退 ALPM 再退 PSR。文档 Section 5 和 Section 6 没有明确写这个顺序因为它们是独立章节。但实际调试时这个顺序错了会导致 PSR 进不去或者 ALPM 唤醒失败。从那以后我每次配 eDP 低功耗特性都强制走一遍「PSR 先、ALPM 后」的顺序并且在驱动里加一个状态检查确认 PSR Active 之后才允许写 ALPM 配置寄存器。希望帮到你。本文还有配套的精品资源点击获取