From: "Beat M. Liechti" <beat@softbase.tech>
To: Rob Clark <robin.clark@oss.qualcomm.com>,
Dmitry Baryshkov <lumag@kernel.org>
Cc: Abhinav Kumar <abhinav.kumar@linux.dev>,
Jessica Zhang <jesszhan0024@gmail.com>,
Sean Paul <sean@poorly.run>,
Marijn Suijten <marijn.suijten@somainline.org>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
Federico Amedeo Izzo <federico@izzo.pro>,
linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org,
"Beat M. Liechti" <beat@softbase.tech>,
stable@vger.kernel.org
Subject: [PATCH v2 1/2] drm/msm/dpu: don't reassign resources on color management changes
Date: Sun, 1 Nov 2026 13:26:57 +0100 [thread overview]
Message-ID: <20261101122943.8155-2-beat@softbase.tech> (raw)
In-Reply-To: <20261101122943.8155-1-beat@softbase.tech>
Since commit 39a750ff5fc9 ("drm/msm/dpu: Add DSPP GC driver to provide
GAMMA_LUT DRM property"), dpu_crtc_atomic_check() releases and reserves
the hardware blocks of a CRTC whenever color_mgmt_changed is set, not
only on a modeset. A commit that merely replaces the GAMMA_LUT or CTM
blob of an active CRTC can therefore move that CRTC to a different
CTL/LM pair without disabling and re-enabling the pipeline, and the
hardware keeps scanning out through blocks the driver no longer
considers in use.
This is easy to hit with GNOME/mutter on a laptop driving an external
display: closing the lid disables the eDP CRTC, and in the same atomic
commit mutter sets new color blobs on the still active HDMI CRTC. With
drm.debug enabled, dpu_rm_reserve() moves the HDMI CRTC from CTL_1 to
the just released CTL_0 while its encoder is neither disabled nor
re-enabled. A few seconds later the display SMMU reports context faults
at the refresh rate and the external screen fills with garbage. Opening
the lid again leads to a stream of "vblank timeout" and "frame done
timeout" errors and the machine has to be power cycled.
Color management affects the topology in only one way: DSPP blocks are
requested when either CTM or GAMMA_LUT is set. Handle that case in
dpu_crtc_check_mode_changed() by requiring a full modeset when the
presence of CTM/GAMMA_LUT changes, and stop reallocating resources on a
bare color_mgmt_changed. Don't set allow_modeset here: if userspace
did not allow a modeset, the atomic core rejects the commit instead of
the CRTC being silently moved to other blocks.
Fixes: 39a750ff5fc9 ("drm/msm/dpu: Add DSPP GC driver to provide GAMMA_LUT DRM property")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Beat M. Liechti <beat@softbase.tech>
---
Notes:
Changes in v2:
- Don't set allow_modeset on behalf of userspace; only set mode_changed
and let drm_atomic_check_only() reject commits that did not allow a
modeset (Dmitry)
- New patch 2/2 removes the CTM-only allow_modeset hack from
msm_atomic_check(), which is redundant with this check (Sashiko review)
- Link to v1: https://lore.kernel.org/r/20261101095754.33840-1-beat@softbase.tech
Testing: ThinkPad T14s Gen 6 (X1E78100), GNOME 50 / mutter on Wayland,
LG 4K60 monitor on the HDMI port (DP to HDMI bridge), logind set to not
suspend on lid close while on external power. Without this patch every
lid close reproduces the corruption and hang described above. With it,
closing and opening the lid produces no SMMU faults, vblank timeouts or
frame done timeouts, and both displays keep working.
v2 was retested on the same kernel with both patches applied: lid
close/open, Night Light toggled repeatedly with the lid open and closed,
and a color profile change. No SMMU faults or timeouts, no visual
problems, and with drm.debug=0x16 no commit was rejected for requiring
a modeset, so mutter is not affected by the stricter check.
On msm-next the patch has only been compile tested (W=1, no new
warnings), not run.
The RFC "drm/msm/dpu: Force modeset if new CTLs have been reserved"
(https://lists.freedesktop.org/archives/freedreno/2025-March/036824.html)
addresses reassignment without a modeset in general. This patch only
removes the color management trigger.
The root cause analysis of the drm.debug trace, the fix and the
changelog were developed with an AI coding assistant (Claude by
Anthropic). I reviewed the change and tested it on the hardware above.
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 25 +++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 42d0a529b..cfcc3556a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1516,6 +1516,19 @@ int dpu_crtc_check_mode_changed(struct drm_crtc_state *old_crtc_state,
(!clone_mode_requested && clone_mode_enabled))
new_crtc_state->mode_changed = true;
+ /*
+ * DSPP blocks are reserved only when CTM or GAMMA_LUT is set (see
+ * dpu_crtc_get_topology()), so enabling or disabling color management
+ * changes the hardware topology. Changing resources on an active CRTC
+ * requires a full modeset; otherwise the CTL/LM blocks get swapped
+ * underneath a running pipeline. If userspace did not allow a modeset,
+ * drm_atomic_check_only() rejects the commit.
+ */
+ if (new_crtc_state->enable &&
+ (!!(old_crtc_state->ctm || old_crtc_state->gamma_lut) !=
+ !!(new_crtc_state->ctm || new_crtc_state->gamma_lut)))
+ new_crtc_state->mode_changed = true;
+
return 0;
}
@@ -1534,9 +1547,15 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
- /* don't reallocate resources if only ACTIVE has beeen changed */
- if (crtc_state->mode_changed || crtc_state->connectors_changed ||
- crtc_state->color_mgmt_changed) {
+ /*
+ * Don't reallocate resources if only ACTIVE or color management
+ * values have changed. A change in DSPP requirements is turned into a
+ * modeset by dpu_crtc_check_mode_changed(). Reallocating on a plain
+ * color_mgmt_changed would move an active CRTC to different CTL/LM
+ * blocks without a modeset, leaving the hardware scanning out through
+ * stale CTL/LM state (SMMU faults, corrupted output, vblank timeouts).
+ */
+ if (crtc_state->mode_changed || crtc_state->connectors_changed) {
rc = dpu_crtc_assign_resources(crtc, crtc_state);
if (rc < 0)
return rc;
--
2.53.0
next prev parent reply other threads:[~2026-11-01 12:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 9:57 [PATCH] " Beat M. Liechti
2026-11-01 10:58 ` Dmitry Baryshkov
2026-11-01 12:26 ` [PATCH v2 0/2] drm/msm: fix CTL/LM swap " Beat M. Liechti
2026-11-01 12:26 ` Beat M. Liechti [this message]
2026-11-01 12:26 ` [PATCH v2 2/2] drm/msm: drop the CTM modeset hack from msm_atomic_check() Beat M. Liechti
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=20261101122943.8155-2-beat@softbase.tech \
--to=beat@softbase.tech \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=federico@izzo.pro \
--cc=freedreno@lists.freedesktop.org \
--cc=jesszhan0024@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
--cc=stable@vger.kernel.org \
/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®