From: Hugo Sales <hugo@hsal.es>
To: amd-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
harry.wentland@amd.com, sunpeng.li@amd.com, siqueira@igalia.com,
alexander.deucher@amd.com, "Chung,
ChiaHsuan (Tom)" <chiahsuan.chung@amd.com>
Subject: [PATCH v2 1/2] drm/amd/display: Fall back to the native mode, not the first, on eDP/LVDS
Date: Sat, 24 Oct 2026 17:33:46 +0100 [thread overview]
Message-ID: <20261024163347.2413649-2-hugo@hsal.es> (raw)
In-Reply-To: <20261024163347.2413649-1-hugo@hsal.es>
Currently, create_stream_for_sink() takes the native timing for a scaled
mode from the preferred mode in connector->modes. After fbdev emulation
probes with size limits below the native resolution, as it does when
video= sets a smaller mode, that mode is no longer in the list
If that probe is the last one before a suspend, for example after an
HDMI hotplug, the resume finds no preferred mode, and the panel is
driven with the scaled mode's timing instead of its own
amdgpu_dm_get_native_mode() copies the preferred mode to the encoder on
every probe, before the size limits apply. When connector->modes has no
preferred mode, take a mode of the native size from the list, or that
copy if the limits pruned them all. The list comes first because
mode_valid may have rejected the copy's timing and kept another mode of
the same size. Limit this to eDP and LVDS, where amdgpu turns scaling on
by itself. On other connectors mode_valid can also leave the preferred
mode out, and then the first valid mode is the right fallback
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5983
Signed-off-by: Hugo Sales <hugo@hsal.es>
---
.../display/amdgpu_dm/amdgpu_dm_connector.c | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index ded8e21897f1c..a13e3b641fd27 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -257,6 +257,8 @@ STATIC_IFN_KUNIT void update_subconnector_property(struct amdgpu_dm_connector *a
EXPORT_IF_KUNIT(update_subconnector_property);
STATIC_IFN_KUNIT int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
+STATIC_IFN_KUNIT struct drm_encoder *amdgpu_dm_connector_to_encoder(
+ struct drm_connector *connector);
STATIC_IFN_KUNIT void amdgpu_dm_fbc_init(struct drm_connector *connector)
{
@@ -1545,6 +1547,51 @@ create_stream_for_sink(struct drm_connector *connector,
break;
}
}
+
+ /*
+ * After a probe with size limits smaller than the preferred mode,
+ * connector->modes no longer has that mode, and the first mode left
+ * would become the stream timing. fbdev emulation probes with limits
+ * that video= can set below the native size. Only eDP and LVDS panels
+ * get a fallback here, since they take only their native size. On other
+ * connectors mode_valid can also reject the preferred mode, and then
+ * the first valid mode is the right one
+ *
+ * Take a mode of the native size from connector->modes if one is left,
+ * since mode_valid may have rejected the preferred timing itself. The
+ * probe sorts the list, so the first one has the highest refresh rate
+ * left. If the limits pruned them all, use the copy of the preferred
+ * mode that amdgpu_dm_get_native_mode() keeps in the encoder. It is
+ * made on every probe, before the limits apply
+ */
+ if (!preferred_mode && aconnector && aconnector->drm_edid &&
+ (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+ connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
+ struct drm_encoder *encoder = amdgpu_dm_connector_to_encoder(connector);
+ const struct drm_display_mode *enc_native =
+ encoder ? &to_amdgpu_encoder(encoder)->native_mode : NULL;
+
+ if (enc_native && enc_native->clock) {
+ list_for_each_entry(connector_mode, &connector->modes, head) {
+ if (connector_mode->hdisplay == enc_native->hdisplay &&
+ connector_mode->vdisplay == enc_native->vdisplay) {
+ preferred_mode = connector_mode;
+ break;
+ }
+ }
+
+ /*
+ * saved_mode is only used for FreeSync video modes, and
+ * that path doesn't read preferred_mode
+ */
+ if (!preferred_mode) {
+ drm_mode_init(&saved_mode, enc_native);
+ drm_mode_set_crtcinfo(&saved_mode, CRTC_INTERLACE_HALVE_V);
+ preferred_mode = &saved_mode;
+ }
+ }
+ }
+
if (!preferred_mode)
preferred_mode = list_first_entry_or_null(
&connector->modes,
--
2.55.0
next prev parent reply other threads:[~2026-10-24 16:33 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 22:30 [PATCH 0/2] drm/amd/display: Keep eDP native timing after resume with video= Hugo Sales
2026-10-14 22:30 ` [PATCH 1/2] drm/amd/display: Fall back to the native mode, not the first, on eDP/LVDS Hugo Sales
2026-10-23 18:26 ` Chung, ChiaHsuan (Tom)
2026-10-24 16:33 ` [PATCH v2 0/2] drm/amd/display: Keep eDP native timing after resume with video= Hugo Sales
2026-10-24 16:33 ` Hugo Sales [this message]
2026-10-24 16:33 ` [PATCH v2 2/2] drm/amd/display: Add KUnit tests for the eDP/LVDS native mode fallback Hugo Sales
2026-10-14 22:30 ` [PATCH " Hugo Sales
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261024163347.2413649-2-hugo@hsal.es \
--to=hugo@hsal.es \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=chiahsuan.chung@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=harry.wentland@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=siqueira@igalia.com \
--cc=sunpeng.li@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®