[PATCH v2 0/2] drm/amd/display: Keep eDP native timing after resume with video=
From: Hugo Sales
Date: Sat Oct 24 2026 - 12:34:09 EST
On a 3840x2400 eDP panel booted with video=eDP-1:1920x1200@60, an HDMI
hotplug followed by suspend/resume brings the panel back with the
1920x1200 mode as its raw timing. The image ends up squeezed into the
top-left corner. Photos, hardware details and the test loop are in
https://gitlab.freedesktop.org/drm/amd/-/issues/5983
The hotplug makes fbdev emulation reprobe every connector with its
framebuffer size as the limit, so connector->modes loses the 3840x2400
mode. On resume, create_stream_for_sink() finds no preferred mode in the
list and scales onto the first mode instead. Patch 1 falls back to a
mode of the native size if the list still has one, and otherwise to the
encoder's native_mode, which amdgpu_dm_get_native_mode() copies from the
preferred mode before the size limits apply. Patch 2 adds KUnit tests
for it
The fallback only applies to eDP and LVDS, where amdgpu turns scaling on
by itself. On other connectors the preferred mode can also be missing
because mode_valid rejected it, and then scaling onto the first valid
mode is right. From reading the code, other connectors take the same
path when userspace sets the scaling mode property after fbdev pruned
the list, but I haven't tried that, and this series doesn't change it
A fuller amdgpu fix would always drive eDP and LVDS at their native
size, not only when the preferred mode is missing. I kept this to a
fallback so it changes less, but I can respin it that way if you'd
prefer
I left out one other case, also because the fix is big. On eDP the probe
can drop every mode of the native size by itself, for example when
mode_valid rejects the native timing after link training settles on a
lower rate. The list then has no native size mode, and the fallback
takes the encoder's copy, a timing DC may reject, where before it took
the first mode. I have a follow-up that uses the copy only when the last
probe with room for the native size kept that exact timing, and retries
without it if DC rejects it. It's about 170 lines plus tests, for a case
I haven't hit on hardware. Sashiko, running locally, has no findings on
it, but the instance on the list may see it differently. It replaces
both patches here and is at
https://github.com/someonewithpc/linux/tree/edp-native-mode-validated
I can send it if you think it's worth it
On amd-staging-drm-next before this rebase, with an HDMI hotplug and
suspend/resume (pm_test=platform) in a loop, 28 of 29 resumes came back
with the wrong timing without the patch, and the other showed it
briefly. With it, 169 of 169 were fine. A backport to 7.2.8 went from
103 of 103 bad to 1363 of 1363 good. Those runs predate the lookup of a
native size mode in the list, but in this case the list has none, so
the patch takes the same path. On the current base the
amdgpu_dm_connector KUnit suite passes, 358 of 358. Without the fix, the
new eDP and LVDS tests fail and the HDMI one passes. Without the lookup,
the test with a native size mode in the list fails
I've also sent a DRM core series that fixes the cause for every
driver. It makes drm_client_modeset_probe() probe with the device's
limits and has fbdev's mode pickers check the framebuffer size
themselves. Either series alone fixes the reported bug:
https://lore.kernel.org/all/20261015212545.1989962-1-hugo@xxxxxxx/
v1: https://lore.kernel.org/r/20261014223041.171317-1-hugo@xxxxxxx
Changes in v2:
- Use drm_mode_init() for the on-stack copy of the encoder's native
mode. drm_mode_copy() reads the destination's list head, which was
uninitialized (Sashiko)
- If connector->modes still has a mode of the native size, use it
instead of the encoder's copy, whose timing mode_valid may have
rejected (Sashiko)
- Build the copy in saved_mode, which this path doesn't use, so the
stack frame doesn't grow (Sashiko)
- KUnit cases for each condition of the fallback
- Link the DRM core series, now sent
- Rebased onto amd-staging-drm-next at 77f548b127c6, as Tom Chung
asked. That includes 3299935e65c0 ("drm/amd/display: Use separate
iterator for preferred mode lookup"), which changes the same lookup
but keeps the fall back to the first mode, so this fix still applies.
It now checks for a NULL preferred_mode, since native_mode_found is
gone
Hugo Sales (2):
drm/amd/display: Fall back to the native mode, not the first, on
eDP/LVDS
drm/amd/display: Add KUnit tests for the eDP/LVDS native mode fallback
.../display/amdgpu_dm/amdgpu_dm_connector.c | 47 ++++
.../tests/amdgpu_dm_connector_test.c | 226 +++++++++++++++++-
2 files changed, 271 insertions(+), 2 deletions(-)
base-commit: 77f548b127c6de34ce271fa09ba270cb1ef9f2da
--
2.55.0