RE: [PATCH v2 7/8] drm/i915/dp: Allow PCON DSC modes through FRL bw check

"Kandpal, Suraj" <[email protected]>
Newsgroups org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe
Message-ID <DS4PPFE901A304FC112C1673FCCD31ED8E9E3DD2@DS4PPFE901A304F.namprd11.prod.outlook.com>
> Subject: [PATCH v2 7/8] drm/i915/dp: Allow PCON DSC modes through FRL bw
> check
> 
> intel_dp_frl_bw_valid() rejects any mode whose uncompressed FRL bandwidth
> exceeds the PCON/sink max FRL bandwidth, even though we are capable of
> enabling PCON DSC encoding at modeset time. As a result, high-bandwidth
> HDMI2.1 modes (e.g. 4K120, 8K60) get pruned for sinks behind a PCON, despite
> the PCON + sink being able to carry them with DSC compression.
> 
> Now, that the HDMI DSC helpers no longer depend on intel_crtc_state, reuse
> them from the FRL bandwidth check. When uncompressed transport does not
> fit, compute the lowest compressed bpp allowed for the output format and
> verify it:
>  - fits the sink's per-scanline chunk-bytes limit and
>  - resulets in the required FRL bandwidth within the PCON/sink limits.

* results

With this fixed LGTM

Reviewed-by: Suraj Kandpal <[email protected]>

> 
> This takes care of the existing FIXME in the FRL bandwidth check.
> 
> Signed-off-by: Ankit Nautiyal <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 80 ++++++++++++++++++++++---
>  1 file changed, 71 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 652215fdb1a7..938e11bc6a46 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -125,6 +125,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
> 
>  static void intel_dp_unset_edid(struct intel_dp *intel_dp);  static int
> intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp);
> +static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp);
> 
>  /* Is link rate UHBR and thus 128b/132b? */  bool intel_dp_is_uhbr(const struct
> intel_crtc_state *crtc_state) @@ -1179,8 +1180,58 @@ static int
> frl_required_bw(int clock, int bpc,
>  	return clock * bpc * 3;
>  }
> 
> +static int frl_required_bw_dsc(int target_clock, int comp_bpp_x16) {
> +	return DIV_ROUND_UP(target_clock * comp_bpp_x16, 16); }
> +
> +static bool
> +intel_dp_pcon_dsc_fits_frl_bw(struct intel_dp *intel_dp,
> +			      const struct drm_display_mode *mode,
> +			      int bpc, enum intel_output_format sink_format,
> +			      int max_frl_bw)
> +{
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	const struct drm_display_info *info = &connector->base.display_info;
> +	int min_dsc_bpp, max_dsc_bpp;
> +	int num_slices, slice_width;
> +	int hdmi_max_chunk_bytes;
> +	int pcon_max_slices, pcon_max_slice_width;
> +
> +	/* PCON and HDMI sink must both support DSC 1.2 */
> +	if (!info->hdmi.dsc_cap.v_1p2 ||
> +	    !drm_dp_pcon_enc_is_dsc_1_2(intel_dp->pcon_dsc_dpcd))
> +		return false;
> +
> +	pcon_max_slices = drm_dp_pcon_dsc_max_slices(intel_dp-
> >pcon_dsc_dpcd);
> +	pcon_max_slice_width =
> +drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd);
> +
> +	num_slices = intel_hdmi_dsc_get_num_slices(mode, sink_format,
> +						   pcon_max_slices,
> +						   pcon_max_slice_width,
> +						   info-
> >hdmi.dsc_cap.max_slices,
> +						   info-
> >hdmi.dsc_cap.clk_per_slice);
> +	if (!num_slices)
> +		return false;
> +
> +	slice_width = DIV_ROUND_UP(mode->hdisplay, num_slices);
> +
> +	intel_hdmi_dsc_get_min_max_bpp(sink_format, bpc, info-
> >hdmi.dsc_cap.all_bpp,
> +				       &min_dsc_bpp, &max_dsc_bpp);
> +
> +	/* Use the lowest allowed compressed bpp for the best-case bandwidth
> */
> +	hdmi_max_chunk_bytes = info->hdmi.dsc_cap.total_chunk_kbytes *
> 1024;
> +	if (!intel_hdmi_dsc_bpp_fits_chunk_bytes(min_dsc_bpp, num_slices,
> slice_width,
> +						 hdmi_max_chunk_bytes))
> +		return false;
> +
> +	return frl_required_bw_dsc(mode->clock, min_dsc_bpp * 16) <=
> +max_frl_bw; }
> +
>  static enum drm_mode_status
> -intel_dp_frl_bw_valid(struct intel_dp *intel_dp, int target_clock,
> +intel_dp_frl_bw_valid(struct intel_dp *intel_dp,
> +		      const struct drm_display_mode *mode,
> +		      int target_clock,
>  		      int bpc, enum intel_output_format sink_format,
>  		      bool respect_downstream_limits)  { @@ -1199,11 +1250,19
> @@ intel_dp_frl_bw_valid(struct intel_dp *intel_dp, int target_clock,
>  	/* converting bw from Gbps to Kbps*/
>  	max_frl_bw = max_frl_bw * 1000000;
> 
> -	/* #FIXME check bandwidth with DSC if both PCON and HDMI sink
> support DSC */
> -	if (target_bw > max_frl_bw)
> -		return MODE_CLOCK_HIGH;
> +	if (target_bw <= max_frl_bw)
> +		return MODE_OK;
> 
> -	return MODE_OK;
> +	/*
> +	 * Uncompressed transport doesn't fit; if both PCON and HDMI sink
> +	 * support DSC, check whether DSC compression brings it within limits.
> +	 */
> +	if (intel_dp_is_hdmi_2_1_sink(intel_dp) &&
> +	    intel_dp_pcon_dsc_fits_frl_bw(intel_dp, mode, bpc, sink_format,
> +					  max_frl_bw))
> +		return MODE_OK;
> +
> +	return MODE_CLOCK_HIGH;
>  }
> 
>  static bool
> @@ -1215,13 +1274,14 @@ intel_dp_pcon_sink_support_frl(struct intel_dp
> *intel_dp)
> 
>  static enum drm_mode_status
>  intel_dp_hdmi_bw_valid(struct intel_dp *intel_dp,
> +		       const struct drm_display_mode *mode,
>  		       int target_clock, int bpc,
>  		       enum intel_output_format sink_format,
>  		       bool respect_downstream_limits)  {
>  	if (intel_dp_pcon_sink_support_frl(intel_dp))
> -		return intel_dp_frl_bw_valid(intel_dp, target_clock, bpc,
> -					     sink_format,
> +		return intel_dp_frl_bw_valid(intel_dp, mode,
> +					     target_clock, bpc, sink_format,
>  					     respect_downstream_limits);
> 
>  	return intel_dp_tmds_clock_valid(intel_dp, target_clock, bpc,
> sink_format, @@ -1241,7 +1301,8 @@
> intel_dp_mode_valid_downstream(struct intel_connector *connector,
>  	    target_clock > intel_dp->dfp.max_dotclock)
>  		return MODE_CLOCK_HIGH;
> 
> -	return intel_dp_hdmi_bw_valid(intel_dp, target_clock, bpc,
> sink_format, true);
> +	return intel_dp_hdmi_bw_valid(intel_dp, mode, target_clock, bpc,
> +				      sink_format, true);
>  }
> 
>  static enum drm_mode_status
> @@ -1661,7 +1722,8 @@ static int intel_dp_hdmi_compute_bpc(struct
> intel_dp *intel_dp,
>  	for (; bpc >= 8; bpc -= 2) {
>  		if (intel_hdmi_bpc_possible(crtc_state, bpc,
>  					    intel_dp_has_hdmi_sink(intel_dp))
> &&
> -		    intel_dp_hdmi_bw_valid(intel_dp, clock, bpc, crtc_state-
> >sink_format,
> +		    intel_dp_hdmi_bw_valid(intel_dp, &crtc_state-
> >hw.adjusted_mode,
> +					   clock, bpc, crtc_state->sink_format,
>  					   respect_downstream_limits) ==
> MODE_OK)
>  			return bpc;
>  	}
> --
> 2.50.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.