From 6cfd04b018f0a37e6d499ffd8382ff93c3f80798 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 30 Oct 2018 17:19:22 -0700 Subject: [PATCH] drm/i915/dp: Validate modes using max Output BPP and slice count when DSC supported When DSC is supported we need to validate the modes based on the maximum supported compressed BPP and maximum supported slice count. This allows us to allow the modes with pixel clock greater than the available link BW as long as it meets the compressed BPP and slice count requirements. v3: * Use the macro for dsc sink support (Jani N) v2: * Properly comment why we are right shifting the bpp value (Anusha) Cc: Gaurav K Singh Cc: Jani Nikula Cc: Ville Syrjala Cc: Anusha Srivatsa Signed-off-by: Manasi Navare Reviewed-by: Anusha Srivatsa Reviewed-by: Gaurav K Singh Link: https://patchwork.freedesktop.org/patch/msgid/20181031001923.31442-6-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 11412b21a1c7..03b8e5104ead 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -635,9 +635,12 @@ intel_dp_mode_valid(struct drm_connector *connector, struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; + struct drm_i915_private *dev_priv = to_i915(connector->dev); int target_clock = mode->clock; int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk; + u16 dsc_max_output_bpp = 0; + u8 dsc_slice_count = 0; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -660,7 +663,33 @@ intel_dp_mode_valid(struct drm_connector *connector, max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); mode_rate = intel_dp_link_required(target_clock, 18); - if (mode_rate > max_rate || target_clock > max_dotclk) + /* + * Output bpp is stored in 6.4 format so right shift by 4 to get the + * integer value since we support only integer values of bpp. + */ + if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && + drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { + if (intel_dp_is_edp(intel_dp)) { + dsc_max_output_bpp = + drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; + dsc_slice_count = + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, + true); + } else { + dsc_max_output_bpp = + intel_dp_dsc_get_output_bpp(max_link_clock, + max_lanes, + target_clock, + mode->hdisplay) >> 4; + dsc_slice_count = + intel_dp_dsc_get_slice_count(intel_dp, + target_clock, + mode->hdisplay); + } + } + + if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) || + target_clock > max_dotclk) return MODE_CLOCK_HIGH; if (mode->clock < 10000) -- 2.30.2