[Intel-gfx] [PATCH v12 09/17] drm/i915/guc/slpc: Reset SLPC on engine reset with flag TDR_OCCURRED
Sagar Arun Kamble
sagar.a.kamble at intel.com
Fri Mar 30 08:31:54 UTC 2018
On engine reset, SLPC needs to be notified for it to clear metrics/stats.
This is done by sending GUC_SLPC_EVENT_RESET with a flag
GUC_SLPC_RESET_FLAG_TDR_OCCURRED.
v2: Full GPU reset in i915 triggers reload of GuC and SLPC reset happens
along that path. Hence only handling engine reset.
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg at intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Sujaritha Sundaresan <sujaritha.sundaresan at intel.com>
Cc: Jeff McGee <jeff.mcgee at intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 3 +++
drivers/gpu/drm/i915/intel_guc_slpc.c | 36 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_guc_slpc.h | 1 +
drivers/gpu/drm/i915/intel_uc.c | 5 +++++
drivers/gpu/drm/i915/intel_uc.h | 1 +
5 files changed, 46 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index cc7dd85..726391c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3020,6 +3020,9 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
wake_up_bit(&dev_priv->gpu_error.flags,
I915_RESET_ENGINE + engine->id);
}
+
+ if (!engine_mask)
+ intel_uc_handle_engine_reset(dev_priv);
}
if (!engine_mask)
diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c
index 7f75d218..bdafbaa 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.c
@@ -390,6 +390,20 @@ static bool slpc_stopped(struct intel_guc_slpc *slpc)
return (data.global_state == SLPC_GLOBAL_STATE_NOT_RUNNING);
}
+static void host2guc_slpc_tdr_reset(struct intel_guc_slpc *slpc)
+{
+ struct intel_guc *guc = slpc_to_guc(slpc);
+ u32 shared_data_gtt_offset = intel_guc_ggtt_offset(guc, slpc->vma);
+ struct slpc_event_input data = {0};
+
+ data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 3);
+ data.args[0] = shared_data_gtt_offset;
+ data.args[1] = 0;
+ data.args[2] = SLPC_RESET_FLAG_TDR_OCCURRED;
+
+ slpc_send(slpc, &data, 5);
+}
+
/**
* intel_guc_slpc_init() - Initialize the SLPC shared data structure.
* @slpc: pointer to intel_guc_slpc.
@@ -471,6 +485,28 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
}
/**
+ * intel_guc_slpc_handle_engine_reset() - Notify SLPC about engine reset.
+ * @slpc: pointer to intel_guc_slpc.
+ *
+ * On engine reset, SLPC needs to be notified for it to clear metrics/stats.
+ * This function notifies by invoking SLPC_EVENT_RESET with a flag
+ * SLPC_RESET_FLAG_TDR_OCCURRED.
+ */
+void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc)
+{
+ mutex_lock(&slpc->lock);
+
+ host2guc_slpc_tdr_reset(slpc);
+
+ /* Check whether SLPC is running */
+ if (wait_for(slpc_running(slpc), 5))
+ DRM_ERROR("SLPC not enabled! State = %s\n",
+ slpc_get_state(slpc));
+
+ mutex_unlock(&slpc->lock);
+}
+
+/**
* intel_guc_slpc_disable() - Stop SLPC tasks.
* @slpc: pointer to intel_guc_slpc.
*
diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h
index 87dac07..75f0b5d 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.h
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.h
@@ -16,6 +16,7 @@ struct intel_guc_slpc {
int intel_guc_slpc_init(struct intel_guc_slpc *slpc);
int intel_guc_slpc_enable(struct intel_guc_slpc *slpc);
+void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc);
void intel_guc_slpc_disable(struct intel_guc_slpc *slpc);
void intel_guc_slpc_fini(struct intel_guc_slpc *slpc);
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index ece6687..c050444 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -475,6 +475,11 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
return ret;
}
+void intel_uc_handle_engine_reset(struct drm_i915_private *dev_priv)
+{
+ intel_guc_slpc_handle_engine_reset(&dev_priv->guc.slpc);
+}
+
void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
{
struct intel_guc *guc = &dev_priv->guc;
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 76139d3..1d67ad3 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -35,6 +35,7 @@ int intel_uc_init_misc(struct drm_i915_private *dev_priv);
void intel_uc_fini_misc(struct drm_i915_private *dev_priv);
void intel_uc_sanitize(struct drm_i915_private *dev_priv);
int intel_uc_init_hw(struct drm_i915_private *dev_priv);
+void intel_uc_handle_engine_reset(struct drm_i915_private *dev_priv);
void intel_uc_fini_hw(struct drm_i915_private *dev_priv);
int intel_uc_init(struct drm_i915_private *dev_priv);
void intel_uc_fini(struct drm_i915_private *dev_priv);
--
2.7.4
More information about the Intel-gfx
mailing list