DP MSA MISC1[6] (DP_MSA_MISC_COLOR_VSC_SDP) tells the sink to derive
colorimetry information from VSC SDP rather than from MSA fields. This
bit should only be set when a VSC SDP with colorimetry is actually being
transmitted.

When a sink does not advertise colorimetry support via VSC SDP
(DPCD 0x2210[3] = 0), intel_dp_compute_vsc_sdp() correctly skips
sending the VSC SDP. However, intel_ddi_set_dp_msa() unconditionally
sets MISC1[6] whenever intel_dp_needs_vsc_sdp() returns true (e.g. for
BT.2020 colorspace), without checking whether the VSC SDP will actually
be sent.

This mismatch causes the sink to ignore MSA colorimetry fields and wait
for a VSC SDP that never arrives, resulting in incorrect colorimetry
decoding and visible color errors.

Fix by gating MISC1[6] on intel_dp->colorimetry_support, mirroring the
check already present in intel_dp_compute_vsc_sdp(). Retain the
has_psr exception since PSR also uses VSC SDP independently of
colorimetry support.

Signed-off-by: Xiao Lu <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 2b7eb010511b..f2175f05b42e 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -469,9 +469,20 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state 
*crtc_state,
         * of Color Encoding Format and Content Color Gamut] while sending
         * YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields
         * which indicate VSC SDP for the Pixel Encoding/Colorimetry Format.
+        * Only set when VSC SDP will actually be transmitted with colorimetry;
+        * colorimetry_support=false means the sink didn't advertise the cap via
+        * DPCD 0x2210[3] and intel_dp_compute_vsc_sdp() will skip sending the 
SDP.
+        * Setting this bit without a corresponding VSC SDP causes the sink to
+        * ignore MSA colorimetry and wait for a VSC SDP that never arrives.
         */
-       if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
-               temp |= DP_MSA_MISC_COLOR_VSC_SDP;
+       if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
+               struct intel_connector *connector =
+                       to_intel_connector(conn_state->connector);
+               struct intel_dp *intel_dp = intel_attached_dp(connector);
+
+               if (intel_dp->colorimetry_support || crtc_state->has_psr)
+                       temp |= DP_MSA_MISC_COLOR_VSC_SDP;
+       }
 
        intel_de_write(display, TRANS_MSA_MISC(display, cpu_transcoder),
                       temp);
-- 
2.43.0

Reply via email to