Commit 72b2d2a6 authored by Imre Deak's avatar Imre Deak
Browse files

drm/i915/dp: Factor out helpers to compute the link limits



Factor out helpers that DP / DP_MST encoders can use to compute the link
rate/lane count and bpp limits. A follow-up patch will call these to
recalculate the limits if DSC compression is required.

Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230921195159.2646027-2-imre.deak@intel.com
parent f83b94d2
Loading
Loading
Loading
Loading
+38 −23
Original line number Diff line number Diff line
@@ -2188,29 +2188,25 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
	return 0;
}

static int
intel_dp_compute_link_config(struct intel_encoder *encoder,
			     struct intel_crtc_state *pipe_config,
			     struct drm_connector_state *conn_state,
			     bool respect_downstream_limits)
static void
intel_dp_compute_config_limits(struct intel_dp *intel_dp,
			       struct intel_crtc_state *crtc_state,
			       bool respect_downstream_limits,
			       struct link_config_limits *limits)
{
	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
	const struct drm_display_mode *adjusted_mode =
		&pipe_config->hw.adjusted_mode;
	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
	struct link_config_limits limits;
	bool joiner_needs_dsc = false;
	int ret;
		&crtc_state->hw.adjusted_mode;

	limits.min_rate = intel_dp_common_rate(intel_dp, 0);
	limits.max_rate = intel_dp_max_link_rate(intel_dp);
	limits->min_rate = intel_dp_common_rate(intel_dp, 0);
	limits->max_rate = intel_dp_max_link_rate(intel_dp);

	limits.min_lane_count = 1;
	limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
	limits->min_lane_count = 1;
	limits->max_lane_count = intel_dp_max_lane_count(intel_dp);

	limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);
	limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config, respect_downstream_limits);
	limits->min_bpp = intel_dp_min_bpp(crtc_state->output_format);
	limits->max_bpp = intel_dp_max_bpp(intel_dp, crtc_state,
					   respect_downstream_limits);

	if (intel_dp->use_max_params) {
		/*
@@ -2221,16 +2217,35 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
		 * configuration, and typically on older panels these
		 * values correspond to the native resolution of the panel.
		 */
		limits.min_lane_count = limits.max_lane_count;
		limits.min_rate = limits.max_rate;
		limits->min_lane_count = limits->max_lane_count;
		limits->min_rate = limits->max_rate;
	}

	intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
	intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);

	drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "
		    "max rate %d max bpp %d pixel clock %iKHz\n",
		    limits.max_lane_count, limits.max_rate,
		    limits.max_bpp, adjusted_mode->crtc_clock);
		    limits->max_lane_count, limits->max_rate,
		    limits->max_bpp, adjusted_mode->crtc_clock);
}

static int
intel_dp_compute_link_config(struct intel_encoder *encoder,
			     struct intel_crtc_state *pipe_config,
			     struct drm_connector_state *conn_state,
			     bool respect_downstream_limits)
{
	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
	const struct drm_display_mode *adjusted_mode =
		&pipe_config->hw.adjusted_mode;
	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
	struct link_config_limits limits;
	bool joiner_needs_dsc = false;
	int ret;

	intel_dp_compute_config_limits(intel_dp, pipe_config,
				       respect_downstream_limits, &limits);

	if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
				    adjusted_mode->crtc_clock))
+30 −22
Original line number Diff line number Diff line
@@ -293,6 +293,35 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
	return 0;
}

static void
intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
				   struct intel_crtc_state *crtc_state,
				   struct link_config_limits *limits)
{
	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	limits->min_rate = limits->max_rate =
		intel_dp_max_link_rate(intel_dp);

	limits->min_lane_count = limits->max_lane_count =
		intel_dp_max_lane_count(intel_dp);

	limits->min_bpp = intel_dp_min_bpp(crtc_state->output_format);
	/*
	 * FIXME: If all the streams can't fit into the link with
	 * their current pipe_bpp we should reduce pipe_bpp across
	 * the board until things start to fit. Until then we
	 * limit to <= 8bpc since that's what was hardcoded for all
	 * MST streams previously. This hack should be removed once
	 * we have the proper retry logic in place.
	 */
	limits->max_bpp = min(crtc_state->pipe_bpp, 24);

	intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
}

static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
				       struct intel_crtc_state *pipe_config,
				       struct drm_connector_state *conn_state)
@@ -312,28 +341,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
	pipe_config->has_pch_encoder = false;

	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	limits.min_rate =
	limits.max_rate = intel_dp_max_link_rate(intel_dp);

	limits.min_lane_count =
	limits.max_lane_count = intel_dp_max_lane_count(intel_dp);

	limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);
	/*
	 * FIXME: If all the streams can't fit into the link with
	 * their current pipe_bpp we should reduce pipe_bpp across
	 * the board until things start to fit. Until then we
	 * limit to <= 8bpc since that's what was hardcoded for all
	 * MST streams previously. This hack should be removed once
	 * we have the proper retry logic in place.
	 */
	limits.max_bpp = min(pipe_config->pipe_bpp, 24);

	intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
	intel_dp_mst_compute_config_limits(intel_dp, pipe_config, &limits);

	ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
					       conn_state, &limits);