Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <gaurav.k.singh@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Reviewed-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Reviewed-by: Gaurav K Singh <gaurav.k.singh@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181031001923.31442-6-manasi.d.navare@intel.com

+30 -1
+30 -1
drivers/gpu/drm/i915/intel_dp.c
··· 635 635 struct intel_dp *intel_dp = intel_attached_dp(connector); 636 636 struct intel_connector *intel_connector = to_intel_connector(connector); 637 637 struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; 638 + struct drm_i915_private *dev_priv = to_i915(connector->dev); 638 639 int target_clock = mode->clock; 639 640 int max_rate, mode_rate, max_lanes, max_link_clock; 640 641 int max_dotclk; 642 + u16 dsc_max_output_bpp = 0; 643 + u8 dsc_slice_count = 0; 641 644 642 645 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 643 646 return MODE_NO_DBLESCAN; ··· 663 660 max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); 664 661 mode_rate = intel_dp_link_required(target_clock, 18); 665 662 666 - if (mode_rate > max_rate || target_clock > max_dotclk) 663 + /* 664 + * Output bpp is stored in 6.4 format so right shift by 4 to get the 665 + * integer value since we support only integer values of bpp. 666 + */ 667 + if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && 668 + drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { 669 + if (intel_dp_is_edp(intel_dp)) { 670 + dsc_max_output_bpp = 671 + drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; 672 + dsc_slice_count = 673 + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, 674 + true); 675 + } else { 676 + dsc_max_output_bpp = 677 + intel_dp_dsc_get_output_bpp(max_link_clock, 678 + max_lanes, 679 + target_clock, 680 + mode->hdisplay) >> 4; 681 + dsc_slice_count = 682 + intel_dp_dsc_get_slice_count(intel_dp, 683 + target_clock, 684 + mode->hdisplay); 685 + } 686 + } 687 + 688 + if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) || 689 + target_clock > max_dotclk) 667 690 return MODE_CLOCK_HIGH; 668 691 669 692 if (mode->clock < 10000)