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
