Commit dc59990e authored by Ankit Nautiyal's avatar Ankit Nautiyal
Browse files

drm/i915/dp: Iterate over output bpp with fractional step size



This patch adds support to iterate over compressed output bpp as per the
fractional step, supported by DP sink.

v2:
-Avoid ending up with compressed bpp, same as pipe bpp. (Stan)

Signed-off-by: default avatarAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: default avatarSuraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: default avatarSui Jingfeng <suijingfeng@loongson.cn>
Link: https://patchwork.freedesktop.org/patch/msgid/20231110101020.4067342-7-ankit.k.nautiyal@intel.com
parent 2df50cb4
Loading
Loading
Loading
Loading
+25 −16
Original line number Diff line number Diff line
@@ -1737,15 +1737,15 @@ static bool intel_dp_dsc_supports_format(const struct intel_connector *connector
	return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format);
}

static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_clock,
					    u32 lane_count, u32 mode_clock,
					    enum intel_output_format output_format,
					    int timeslots)
{
	u32 available_bw, required_bw;

	available_bw = (link_clock * lane_count * timeslots)  / 8;
	required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
	available_bw = (link_clock * lane_count * timeslots * 16)  / 8;
	required_bw = compressed_bppx16 * (intel_dp_mode_to_fec_clock(mode_clock));

	return available_bw > required_bw;
}
@@ -1753,7 +1753,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
static int dsc_compute_link_config(struct intel_dp *intel_dp,
				   struct intel_crtc_state *pipe_config,
				   struct link_config_limits *limits,
				   u16 compressed_bpp,
				   u16 compressed_bppx16,
				   int timeslots)
{
	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
@@ -1768,8 +1768,8 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
		for (lane_count = limits->min_lane_count;
		     lane_count <= limits->max_lane_count;
		     lane_count <<= 1) {
			if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count,
							     adjusted_mode->clock,
			if (!is_bw_sufficient_for_dsc_config(compressed_bppx16, link_rate,
							     lane_count, adjusted_mode->clock,
							     pipe_config->output_format,
							     timeslots))
				continue;
@@ -1882,7 +1882,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
		ret = dsc_compute_link_config(intel_dp,
					      pipe_config,
					      limits,
					      valid_dsc_bpp[i],
					      valid_dsc_bpp[i] << 4,
					      timeslots);
		if (ret == 0) {
			pipe_config->dsc.compressed_bpp_x16 =
@@ -1902,6 +1902,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
 */
static int
xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
			      const struct intel_connector *connector,
			      struct intel_crtc_state *pipe_config,
			      struct link_config_limits *limits,
			      int dsc_max_bpp,
@@ -1909,23 +1910,31 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
			      int pipe_bpp,
			      int timeslots)
{
	u16 compressed_bpp;
	u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
	u16 compressed_bppx16;
	u8 bppx16_step;
	int ret;

	if (DISPLAY_VER(i915) < 14 || bppx16_incr <= 1)
		bppx16_step = 16;
	else
		bppx16_step = 16 / bppx16_incr;

	/* Compressed BPP should be less than the Input DSC bpp */
	dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
	dsc_max_bpp = min(dsc_max_bpp << 4, (pipe_bpp << 4) - bppx16_step);
	dsc_min_bpp = dsc_min_bpp << 4;

	for (compressed_bpp = dsc_max_bpp;
	     compressed_bpp >= dsc_min_bpp;
	     compressed_bpp--) {
	for (compressed_bppx16 = dsc_max_bpp;
	     compressed_bppx16 >= dsc_min_bpp;
	     compressed_bppx16 -= bppx16_step) {
		ret = dsc_compute_link_config(intel_dp,
					      pipe_config,
					      limits,
					      compressed_bpp,
					      compressed_bppx16,
					      timeslots);
		if (ret == 0) {
			pipe_config->dsc.compressed_bpp_x16 =
				to_bpp_x16(compressed_bpp);
			pipe_config->dsc.compressed_bpp_x16 = compressed_bppx16;
			return 0;
		}
	}
@@ -1963,7 +1972,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
	dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));

	if (DISPLAY_VER(i915) >= 13)
		return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits,
		return xelpd_dsc_compute_link_config(intel_dp, connector, pipe_config, limits,
						     dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
	return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
					   dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);