[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