Commit ecf8a99f authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2022-02-24' of...

Merge tag 'drm-intel-fixes-2022-02-24' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-fixes

- Fix QGV handling on ADL-P+ (Ville Syrjälä)
- Fix bw atomic check when switching between SAGV vs. no SAGV (Ville Syrjälä)
- Disconnect PHYs left connected by BIOS on disabled ports (Imre Deak)
- Fix SAVG to no SAGV transitions on TGL+ (Ville Syrjälä)
- Print PHY name properly on calibration error (DG2) (Matt Roper)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/YhdyHwRWkOTWwlqi@tursulin-mobl2
parents 7c17b3d3 28adef86
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -825,6 +825,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
	unsigned int max_bw_point = 0, max_bw = 0;
	unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
	unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
	bool changed = false;
	u32 mask = 0;

	/* FIXME earlier gens need some checks too */
@@ -868,6 +869,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
		new_bw_state->data_rate[crtc->pipe] = new_data_rate;
		new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;

		changed = true;

		drm_dbg_kms(&dev_priv->drm,
			    "pipe %c data rate %u num active planes %u\n",
			    pipe_name(crtc->pipe),
@@ -875,7 +878,19 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
			    new_bw_state->num_active_planes[crtc->pipe]);
	}

	if (!new_bw_state)
	old_bw_state = intel_atomic_get_old_bw_state(state);
	new_bw_state = intel_atomic_get_new_bw_state(state);

	if (new_bw_state &&
	    intel_can_enable_sagv(dev_priv, old_bw_state) !=
	    intel_can_enable_sagv(dev_priv, new_bw_state))
		changed = true;

	/*
	 * If none of our inputs (data rates, number of active
	 * planes, SAGV yes/no) changed then nothing to do here.
	 */
	if (!changed)
		return 0;

	ret = intel_atomic_lock_global_state(&new_bw_state->base);
@@ -961,7 +976,6 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
	 */
	new_bw_state->qgv_points_mask = ~allowed_points & mask;

	old_bw_state = intel_atomic_get_old_bw_state(state);
	/*
	 * If the actual mask had changed we need to make sure that
	 * the commits are serialized(in case this is a nomodeset, nonblocking)
+4 −4
Original line number Diff line number Diff line
@@ -30,19 +30,19 @@ struct intel_bw_state {
	 */
	u8 pipe_sagv_reject;

	/* bitmask of active pipes */
	u8 active_pipes;

	/*
	 * Current QGV points mask, which restricts
	 * some particular SAGV states, not to confuse
	 * with pipe_sagv_mask.
	 */
	u8 qgv_points_mask;
	u16 qgv_points_mask;

	unsigned int data_rate[I915_MAX_PIPES];
	u8 num_active_planes[I915_MAX_PIPES];

	/* bitmask of active pipes */
	u8 active_pipes;

	int min_cdclk;
};

+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv)
		if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy),
					    DG2_PHY_DP_TX_ACK_MASK, 25))
			DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n",
				  phy);
				  phy_name(phy));
	}
}

+20 −6
Original line number Diff line number Diff line
@@ -691,6 +691,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
{
	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
	struct intel_encoder *encoder = &dig_port->base;
	intel_wakeref_t tc_cold_wref;
	enum intel_display_power_domain domain;
	int active_links = 0;

	mutex_lock(&dig_port->tc_lock);
@@ -702,12 +704,11 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)

	drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
	drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
	if (active_links) {
		enum intel_display_power_domain domain;
		intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port, &domain);

		dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
	tc_cold_wref = tc_cold_block(dig_port, &domain);

	dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
	if (active_links) {
		if (!icl_tc_phy_is_connected(dig_port))
			drm_dbg_kms(&i915->drm,
				    "Port %s: PHY disconnected with %d active link(s)\n",
@@ -716,9 +717,22 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)

		dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
							  &dig_port->tc_lock_power_domain);
	} else {
		/*
		 * TBT-alt is the default mode in any case the PHY ownership is not
		 * held (regardless of the sink's connected live state), so
		 * we'll just switch to disconnected mode from it here without
		 * a note.
		 */
		if (dig_port->tc_mode != TC_PORT_TBT_ALT)
			drm_dbg_kms(&i915->drm,
				    "Port %s: PHY left in %s mode on disabled port, disconnecting it\n",
				    dig_port->tc_port_name,
				    tc_port_mode_name(dig_port->tc_mode));
		icl_tc_phy_disconnect(dig_port);
	}

	tc_cold_unblock(dig_port, domain, tc_cold_wref);
	}

	drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
		    dig_port->tc_port_name,
+11 −11
Original line number Diff line number Diff line
@@ -4029,6 +4029,17 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
			return ret;
	}

	if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
	    intel_can_enable_sagv(dev_priv, old_bw_state)) {
		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
		if (ret)
			return ret;
	} else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
		ret = intel_atomic_lock_global_state(&new_bw_state->base);
		if (ret)
			return ret;
	}

	for_each_new_intel_crtc_in_state(state, crtc,
					 new_crtc_state, i) {
		struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
@@ -4044,17 +4055,6 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
			intel_can_enable_sagv(dev_priv, new_bw_state);
	}

	if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
	    intel_can_enable_sagv(dev_priv, old_bw_state)) {
		ret = intel_atomic_serialize_global_state(&new_bw_state->base);
		if (ret)
			return ret;
	} else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
		ret = intel_atomic_lock_global_state(&new_bw_state->base);
		if (ret)
			return ret;
	}

	return 0;
}