Arch Linux 下 NVIDIA HDMI 2.1 睡眠唤醒后 4K 144Hz 掉到 60Hz 的排查与修复
CATALOG // OUTLINE ▼
最近被一个奇怪的问题折磨了挺久:我的 Arch Linux + KDE Plasma 6 Wayland 电脑只要进入睡眠再唤醒,外接的 4K 144Hz 显示器刷新率就会瞬间腰斩,不仅掉到 60Hz,而且在系统设置里压根找不到 120Hz/144Hz 的选项,就像它们从未存在过一样。
之前遇到这种情况,我只能重新插拔 HDMI 线或者重启系统。今天想想还是不忍了准备自己解决,经过一番排查,发现这根本不是 KDE Plasma 或 KWin 的锅,而是 NVIDIA 驱动对于 HDMI 2.1 FRL 协商的一个陈年老 Bug。本文记录完整的排查证据链,并给出一套无需重启、无需物理拔插、全自动恢复 4K 144Hz 的 DDC/CI 优雅解决方案。
1. 故障现象与硬件拓扑
诡异的故障表现
- 系统睡眠唤醒后,外接显示器(我的设备是 SKYWORTH F27G10U,4K 144Hz)最高刷新率锁定在 60Hz。
- 核心特征:并不是“设置里勾选了 144Hz 但实际掉帧或跑 60Hz”,而是 100Hz / 120Hz / 144Hz 这些高刷模式直接从系统的模式列表里彻底消失了。
- 重新插拔 HDMI 线或重启电脑后恢复正常,显示器睡眠后再唤醒则几乎必现。
- 重启显示器无法恢复正常。
硬件环境与输出拓扑
- 设备:Lenovo 笔记本(Intel Alder Lake-S + NVIDIA RTX 4050 Laptop)
- 系统/内核:Arch Linux 7.3.0-4-cachyos
- 显卡驱动:
nvidia-open-dkms(580.xx 系列开源内核模块) - 桌面环境:KDE Plasma 6.8.1 / Wayland (
kwin_wayland) - 显示拓扑:
- 内屏:
card2-eDP-1(日常外接时禁用) - 外接屏:
card1-HDMI-A-1创维 F27G10U(3840x2160@144Hz)
- 内屏:
关键线索:HDMI 接口在笔记本上是直连独显(
card1-HDMI-A-1)的,走的是 NVIDIA 专有驱动的 HDMI 2.1 输出路径,排除了核显驱动的问题。
2. 深入排查:高刷模式究竟去哪儿了?
既然高刷选项直接消失了,那到底是 EDID 读崩了、KWin 的缓存出 Bug,还是驱动层把高刷给砍了?
2.1 检查 KScreen 输出与模式表
在唤醒故障发生后,使用命令行工具查看当前的输出模式:
1 | |
此时抓到的 HDMI-A-1 模式列表十分耐人寻味:
1 | |
仔细看这个模式表:4K 下的 100/120/144 全部消失,但是 2K(1440p)@120Hz 和 1080p@120Hz 却完好无损!
结合 HDMI 协议与带宽计算,真相瞬间浮出水面:
| 分辨率与刷新率 | 所需带宽 / Pixel Clock | 唤醒后状态 | 依赖的技术 |
|---|---|---|---|
| 3840x2160@144 | 1279.86 MHz | ❌ 彻底消失 | 必须 HDMI 2.1 FRL 协议 |
| 3840x2160@120 | 1058.40 MHz | ❌ 彻底消失 | 必须 HDMI 2.1 FRL 协议 |
| 3840x2160@100 | 888.80 MHz | ❌ 彻底消失 | 必须 HDMI 2.1 FRL 协议 |
| 3840x2160@60 | 594.00 MHz | ✅ 依然存在 | 传统 HDMI 2.0 TMDS 足以承载 |
| 2560x1440@120 | 497.76 MHz | ✅ 依然存在 | 传统 HDMI 2.0 TMDS 足以承载 |
| 1920x1080@120 | < 350 MHz | ✅ 依然存在 | 传统 HDMI 2.0 TMDS 足以承载 |
👉 结论:显示链路在唤醒后从 HDMI 2.1 的 FRL(Fixed Rate Link)模式掉回了老旧的 TMDS(HDMI 2.0)模式!因此驱动按照 TMDS 的带宽上限把所有超出带宽的 4K 高刷模式全部裁决丢弃了。
2.2 确认不是 EDID 数据损坏
会不会是睡眠唤醒时 I2C 通信丢包导致 EDID 没读全?
用 edid-decode 解析一下驱动导出的原始 EDID:
1 | |
输出解析结果非常健康:Base EDID、CTA-861 和 DisplayID 三个 Block 校验和全部一致,DisplayID 里清清楚楚写着:
DTD: 3840x2160 100.000 HzDTD: 3840x2160 120.000 HzDTD: 3840x2160 143.998650 Hz
这证明:显示器汇报的能力完好无损,纯粹是驱动层面没有激活高刷链路。
2.3 排除 KWin / 桌面环境层的问题
为了确认是不是 KWin 的缓存机制在作祟,直接查 DRM 底层连接器:
1 | |
内核层面汇报的模式列表同样没有 4K144。说明模式在驱动内核层就已经被过滤掉了,与上层的 Wayland 合成器无关。
同时,尝试过以下软件级重置,全部无效:
kscreen-doctor output.HDMI-A-1.disable && kscreen-doctor output.HDMI-A-1.enable❌kscreen-doctor --dpms off && kscreen-doctor --dpms on❌modetest -c触发接口重探 ❌
原因在于:NVIDIA 驱动把“当前协商好的链路能力”缓存在 Connector 对象上。单纯的软件 modeset 根本不会触发底层的 HDMI 重新握手,只有收到 HPD(Hot Plug Detect,热插拔中断信号)时,驱动才会重新进行 FRL Link Training。
3. 根因确认:NVIDIA 的已知 Bug
至此,问题定性:NVIDIA Linux 驱动在 Suspend/Resume 唤醒后,未对 HDMI 2.1 FRL 链路重新进行 Link Training,而是直接粗暴退回到了 TMDS 模式。
经过检索,这在 NVIDIA 官方论坛是一个被多位用户确认的已知 Bug:
- Bug 编号:
5801388 - 官方论坛讨论帖:Monitor refresh rate bugs out after going to sleep
- 截至目前,最新的驱动分支(包括 580xx 以及 610.xx 测试版)仍未彻底修复该问题。
既然知道了只有 HPD 能触发重新协商,我们难道真的只能每次去拔线或者按物理电源键吗?
当然不用,Linux 下我们有 DDC/CI。
4. 优雅破局:利用 DDC/CI 模拟硬件热插拔
几乎所有现代显示器都支持 DDC/CI 协议,它允许主机通过 I2C 信号控制显示器的菜单设置和电源状态。
既然拔插线缆和按电源键本质上是切断显示器信号引发一次 HPD,我们完全可以通过软件向显示器下发 D6 05(关机) 和 D6 01(开机) 控制码,让显示器原地“重启”一次。
4.1 安装并测试 ddcutil
首先安装命令行工具:
1 | |
检测当前外接显示器支持情况:
1 | |
正常会检测到类似输出:
1 | |
确认电源控制(VCP code D6)可用:
1 | |
4.2 手动急救一行流
当唤醒发现刷新率掉了之后,只需在终端敲入以下指令:
1 | |
实测一秒见效:显示器息屏 4 秒后重新点亮,NVIDIA 驱动受到 HPD 刺激后重新完成了 FRL 协商,4K100/120/144 全部满血复活!并且 HDR 状态、200% 显示缩放以及窗口布局丝毫不受影响。
5. 优化体验:配置全自动唤醒修复服务
我们可以编写一个检测脚本,并将其挂载到 systemd 的睡眠唤醒 hook 中。
5.1 编写急救脚本 ~/.local/bin/fix-hdmi-refresh
这个脚本会先检查当前是不是已经在 144Hz:如果是,直接静默退出(不闪屏);如果高刷模式丢了,才执行显示器电源重启并套用 144Hz。
创建脚本 ~/.local/bin/fix-hdmi-refresh:
1 | |
赋予执行权限:
1 | |
5.2 挂载 systemd sleep hook 实现唤醒自动修复
在 /etc/systemd/system-sleep/ 目录下添加一个唤醒执行钩子。系统睡眠唤醒(post 阶段)时,会自动以当前桌面用户的身份调用上述急救脚本。
创建脚本 /etc/systemd/system-sleep/99-hdmi-frl-refresh.sh:
1 | |
赋予 root 执行权限:
1 | |
自动化工作流解析
- 电脑唤醒后,systemd sleep hook 被触发,先等待 4 秒让驱动与 KWin 重新就绪;
- 检测当前是否依然维持 4K144:若显示器没有完全睡死、高刷还在,脚本直接退出,屏幕完全不闪烁;
- 若检测到高刷丢失(模式消失),自动发送 DDC 指令重启显示器并重新绑定 144Hz。从唤醒到完全自动搞定只需数秒,再也不用手动折腾!
6. 其他替代思路
转投 DP:如果显示器和拓展坞/显卡支持 DP 1.4,可以改用 DP 线。DisplayPort 不使用 HDMI 的 FRL 机制(通常通过 DSC 压缩上 4K144),完全不受 NVIDIA 该 Bug 的影响。
// HDMI本质一坨啊之前拒绝AMD为开源驱动提供 HDMI 2.1 支持的时候就看出来了,但是手里只有 HDMI 线一直懒得买 DP 线了:(