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/[email protected]/ v1: https://lore.kernel.org/r/[email protected] 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
