Lenovo Legion 5 Pro stuck with 60Hz on a 165Hz panel
This laptop (Lenovo Legion 5 Pro 2021 16ACH6H) uses a CSOT T3 MNG007DA1-1 165Hz panel. It has two modes toggleable in BIOS: discrete graphics mode and hybrid graphics mode. In discrete graphics mode, the internal display is physically connected to an NVIDIA GPU and works fine. In hybrid graphics mode, it's connected to the internal AMD GPU and is stuck at a 60Hz refresh rate.
Discrete graphics mode
/sys/class/drm/card0-eDP-1/edid
od -Ax -t x1 -v /sys/class/drm/card0-eDP-1/edid
output
od -Ax -t x1 -v /sys/class/drm/card0-eDP-1/edid
output000000 00 ff ff ff ff ff ff 00 0e 6f 00 16 00 00 00 00
000010 00 1e 01 04 b5 22 16 78 03 ee 95 a3 54 4c 99 26
000020 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
000030 01 01 01 01 01 01 6e 6e 00 a0 a0 40 84 60 30 20
000040 36 00 59 d7 10 00 00 18 00 00 00 fd 0c 3c a5 1f
000050 1f 4e 01 0a 20 20 20 20 20 20 00 00 00 fe 00 43
000060 53 4f 54 20 54 33 0a 20 20 20 20 20 00 00 00 fe
000070 00 4d 4e 47 30 30 37 44 41 31 2d 31 0a 20 02 02
000080 02 03 1d 00 e3 05 80 00 e6 06 05 01 6a 6a 24 6d
000090 1a 00 00 02 03 3c a5 00 04 6a 24 6a 24 00 00 00
0000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff
000100 70 13 79 00 00 03 01 14 ac 2f 01 85 ff 09 9f 00
000110 2f 00 1f 00 3f 06 83 00 02 00 05 00 00 00 00 00
000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 90
000180
Hybrid graphics mode
/sys/class/drm/card0-eDP-1/edid
od -Ax -t x1 -v /sys/class/drm/card0-eDP-1/edid
output
od -Ax -t x1 -v /sys/class/drm/card0-eDP-1/edid
output000000 00 ff ff ff ff ff ff 00 0e 6f 00 16 00 00 00 00
000010 00 1e 01 04 b5 22 16 78 03 ee 95 a3 54 4c 99 26
000020 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
000030 01 01 01 01 01 01 6e 6e 00 a0 a0 40 84 60 30 20
000040 36 00 59 d7 10 00 00 18 00 00 00 fd 0c 3c a5 1f
000050 1f 4e 01 0a 20 20 20 20 20 20 00 00 00 fe 00 43
000060 53 4f 54 20 54 33 0a 20 20 20 20 20 00 00 00 fe
000070 00 4d 4e 47 30 30 37 44 41 31 2d 31 0a 20 01 03
000080 02 03 1d 00 e3 05 80 00 e6 06 05 01 6a 6a 24 6d
000090 1a 00 00 02 03 3c a5 00 04 6a 24 6a 24 00 00 00
0000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff
000100
Relevant journalctl
log
journalctl
logkernel: EDID block 2 (tag 0x70) checksum is invalid, remainder is 130
kernel: [00] GOOD 00 ff ff ff ff ff ff 00 0e 6f 00 16 00 00 00 00
kernel: [00] GOOD 00 1e 01 04 b5 22 16 78 03 ee 95 a3 54 4c 99 26
kernel: [00] GOOD 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
kernel: [00] GOOD 01 01 01 01 01 01 6e 6e 00 a0 a0 40 84 60 30 20
kernel: [00] GOOD 36 00 59 d7 10 00 00 18 00 00 00 fd 0c 3c a5 1f
kernel: [00] GOOD 1f 4e 01 0a 20 20 20 20 20 20 00 00 00 fe 00 43
kernel: [00] GOOD 53 4f 54 20 54 33 0a 20 20 20 20 20 00 00 00 fe
kernel: [00] GOOD 00 4d 4e 47 30 30 37 44 41 31 2d 31 0a 20 02 02
kernel: [01] GOOD 02 03 1d 00 e3 05 80 00 e6 06 05 01 6a 6a 24 6d
kernel: [01] GOOD 1a 00 00 02 03 3c a5 00 04 6a 24 6a 24 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [01] GOOD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff
kernel: [02] BAD 70 13 79 00 00 03 01 14 ac 2f 01 85 ff 09 9f 00
kernel: [02] BAD 2f 00 1f 00 3f 06 83 00 02 00 05 00 00 00 00 00
kernel: [02] BAD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [02] BAD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [02] BAD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [02] BAD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [02] BAD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
kernel: [02] BAD 87 00 87 00 00 00 00 00 00 00 00 00 00 00 37 90
Cause
From what I could gather, in hybrid mode, the laptop incorrectly reports 2 bytes as 0x87 where zeroes should be. This results in an invalid checksum, causing the extension block containing timings to be dismissed.
Proposed solution
Add a quirk to treat 0x87 bytes as zeroes for this specific panel.