[PATCH] drm/i915: Disable DP AUX transfers for GPU reset

Imre Deak imre.deak at intel.com
Tue Oct 4 17:31:43 UTC 2022


Signed-off-by: Imre Deak <imre.deak at intel.com>
---
 drivers/gpu/drm/i915/display/g4x_dp.c         |  8 +++---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  7 ++---
 drivers/gpu/drm/i915/display/intel_display.c  |  5 ++++
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 10 +++++++
 drivers/gpu/drm/i915/display/intel_dp.h       |  1 +
 drivers/gpu/drm/i915/display/intel_dp_aux.c   | 27 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp_aux.h   |  3 +++
 drivers/gpu/drm/i915/i915_driver.c            | 20 +++++++++-----
 drivers/gpu/drm/i915/i915_driver.h            |  2 ++
 10 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index e3e3d27ffb53f..1ee25a2e75401 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -1249,15 +1249,13 @@ enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
 	return INVALID_PIPE;
 }
 
-static void intel_dp_encoder_reset(struct drm_encoder *encoder)
+static void g4x_dp_encoder_reset(struct drm_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
 
 	intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
 
-	intel_dp->reset_link_params = true;
-
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		intel_wakeref_t wakeref;
 
@@ -1265,11 +1263,11 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
 			intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
 	}
 
-	intel_pps_encoder_reset(intel_dp);
+	intel_dp_encoder_reset(to_intel_encoder(encoder));
 }
 
 static const struct drm_encoder_funcs intel_dp_enc_funcs = {
-	.reset = intel_dp_encoder_reset,
+	.reset = g4x_dp_encoder_reset,
 	.destroy = intel_dp_encoder_destroy,
 };
 
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 971356237eca3..73e38441a2f00 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3802,16 +3802,13 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
 static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
 {
 	struct drm_i915_private *i915 = to_i915(encoder->dev);
-	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
 	struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
 	enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
 
-	intel_dp->reset_link_params = true;
-
-	intel_pps_encoder_reset(intel_dp);
-
 	if (intel_phy_is_tc(i915, phy))
 		intel_tc_port_init_mode(dig_port);
+
+	intel_dp_encoder_reset(to_intel_encoder(encoder));
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8c3bd9ba0d748..1b8b59b960964 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -75,6 +75,7 @@
 #include "g4x_dp.h"
 #include "g4x_hdmi.h"
 #include "hsw_ips.h"
+#include "i915_driver.h"
 #include "i915_drv.h"
 #include "i915_utils.h"
 #include "icl_dsi.h"
@@ -937,6 +938,8 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
 
 	dev_priv->modeset_restore_state = state;
 	state->acquire_ctx = ctx;
+
+	i915_driver_suspend_encoders(dev_priv);
 }
 
 void intel_display_finish_reset(struct drm_i915_private *i915)
@@ -958,6 +961,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915)
 
 	/* reset doesn't touch the display */
 	if (!gpu_reset_clobbers_display(i915)) {
+		drm_mode_config_reset(&i915->drm);
 		/* for testing only restore the display */
 		ret = __intel_display_resume(i915, state, ctx);
 		if (ret)
@@ -969,6 +973,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915)
 		 * so need a full re-initialization.
 		 */
 		intel_pps_unlock_regs_wa(i915);
+		drm_mode_config_reset(&i915->drm);
 		intel_modeset_init_hw(i915);
 		intel_init_clock_gating(i915);
 		intel_hpd_init(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e2b853e9e51de..aada45d939c27 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1657,6 +1657,7 @@ struct intel_dp {
 	struct drm_dp_desc desc;
 	struct drm_dp_aux aux;
 	u32 aux_busy_last_status;
+	int aux_disable_count;
 	u8 train_set[4];
 
 	struct intel_pps pps;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 70b06806ec0d9..fb21cb9082ea9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4882,9 +4882,19 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
 
+	intel_dp_aux_disable(intel_dp);
 	intel_pps_vdd_off_sync(intel_dp);
 }
 
+void intel_dp_encoder_reset(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_dp->reset_link_params = true;
+	intel_pps_encoder_reset(intel_dp);
+	intel_dp_aux_enable(intel_dp);
+}
+
 void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index a54902c713a34..739cf1651887a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -51,6 +51,7 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state,
 					   bool enable);
 void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
+void intel_dp_encoder_reset(struct intel_encoder *encoder);
 void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder);
 void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
 int intel_dp_compute_config(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c
index 48c375c65a418..88caf0f9a07ec 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c
@@ -181,6 +181,27 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
 	return ret;
 }
 
+void intel_dp_aux_disable(struct intel_dp *intel_dp)
+{
+	intel_wakeref_t wakeref;
+
+	with_intel_pps_lock(intel_dp, wakeref)
+		intel_dp->aux_disable_count++;
+}
+
+void intel_dp_aux_enable(struct intel_dp *intel_dp)
+{
+	intel_wakeref_t wakeref;
+
+	with_intel_pps_lock(intel_dp, wakeref)
+		intel_dp->aux_disable_count--;
+}
+
+static bool intel_dp_aux_is_disabled(struct intel_dp *intel_dp)
+{
+	return intel_dp->aux_disable_count;
+}
+
 static int
 intel_dp_aux_xfer(struct intel_dp *intel_dp,
 		  const u8 *send, int send_bytes,
@@ -215,6 +236,11 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
 	aux_wakeref = intel_display_power_get(i915, aux_domain);
 	pps_wakeref = intel_pps_lock(intel_dp);
 
+	if (intel_dp_aux_is_disabled(intel_dp)) {
+		ret = -ENXIO;
+		goto out_unlock;
+	}
+
 	/*
 	 * We will be called with VDD already enabled for dpcd/edid/oui reads.
 	 * In such cases we want to leave VDD enabled and it's up to upper layers
@@ -370,6 +396,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
 	if (vdd)
 		intel_pps_vdd_off_unlocked(intel_dp, false);
 
+out_unlock:
 	intel_pps_unlock(intel_dp, pps_wakeref);
 	intel_display_power_put_async(i915, aux_domain, aux_wakeref);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.h b/drivers/gpu/drm/i915/display/intel_dp_aux.h
index 738577537bc7f..be4660988839f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.h
@@ -11,4 +11,7 @@ struct intel_dp;
 void intel_dp_aux_fini(struct intel_dp *intel_dp);
 void intel_dp_aux_init(struct intel_dp *intel_dp);
 
+void intel_dp_aux_disable(struct intel_dp *intel_dp);
+void intel_dp_aux_enable(struct intel_dp *intel_dp);
+
 #endif /* __INTEL_DP_AUX_H__ */
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index fb3826dabe8b6..59c18010e08a3 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1091,18 +1091,24 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
 	i915_gem_flush_free_objects(to_i915(dev));
 }
 
-static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
+void i915_driver_suspend_encoders(struct drm_i915_private *i915)
 {
-	struct drm_device *dev = &dev_priv->drm;
 	struct intel_encoder *encoder;
 
-	if (!HAS_DISPLAY(dev_priv))
-		return;
-
-	drm_modeset_lock_all(dev);
-	for_each_intel_encoder(dev, encoder)
+	for_each_intel_encoder(&i915->drm, encoder)
 		if (encoder->suspend)
 			encoder->suspend(encoder);
+}
+
+static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = &dev_priv->drm;
+
+	if (!HAS_DISPLAY(dev_priv))
+		return;
+
+	drm_modeset_lock_all(dev);
+	i915_driver_suspend_encoders(dev_priv);
 	drm_modeset_unlock_all(dev);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h
index 44ec543d92cb3..20a66ad9d9ca4 100644
--- a/drivers/gpu/drm/i915/i915_driver.h
+++ b/drivers/gpu/drm/i915/i915_driver.h
@@ -27,6 +27,8 @@ void i915_driver_shutdown(struct drm_i915_private *i915);
 int i915_driver_resume_switcheroo(struct drm_i915_private *i915);
 int i915_driver_suspend_switcheroo(struct drm_i915_private *i915, pm_message_t state);
 
+void i915_driver_suspend_encoders(struct drm_i915_private *i915);
+
 void
 i915_print_iommu_status(struct drm_i915_private *i915, struct drm_printer *p);
 
-- 
2.37.1



More information about the Intel-gfx-trybot mailing list