From 7299b530741e0b6944cbbe29c3c2a02fdfc6e418 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 22 Mar 2022 14:00:11 +0200 Subject: [PATCH] drm/i915/dp: Rework HDMI DFP TMDS clock handling MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Rework the HDMI DFP TMDS clock checks to also check at 8bpc. Previously we only checked the deep color cases. But I suppose a sink could potentially declare "4:2:0 also" modes that only actually fit within its own limits when using 4:2:0. Even if that is too nuts to be real there is no real harm in running through the full checks for everything. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220322120015.28074-9-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_dp.c | 35 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 30d5cad7c7d3..20f713b55a1c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1136,16 +1136,28 @@ static bool intel_dp_is_ycbcr420(struct intel_dp *intel_dp, intel_dp->dfp.ycbcr_444_to_420); } -static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - int bpc) +static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + int bpc) { bool ycbcr420_output = intel_dp_is_ycbcr420(intel_dp, crtc_state); int clock = crtc_state->hw.adjusted_mode.crtc_clock; - return intel_hdmi_bpc_possible(crtc_state, bpc, - intel_dp->has_hdmi_sink, ycbcr420_output) && - intel_dp_tmds_clock_valid(intel_dp, clock, bpc, ycbcr420_output) == MODE_OK; + /* + * Current bpc could already be below 8bpc due to + * FDI bandwidth constraints or other limits. + * HDMI minimum is 8bpc however. + */ + bpc = max(bpc, 8); + + for (; bpc >= 8; bpc -= 2) { + if (intel_hdmi_bpc_possible(crtc_state, bpc, + intel_dp->has_hdmi_sink, ycbcr420_output) && + intel_dp_tmds_clock_valid(intel_dp, clock, bpc, ycbcr420_output) == MODE_OK) + return bpc; + } + + return -EINVAL; } static int intel_dp_max_bpp(struct intel_dp *intel_dp, @@ -1161,10 +1173,13 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp, bpc = min_t(int, bpc, intel_dp->dfp.max_bpc); if (intel_dp->dfp.min_tmds_clock) { - for (; bpc >= 10; bpc -= 2) { - if (intel_dp_hdmi_bpc_possible(intel_dp, crtc_state, bpc)) - break; - } + int max_hdmi_bpc; + + max_hdmi_bpc = intel_dp_hdmi_compute_bpc(intel_dp, crtc_state, bpc); + if (max_hdmi_bpc < 0) + return 0; + + bpc = min(bpc, max_hdmi_bpc); } bpp = bpc * 3; -- 2.11.0