[PATCH v2 0/2] drm/client: Keep larger modes in connector->modes on fbdev hotplug

From: Hugo Sales

Date: Sat Oct 24 2026 - 12:54:34 EST


On an ASUS ROG Flow X13 with a 3840x2400 eDP panel, booted with
video=eDP-1:1920x1200@60, an HDMI hotplug makes fbdev reprobe every
connector with its 1920x1200 framebuffer as the limit. connector->modes
loses the panel's 3840x2400 mode, and after suspend/resume amdgpu drives
the panel with the 1920x1200 timing. The image ends up squeezed into the
top-left corner. Details are in
https://gitlab.freedesktop.org/drm/amd/-/issues/5983

Patch 1 makes drm_client_modeset_probe() probe with the device's
limits and moves the framebuffer size check into the fbdev mode
pickers. Patch 2 adds KUnit tests for it

fbdev's hotplug probe has passed the framebuffer size since 2010
(4abe35204af8). The pickers didn't check mode sizes then, so leaving
larger modes out of the list was what kept fbdev from picking one. They
check the size themselves now, so the probe can use the device's limits
like initial setup, drm_log and GETCONNECTOR already do

The HiBMC thread "[RFC] drm/client: Relax clone mode selection in
drm_client_target_cloned" runs into the same pruning: its 640x480
framebuffer removes 1024x768 from both connectors' lists. With this
series userspace sees that mode again, but fbdev still can't use it, so
this doesn't replace that RFC:
https://lore.kernel.org/r/a48e0b33-7eab-478e-a396-b6e76b7a066f@xxxxxxxxxx

I sent an amdgpu fix for the same symptom separately. On eDP and LVDS
it makes amdgpu fall back to a mode of the native size, or to the
encoder's native mode if the list has none:
https://lore.kernel.org/r/20261024163347.2413649-1-hugo@xxxxxxx
This series fixes the shared mode list for every driver instead. Either
one alone fixes the reported bug, from my testing

On amd-staging-drm-next with only this series applied, with an HDMI
hotplug and suspend/resume (pm_test=platform) in a loop, 255 of 255
resumes kept the native timing. Without it, 28 of 29 came back with the
wrong timing, and the same loop on unpatched v7.2.8 got it wrong in 103
of 103. The drm KUnit tests pass, also under KASAN, which reports
nothing in the code this series touches

Ville, you said the approach should be fine. If this matches what you
had in mind, I'd appreciate an Acked-by or Reviewed-by

Changes in v2:
- Tests: free the picked modes through a KUnit cleanup action, so a
failed assert no longer leaks them, and assert only after dropping
mode_config.mutex. Both came from Sashiko's review of v1
- Tests: add a firmware config test for a tiled connector with missing
tiles, with and without a non-tiled mode that fits
- Check the size of the CRTC's current mode before
drm_client_firmware_config() falls back to it. Without the 640x480
modes, a DisplayPort sink with no mode that fits could reach that
fallback with a mode larger than the framebuffer. Sashiko found this
on a local run over v2, and a new test covers it
- Don't use the firmware config when a lit connector ends up with no
mode. Accepting it would also skip the fallback, which may light up
other connectors on that CRTC. Sashiko found this on a later local run
- Sashiko also found a NULL modes[i]->name print in
drm_client_firmware_config(). It predates this series, so the fix
went out on its own:
https://lore.kernel.org/r/20261022114356.669988-1-hugo@xxxxxxx
- Rebased onto drm-misc-next at cf5d8e390e2a
- v1: https://lore.kernel.org/r/20261015212545.1989962-1-hugo@xxxxxxx

Hugo Sales (2):
drm/client: Probe connectors with the device's mode size limits
drm/tests: Add KUnit tests for the client mode size limits

drivers/gpu/drm/drm_client_modeset.c | 72 ++-
.../gpu/drm/tests/drm_client_modeset_test.c | 498 +++++++++++++++++-
2 files changed, 550 insertions(+), 20 deletions(-)


base-commit: cf5d8e390e2ac2cfa24a50645efdbb9f0eebe65f
--
2.55.0