//Jeff 的技术站SUPPORT · DEVELOPMENT · OPERATIONS
项目记录 · 适用范围与状态以原文为准,操作前请先阅读已知限制。

内屏(eDP)点亮:完整诊断记录

本文记录 “跑码时内屏正常、进系统后黑屏” 这一问题的完整排查过程与技术结论,供同机型(Raptor Lake-H + 无独显)遇到相同症状的人参考。


1. 症状

阶段 现象
开机跑码 内屏正常显示(Verbose 文字正常滚动)
驱动接管瞬间 屏幕变黑
手电筒照射 有背光、无画面(背光一直亮着)
外接显示器 正常,可进系统
系统内 ioreg 能看到内屏(1920×1080,主显示器)

三条关键事实:系统认得内屏、背光亮着、就是没有画面 —— 说明问题在“视频链路”,不在背光、不在面板识别。


2. 定位过程

2.1 排除背光

  • 手电筒能看到背光常亮 → 背光已开
  • PCH PWM 占空比已到 100%,但屏幕不亮 → 亮度不走传统 PWM 路径
  • 面板 DPCD 0x721 = 0x84:面板处于 AUX 背光模式(背光由 DPCD 寄存器控制),0x722/0x723 = 0xBF00(固件设定的约 74% 亮度)

结论:背光由面板固件通过 DPCD 锁存维持,与“是否有画面”无关。

2.2 锁定视频链路

内核日志给出决定性证据:

FB0: Hardware mode set failed, err = 0xe00002d8
[IGFB][ERROR][AUX] ddi = 0 Time out: 0x5d10023f
  • 0xe00002d8 = kIOReturnTimeout,AUX 事务重试耗尽
  • 0x5d10023f 的 bit28 是 TIMEOUT_ERROR

即:驱动做 modeset 时,所有 AUX 事务都超时,eDP 链路从未完成训练,所以没有视频输出。

2.3 面板与 AUX 硬件是否正常?

用裸寄存器直接访问 DP AUX 通道(绕过驱动栈)做探针,得到:

探测 结果
DPCD 0x000–0x00F(接收器能力) 可读,正常
DPCD 0x202(链路状态) 0x01(仅 CR 完成,未完成信道均衡)
DPCD 0x721(背光模式) 0x84(AUX 背光模式锁存)
DPCD 0x722/0x723(亮度) 0xBF00
写入 0x722 = 0xFFFF AUX 应答 ACK(status=0),但寄存器值不变

结论:面板与 AUX 通道本身是好的;面板在链路未训练时对 DPCD 写入返回 ACK 但不落盘(冻结快照行为)。

2.4 为什么固件能、驱动不能?

  • 固件(BIOS/UEFI)在开机早期已经完成 eDP 链路训练 → 跑码阶段有画面
  • macOS 驱动接管后重新训练这条链路,但它的 AUX 事务要先经过电源井(power well)状态机
  • 这台机器的黑苹果环境下,该状态机不工作 → 驱动侧 AUX 全部超时

裸寄存器直连 AUX 是成功的,说明差别只在驱动封装的电源井流程,不在硬件。


3. 失败的尝试(供参考,不要重走)

方案 结果
调整 DVMT / 显存补丁 无关,FB0 依然 AUX 超时
反汇编驱动,替换内部 AUX worker(vtable hook) 会卡启动。在 processKext 阶段改 vtable 影响早期启动路径,两次验证均死机/卡 verbose
修改 DPCD 强制设置链路参数 写入被 ACK 但不生效(链路未训练时面板冻结 DPCD)
等待电源井就绪后重试 超时依旧,状态机不推进

教训:不要在启动关键期用 vtable 钩子改图形驱动内部函数。代价是整个系统起不来。


4. 最终方案:-wex-edp-keep

来自 WhateverXe 上游 issue #43(2026-11)的社区方案。

核心思路:既然固件已经把链路训练好了,就不要重训。

驱动在 modeset 时会先检查链路是否已由固件训练完成:

若 已训练完成 → 返回 Partial modeset(只更新部分状态,不动链路)

加启动参数即可:

- amfi_get_out_of_my_way=1 msgbuf=1048576 -v
+ amfi_get_out_of_my_way=1 msgbuf=1048576 -v -wex-edp-keep

验证

ioreg -l | grep WEXEDPKeep

输出示例:

"WEXEDPKeep" = <01000000 04000000 04000000 00000000 ...>

字段含义:

字段 值 含义
version 1 记录结构版本
call 4 驱动共请求 4 次完整 modeset
kept 4 4 次全部被拦截为 Partial modeset
reasons 0 拦截原因位图(0 = 均为“链路已训练”)

同时内核日志中的 Hardware mode set failed 完全消失,内屏点亮,Metal 加速正常。

该方案的机制细节

  1. wrapDisplay13ReadAUX 中捕获面板 DPCD 的链路能力(capLinkCaps)
  2. 驱动在完整 modeset 时调用 Display13EDPKeep 决策
  3. 满足条件(DDI < 2 且该端口配置为内屏、链路已训练)时返回 Partial modeset
  4. 于是 TRANS_DDI_FUNC_CTL / TRANSCONF / 时序寄存器按请求更新,但不重新训练链路

5. 代价与限制

场景 结果 原因
睡眠唤醒 内屏黑到重启 唤醒触发完整 modeset 重训
手动关闭显示器 同上 同上
切换分辨率 / 刷新率 同上 同上
日常使用(不碰上述操作) 完全正常 —

规避方式:系统设置里关闭显示器休眠、不手动关屏、分辨率保持默认。


6. 复现所需的最小配置

项目 值
核显 0xA720(Raptor Lake-H/P Iris Xe)
驱动 WhateverXe ≥ 0.6.1(0.7.0 验证通过)
补丁 edp-keep 系列 3 个 commit(eDP 端口准入、VBT panel type 0xFF、keep 决策钩子)
启动参数 -wex-edp-keep
前提 固件阶段内屏已点亮(跑码有画面)

若跑码阶段内屏就不亮,说明固件没有训练链路,此方案不适用。

记录来源:EnormousKnob/zbook-g10-hackintosh查看配置与脚本 →