[PATCH 24/30] drm/i915/guc: New reset-engine command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Format of the ENGINE_RESET H2G message has been updated. Additionally,
the firmware will send a G2H ENGINE_RESET_COMPLETE message (with the
engine's guc_class in data[2]) to confirm that the reset has been
completed (but this will be handled in a other patch).

Co-Developed-by: Michel Thierry <michel.thierry@xxxxxxxxx>
Signed-off-by: Michel Thierry <michel.thierry@xxxxxxxxx>
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx>
Cc: Vinay Belgaumkar <vinay.belgaumkar@xxxxxxxxx>
Cc: Michal Winiarski <michal.winiarski@xxxxxxxxx>
Cc: Tomasz Lis <tomasz.lis@xxxxxxxxx>
---
 drivers/gpu/drm/i915/intel_guc.c | 73 +++++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/intel_guc.h |  6 +++
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index e54de551b567..abedb8982040 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -610,27 +610,80 @@ int intel_guc_suspend(struct intel_guc *guc)
 	return guc_sleep_state_action(guc, data, ARRAY_SIZE(data));
 }
 
+static inline void
+guc_set_class_under_reset(struct intel_guc *guc, unsigned int guc_class)
+{
+	GEM_BUG_ON(guc_class >= GUC_MAX_ENGINE_CLASSES);
+	guc->engine_class_under_reset |= BIT(guc_class);
+}
+
+static inline void
+guc_clear_class_under_reset(struct intel_guc *guc, unsigned int guc_class)
+{
+	GEM_BUG_ON(guc_class >= GUC_MAX_ENGINE_CLASSES);
+	guc->engine_class_under_reset &= ~BIT(guc_class);
+}
+
+static inline bool
+guc_is_class_under_reset(struct intel_guc *guc, unsigned int guc_class)
+{
+	return guc->engine_class_under_reset & BIT(guc_class);
+}
+
+static int __guc_action_reset_engine(struct intel_guc *guc,
+				     u32 guc_class,
+				     u32 stage_id)
+{
+	u32 action[] = {
+		INTEL_GUC_ACTION_REQUEST_ENGINE_RESET,
+		guc_class,
+		stage_id,
+	};
+
+	return intel_guc_send(guc, action, ARRAY_SIZE(action));
+}
+
+#define GUC_ENGINE_RESET_COMPLETE_WAIT_MS 100
+
 /**
  * intel_guc_reset_engine() - ask GuC to reset an engine
  * @guc:	intel_guc structure
  * @engine:	engine to be reset
+ *
+ * Ask GuC to reset an engine. The firmware will send a separate
+ * ENGINE_RESET_COMPLETE message (with the engine's guc_class)
+ * to confirm that the reset has been completed.
  */
 int intel_guc_reset_engine(struct intel_guc *guc,
 			   struct intel_engine_cs *engine)
 {
-	u32 data[7];
+	struct intel_guc_client *client = guc->execbuf_client;
+	u8 guc_class = engine->class;
+	int ret;
 
-	GEM_BUG_ON(!guc->execbuf_client);
+	GEM_BUG_ON(guc_is_class_under_reset(guc, guc_class));
+	guc_set_class_under_reset(guc, guc_class);
 
-	data[0] = INTEL_GUC_ACTION_REQUEST_ENGINE_RESET;
-	data[1] = engine->guc_id;
-	data[2] = 0;
-	data[3] = 0;
-	data[4] = 0;
-	data[5] = guc->execbuf_client->stage_id;
-	data[6] = intel_guc_ggtt_offset(guc, guc->shared_data);
+	ret = __guc_action_reset_engine(guc, guc_class, client->stage_id);
+	if (ret)
+		goto fail;
 
-	return intel_guc_send(guc, data, ARRAY_SIZE(data));
+	ret = wait_for(!guc_is_class_under_reset(guc, guc_class),
+		       GUC_ENGINE_RESET_COMPLETE_WAIT_MS);
+	if (ret)
+		goto fail_timedout;
+
+	return 0;
+
+fail_timedout:
+	DRM_ERROR("reset_complete timed out, engine class %u\n", guc_class);
+fail:
+	/*
+	 * Clear flag on any failure, we fall back to full reset in
+	 * case of timeout/error.
+	 */
+	guc_clear_class_under_reset(guc, guc_class);
+	return ret;
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index dbe4297f8a7d..a4bc3355a753 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -80,6 +80,12 @@ struct intel_guc {
 	/* Cyclic counter mod pagesize	*/
 	u32 db_cacheline;
 
+	/*
+	 * Track outstanding request-engine-reset h2g commands,
+	 * accessed by set/clear/is_engine_class_under_reset
+	 */
+	unsigned long engine_class_under_reset;
+
 	/* GuC's FW specific registers used in MMIO send */
 	struct {
 		u32 base;
-- 
2.19.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux