Commit e24bcd34 authored by Manasi Navare's avatar Manasi Navare Committed by Uma Shankar
Browse files

drm/i915/dp: Add all tiled and port sync conns to modeset



If one of the synced crtcs needs a full modeset, we need
to make sure all the synced crtcs are forced a full
modeset.

v3:
* Remove ~BIT(cpu_trans) which is a nop (Ville)
* use get_new_crtc_state and remove error check (Ville)

v2:
* Add tiles based on cpu_trans check (Ville)

Suggested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarManasi Navare <manasi.d.navare@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarUma Shankar <uma.shankar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200214114126.13192-3-manasi.d.navare@intel.com
parent b50a1aa6
Loading
Loading
Loading
Loading
+0 −85
Original line number Diff line number Diff line
@@ -14694,76 +14694,6 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
	return false;
}
static int
intel_modeset_all_tiles(struct intel_atomic_state *state, int tile_grp_id)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;
	int ret = 0;
	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct drm_connector_state *conn_state;
		struct drm_crtc_state *crtc_state;
		if (!connector->has_tile ||
		    connector->tile_group->id != tile_grp_id)
			continue;
		conn_state = drm_atomic_get_connector_state(&state->base,
							    connector);
		if (IS_ERR(conn_state)) {
			ret =  PTR_ERR(conn_state);
			break;
		}
		if (!conn_state->crtc)
			continue;
		crtc_state = drm_atomic_get_crtc_state(&state->base,
						       conn_state->crtc);
		if (IS_ERR(crtc_state)) {
			ret = PTR_ERR(crtc_state);
			break;
		}
		crtc_state->mode_changed = true;
		ret = drm_atomic_add_affected_connectors(&state->base,
							 conn_state->crtc);
		if (ret)
			break;
	}
	drm_connector_list_iter_end(&conn_iter);
	return ret;
}
static int
intel_atomic_check_tiled_conns(struct intel_atomic_state *state)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct drm_connector *connector;
	struct drm_connector_state *old_conn_state, *new_conn_state;
	int i, ret;
	if (INTEL_GEN(dev_priv) < 11)
		return 0;
	/* Is tiled, mark all other tiled CRTCs as needing a modeset */
	for_each_oldnew_connector_in_state(&state->base, connector,
					   old_conn_state, new_conn_state, i) {
		if (!connector->has_tile)
			continue;
		if (!intel_connector_needs_modeset(state, connector))
			continue;
		ret = intel_modeset_all_tiles(state, connector->tile_group->id);
		if (ret)
			return ret;
	}
	return 0;
}
/**
 * intel_atomic_check - validate state object
 * @dev: drm device
@@ -14792,21 +14722,6 @@ static int intel_atomic_check(struct drm_device *dev,
	if (ret)
		goto fail;
	/**
	 * This check adds all the connectors in current state that belong to
	 * the same tile group to a full modeset.
	 * This function directly sets the mode_changed to true and we also call
	 * drm_atomic_add_affected_connectors(). Hence we are not explicitly
	 * calling drm_atomic_helper_check_modeset() after this.
	 *
	 * Fixme: Handle some corner cases where one of the
	 * tiled connectors gets disconnected and tile info is lost but since it
	 * was previously synced to other conn, we need to add that to the modeset.
	 */
	ret = intel_atomic_check_tiled_conns(state);
	if (ret)
		goto fail;
	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
					    new_crtc_state, i) {
		if (!needs_modeset(new_crtc_state)) {
+135 −1
Original line number Diff line number Diff line
@@ -6585,6 +6585,140 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
	}
}

static int intel_modeset_tile_group(struct intel_atomic_state *state,
				    int tile_group_id)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct drm_connector_list_iter conn_iter;
	struct drm_connector *connector;
	int ret = 0;

	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct drm_connector_state *conn_state;
		struct intel_crtc_state *crtc_state;
		struct intel_crtc *crtc;

		if (!connector->has_tile ||
		    connector->tile_group->id != tile_group_id)
			continue;

		conn_state = drm_atomic_get_connector_state(&state->base,
							    connector);
		if (IS_ERR(conn_state)) {
			ret = PTR_ERR(conn_state);
			break;
		}

		crtc = to_intel_crtc(conn_state->crtc);

		if (!crtc)
			continue;

		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
		crtc_state->uapi.mode_changed = true;

		ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
		if (ret)
			break;
	}
	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);

	return ret;
}

static int intel_modeset_affected_transcoders(struct intel_atomic_state *state, u8 transcoders)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct intel_crtc *crtc;

	if (transcoders == 0)
		return 0;

	for_each_intel_crtc(&dev_priv->drm, crtc) {
		struct intel_crtc_state *crtc_state;
		int ret;

		crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
		if (IS_ERR(crtc_state))
			return PTR_ERR(crtc_state);

		if (!crtc_state->hw.enable)
			continue;

		if (!(transcoders & BIT(crtc_state->cpu_transcoder)))
			continue;

		crtc_state->uapi.mode_changed = true;

		ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
		if (ret)
			return ret;

		ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
		if (ret)
			return ret;

		transcoders &= ~BIT(crtc_state->cpu_transcoder);
	}

	WARN_ON(transcoders != 0);

	return 0;
}

static int intel_modeset_synced_crtcs(struct intel_atomic_state *state,
				      struct drm_connector *connector)
{
	const struct drm_connector_state *old_conn_state =
		drm_atomic_get_old_connector_state(&state->base, connector);
	const struct intel_crtc_state *old_crtc_state;
	struct intel_crtc *crtc;
	u8 transcoders;

	crtc = to_intel_crtc(old_conn_state->crtc);
	if (!crtc)
		return 0;

	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);

	if (!old_crtc_state->hw.active)
		return 0;

	transcoders = old_crtc_state->sync_mode_slaves_mask;
	if (old_crtc_state->master_transcoder != INVALID_TRANSCODER)
		transcoders |= BIT(old_crtc_state->master_transcoder);

	return intel_modeset_affected_transcoders(state,
						  transcoders);
}

static int intel_dp_connector_atomic_check(struct drm_connector *conn,
					   struct drm_atomic_state *_state)
{
	struct drm_i915_private *dev_priv = to_i915(conn->dev);
	struct intel_atomic_state *state = to_intel_atomic_state(_state);
	int ret;

	ret = intel_digital_connector_atomic_check(conn, &state->base);
	if (ret)
		return ret;

	if (INTEL_GEN(dev_priv) < 11)
		return 0;

	if (!intel_connector_needs_modeset(state, conn))
		return 0;

	if (conn->has_tile) {
		ret = intel_modeset_tile_group(state, conn->tile_group->id);
		if (ret)
			return ret;
	}

	return intel_modeset_synced_crtcs(state, conn);
}

static const struct drm_connector_funcs intel_dp_connector_funcs = {
	.force = intel_dp_force,
	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -6601,7 +6735,7 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
	.detect_ctx = intel_dp_detect,
	.get_modes = intel_dp_get_modes,
	.mode_valid = intel_dp_mode_valid,
	.atomic_check = intel_digital_connector_atomic_check,
	.atomic_check = intel_dp_connector_atomic_check,
};

static const struct drm_encoder_funcs intel_dp_enc_funcs = {