Commit 5ec260d7 authored by Ankit Nautiyal's avatar Ankit Nautiyal
Browse files

drm/i915/dp: Account for DSC slice overhead



Account for DSC slice overhead bubbles and adjust the pixel rate while
checking the pixel rate against the max dotclock limits.

v2: Add missing assignment for dsc_slice_count in
mst_connector_mode_valid_ctx(). (Imre)

v3: Explicitly pass dsc_slice_count as 0 for Non-DSC case. (Imre)

Signed-off-by: default avatarAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260202103731.357416-15-ankit.k.nautiyal@intel.com
parent 0bdd29f5
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -1414,6 +1414,8 @@ bool intel_dp_can_join(struct intel_display *display,

bool intel_dp_dotclk_valid(struct intel_display *display,
			   int target_clock,
			   int htotal,
			   int dsc_slice_count,
			   int num_joined_pipes)
{
	int max_dotclk = display->cdclk.max_dotclk_freq;
@@ -1421,6 +1423,12 @@ bool intel_dp_dotclk_valid(struct intel_display *display,

	effective_dotclk_limit = max_dotclk * num_joined_pipes;

	if (dsc_slice_count)
		target_clock = intel_dsc_get_pixel_rate_with_dsc_bubbles(display,
									 target_clock,
									 htotal,
									 dsc_slice_count);

	return target_clock <= effective_dotclk_limit;
}

@@ -1553,8 +1561,13 @@ intel_dp_mode_valid(struct drm_connector *_connector,
		if (status != MODE_OK)
			continue;

		if (!dsc)
			dsc_slice_count = 0;

		if (!intel_dp_dotclk_valid(display,
					   target_clock,
					   mode->htotal,
					   dsc_slice_count,
					   num_joined_pipes)) {
			status = MODE_CLOCK_HIGH;
			continue;
@@ -2816,6 +2829,8 @@ intel_dp_compute_link_for_joined_pipes(struct intel_encoder *encoder,
		if (ret ||
		    !intel_dp_dotclk_valid(display,
					   adjusted_mode->crtc_clock,
					   adjusted_mode->crtc_htotal,
					   0,
					   num_joined_pipes))
			dsc_needed = true;
	}
@@ -2826,6 +2841,8 @@ intel_dp_compute_link_for_joined_pipes(struct intel_encoder *encoder,
	}

	if (dsc_needed) {
		int dsc_slice_count;

		drm_dbg_kms(display->drm,
			    "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
			    str_yes_no(ret), str_yes_no(joiner_needs_dsc),
@@ -2842,8 +2859,12 @@ intel_dp_compute_link_for_joined_pipes(struct intel_encoder *encoder,
		if (ret < 0)
			return ret;

		dsc_slice_count = intel_dsc_line_slice_count(&pipe_config->dsc.slice_config);

		if (!intel_dp_dotclk_valid(display,
					   adjusted_mode->crtc_clock,
					   adjusted_mode->crtc_htotal,
					   dsc_slice_count,
					   num_joined_pipes))
			return -EINVAL;
	}
+2 −0
Original line number Diff line number Diff line
@@ -226,6 +226,8 @@ bool intel_dp_can_join(struct intel_display *display,
		       int num_joined_pipes);
bool intel_dp_dotclk_valid(struct intel_display *display,
			   int target_clock,
			   int htotal,
			   int dsc_slice_count,
			   int num_joined_pipes);

#endif /* __INTEL_DP_H__ */
+20 −0
Original line number Diff line number Diff line
@@ -626,6 +626,8 @@ static int mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode
		if (ret ||
		    !intel_dp_dotclk_valid(display,
					   adjusted_mode->clock,
					   adjusted_mode->htotal,
					   0,
					   num_joined_pipes))
			dsc_needed = true;
	}
@@ -637,6 +639,8 @@ static int mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode

	/* enable compression if the mode doesn't fit available BW */
	if (dsc_needed) {
		int dsc_slice_count;

		drm_dbg_kms(display->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
			    str_yes_no(ret), str_yes_no(joiner_needs_dsc),
			    str_yes_no(intel_dp->force_dsc_en));
@@ -670,8 +674,12 @@ static int mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode
		if (ret)
			return ret;

		dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, pipe_config);

		if (!intel_dp_dotclk_valid(display,
					   adjusted_mode->clock,
					   adjusted_mode->htotal,
					   dsc_slice_count,
					   num_joined_pipes))
			return -EINVAL;
	}
@@ -1528,6 +1536,8 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector,

	*status = MODE_CLOCK_HIGH;
	for (num_joined_pipes = 1; num_joined_pipes <= I915_MAX_PIPES; num_joined_pipes++) {
		int dsc_slice_count = 0;

		if (connector->force_joined_pipes &&
		    num_joined_pipes != connector->force_joined_pipes)
			continue;
@@ -1546,6 +1556,11 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector,
			 */
			int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);

			dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
								       mode->clock,
								       mode->hdisplay,
								       num_joined_pipes);

			if (!drm_dp_is_uhbr_rate(max_link_clock))
				bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;

@@ -1572,8 +1587,13 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector,
		if (*status != MODE_OK)
			continue;

		if (!dsc)
			dsc_slice_count = 0;

		if (!intel_dp_dotclk_valid(display,
					   mode->clock,
					   mode->htotal,
					   dsc_slice_count,
					   num_joined_pipes)) {
			*status = MODE_CLOCK_HIGH;
			continue;
+0 −1
Original line number Diff line number Diff line
@@ -1104,7 +1104,6 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent,
	drm_dsc_dump_config(p, indent, &crtc_state->dsc.config);
}

static
int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display,
					      int pixel_rate, int htotal,
					      int dsc_horizontal_slices)
+3 −0
Original line number Diff line number Diff line
@@ -41,5 +41,8 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent,
			   const struct intel_crtc_state *crtc_state);
int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state);
unsigned int intel_vdsc_prefill_lines(const struct intel_crtc_state *crtc_state);
int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display,
					      int pixel_rate, int htotal,
					      int dsc_horizontal_slices);

#endif /* __INTEL_VDSC_H__ */