All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 08/11] drm/i915/guc: Fix GuC interaction in reset/suspend scenarios
Date: Sat, 16 Sep 2017 02:36:26 +0530	[thread overview]
Message-ID: <1505509589-5730-9-git-send-email-sagar.a.kamble@intel.com> (raw)
In-Reply-To: <1505509589-5730-1-git-send-email-sagar.a.kamble@intel.com>

guc_ggtt_invalidate/guc_interrupts should be disabled towards
end of reset/suspend post GuC suspension as these are setup back again
during recovery/resume.

Prepared helpers intel_guc_pause and intel_guc_unpause that will do
teardown/bringup of this setup along with suspension/resumption of GuC if
loaded. These helpers can then be used along the system or runtime
suspend/resume paths as applicable. Currently post system resume, since
GuC is loaded completely system_resume function for GuC is doing
nothing. We rely on the setup happening in intel_uc_init_hw path.
During runtime_suspend we will call intel_guc_pause helper.
Another helper added is intel_guc_reset_prepare, this will make sure that
disabling of ggtt_invalidate and GuC interrupts happens prior to reset and
updates the firmware load status to PENDING.

v2: Updated commit message. Added note about skipped call to
intel_guc_system_resume. guc_enable/disable_communication was moved to
earlier patch so corresponding rebase. (Michal Wajdeczko)

v3: Introduction of intel_uc_runtime/system_suspend/resume. Updated
changes for enable/disable_communication.

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c            |  11 ++-
 drivers/gpu/drm/i915/i915_gem.c            |   4 +-
 drivers/gpu/drm/i915/i915_guc_submission.c |  50 -----------
 drivers/gpu/drm/i915/intel_guc.c           | 129 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_guc.h           |   7 +-
 drivers/gpu/drm/i915/intel_uc.c            |  30 +++++++
 drivers/gpu/drm/i915/intel_uc.h            |   5 ++
 7 files changed, 179 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dec2850..4751679 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1684,6 +1684,11 @@ static int i915_drm_resume(struct drm_device *dev)
 
 	drm_mode_config_reset(dev);
 
+	/*
+	 * NB: Full gem reinitialization is being done during i915_drm_resume,
+	 * hence intel_guc_system_resume will be of no use. If full
+	 * reinitialization is avoided, need to call intel_guc_system_resume.
+	 */
 	mutex_lock(&dev->struct_mutex);
 	if (i915_gem_init_hw(dev_priv)) {
 		DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
@@ -1691,8 +1696,6 @@ static int i915_drm_resume(struct drm_device *dev)
 	}
 	mutex_unlock(&dev->struct_mutex);
 
-	intel_guc_resume(&dev_priv->guc);
-
 	intel_modeset_init_hw(dev);
 
 	spin_lock_irq(&dev_priv->irq_lock);
@@ -2493,7 +2496,7 @@ static int intel_runtime_suspend(struct device *kdev)
 	 */
 	i915_gem_runtime_suspend(dev_priv);
 
-	intel_guc_suspend(&dev_priv->guc);
+	intel_uc_runtime_suspend(dev_priv);
 
 	intel_runtime_pm_disable_interrupts(dev_priv);
 
@@ -2578,7 +2581,7 @@ static int intel_runtime_resume(struct device *kdev)
 	if (intel_uncore_unclaimed_mmio(dev_priv))
 		DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
 
-	intel_guc_resume(&dev_priv->guc);
+	intel_uc_runtime_resume(dev_priv);
 
 	if (IS_GEN9_LP(dev_priv)) {
 		bxt_disable_dc9(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eb20e73..7354307 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2847,6 +2847,8 @@ int i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
 
 	i915_gem_revoke_fences(dev_priv);
 
+	intel_uc_reset_prepare(dev_priv);
+
 	return err;
 }
 
@@ -4575,7 +4577,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
 	i915_gem_contexts_lost(dev_priv);
 	mutex_unlock(&dev->struct_mutex);
 
-	intel_guc_suspend(&dev_priv->guc);
+	intel_uc_system_suspend(dev_priv);
 
 	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
 	cancel_delayed_work_sync(&dev_priv->gt.retire_work);
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 8ad1abe..f0ff874 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1206,53 +1206,3 @@ void i915_guc_submission_disable(struct drm_i915_private *dev_priv)
 	guc_client_free(guc->execbuf_client);
 	guc->execbuf_client = NULL;
 }
-
-/**
- * intel_guc_suspend() - notify GuC entering suspend state
- */
-int intel_guc_suspend(struct intel_guc *guc)
-{
-	struct drm_i915_private *dev_priv = guc_to_i915(guc);
-	struct i915_gem_context *ctx;
-	u32 data[3];
-
-	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
-		return 0;
-
-	gen9_disable_guc_interrupts(dev_priv);
-
-	ctx = dev_priv->kernel_context;
-
-	data[0] = INTEL_GUC_ACTION_ENTER_S_STATE;
-	/* any value greater than GUC_POWER_D0 */
-	data[1] = GUC_POWER_D1;
-	/* first page is shared data with GuC */
-	data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE;
-
-	return intel_guc_send(guc, data, ARRAY_SIZE(data));
-}
-
-/**
- * intel_guc_resume() - notify GuC resuming from suspend state
- */
-int intel_guc_resume(struct intel_guc *guc)
-{
-	struct drm_i915_private *dev_priv = guc_to_i915(guc);
-	struct i915_gem_context *ctx;
-	u32 data[3];
-
-	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
-		return 0;
-
-	if (i915.guc_log_level >= 0)
-		gen9_enable_guc_interrupts(dev_priv);
-
-	ctx = dev_priv->kernel_context;
-
-	data[0] = INTEL_GUC_ACTION_EXIT_S_STATE;
-	data[1] = GUC_POWER_D0;
-	/* first page is shared data with GuC */
-	data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE;
-
-	return intel_guc_send(guc, data, ARRAY_SIZE(data));
-}
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index b507e71..3226869 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -164,3 +164,132 @@ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset)
 
 	return intel_guc_send(guc, data, ARRAY_SIZE(data));
 }
+
+/**
+ * intel_guc_suspend() - notify GuC entering suspend state
+ */
+static int intel_guc_suspend(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct i915_gem_context *ctx;
+	u32 data[3];
+
+	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
+		return 0;
+
+	ctx = dev_priv->kernel_context;
+
+	data[0] = INTEL_GUC_ACTION_ENTER_S_STATE;
+	/* any value greater than GUC_POWER_D0 */
+	data[1] = GUC_POWER_D1;
+	/* first page is shared data with GuC */
+	data[2] = guc_ggtt_offset(ctx->engine[RCS].state);
+
+	return intel_guc_send(guc, data, ARRAY_SIZE(data));
+}
+
+/**
+ * intel_guc_resume() - notify GuC resuming from suspend state
+ */
+static int intel_guc_resume(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct i915_gem_context *ctx;
+	u32 data[3];
+
+	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
+		return 0;
+
+	ctx = dev_priv->kernel_context;
+
+	data[0] = INTEL_GUC_ACTION_EXIT_S_STATE;
+	data[1] = GUC_POWER_D0;
+	/* first page is shared data with GuC */
+	data[2] = guc_ggtt_offset(ctx->engine[RCS].state);
+
+	return intel_guc_send(guc, data, ARRAY_SIZE(data));
+}
+
+static void intel_guc_sanitize(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+
+	i915_ggtt_disable_guc(dev_priv);
+	gen9_disable_guc_interrupts(dev_priv);
+}
+
+void intel_guc_reset_prepare(struct intel_guc *guc)
+{
+	if (!i915.enable_guc_loading)
+		return;
+
+	intel_guc_sanitize(guc);
+	guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING;
+}
+
+static int intel_guc_pause(struct intel_guc *guc)
+{
+	int ret = 0;
+
+	ret = intel_guc_suspend(guc);
+	intel_guc_sanitize(guc);
+
+	return ret;
+}
+
+static int intel_guc_unpause(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	int ret = 0;
+
+	if (i915.guc_log_level >= 0)
+		gen9_enable_guc_interrupts(dev_priv);
+	i915_ggtt_enable_guc(dev_priv);
+	ret = intel_guc_resume(guc);
+
+	return ret;
+}
+
+int intel_guc_runtime_suspend(struct intel_guc *guc)
+{
+	if (!i915.enable_guc_loading)
+		return 0;
+
+	return intel_guc_pause(guc);
+}
+
+int intel_guc_runtime_resume(struct intel_guc *guc)
+{
+	if (!i915.enable_guc_loading)
+		return 0;
+
+	return intel_guc_unpause(guc);
+}
+
+int intel_guc_system_suspend(struct intel_guc *guc)
+{
+	int ret = 0;
+
+	if (!i915.enable_guc_loading)
+		return ret;
+
+	ret = intel_guc_pause(guc);
+	guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING;
+
+	return ret;
+}
+
+int intel_guc_system_resume(struct intel_guc *guc)
+{
+	int ret = 0;
+
+	if (!i915.enable_guc_loading)
+		return ret;
+
+	/*
+	 * Placeholder for GuC resume from system suspend/freeze states.
+	 * Currently full reinitialization of GEM and GuC happens along
+	 * these paths, Hence this function is doing nothing.
+	 */
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 29d7200..e912667 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -148,6 +148,11 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma)
 int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len);
 int intel_guc_sample_forcewake(struct intel_guc *guc);
 int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset);
+void intel_guc_reset_prepare(struct intel_guc *guc);
+int intel_guc_runtime_suspend(struct intel_guc *guc);
+int intel_guc_runtime_resume(struct intel_guc *guc);
+int intel_guc_system_suspend(struct intel_guc *guc);
+int intel_guc_system_resume(struct intel_guc *guc);
 
 /* intel_guc_loader.c */
 int intel_guc_select_fw(struct intel_guc *guc);
@@ -160,8 +165,6 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma)
 void i915_guc_submission_disable(struct drm_i915_private *dev_priv);
 void i915_guc_submission_fini(struct drm_i915_private *dev_priv);
 struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
-int intel_guc_suspend(struct intel_guc *guc);
-int intel_guc_resume(struct intel_guc *guc);
 
 /* intel_guc_log.c */
 int intel_guc_log_create(struct intel_guc *guc);
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index c7cc8c46..8fd1798 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -421,3 +421,33 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
 
 	i915_ggtt_disable_guc(dev_priv);
 }
+
+void intel_uc_reset_prepare(struct drm_i915_private *dev_priv)
+{
+	intel_guc_reset_prepare(&dev_priv->guc);
+	guc_disable_communication(&dev_priv->guc);
+}
+
+void intel_uc_runtime_suspend(struct drm_i915_private *dev_priv)
+{
+	intel_guc_runtime_suspend(&dev_priv->guc);
+	guc_disable_communication(&dev_priv->guc);
+}
+
+int intel_uc_runtime_resume(struct drm_i915_private *dev_priv)
+{
+	intel_guc_runtime_resume(&dev_priv->guc);
+	return guc_enable_communication(&dev_priv->guc);
+}
+
+void intel_uc_system_suspend(struct drm_i915_private *dev_priv)
+{
+	intel_guc_system_suspend(&dev_priv->guc);
+	guc_disable_communication(&dev_priv->guc);
+}
+
+int intel_uc_system_resume(struct drm_i915_private *dev_priv)
+{
+	intel_guc_system_resume(&dev_priv->guc);
+	return guc_enable_communication(&dev_priv->guc);
+}
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 0d346ef..4d49a19 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -105,5 +105,10 @@ struct intel_uc_fw {
 void intel_uc_fini_fw(struct drm_i915_private *dev_priv);
 int intel_uc_init_hw(struct drm_i915_private *dev_priv);
 void intel_uc_fini_hw(struct drm_i915_private *dev_priv);
+void intel_uc_reset_prepare(struct drm_i915_private *dev_priv);
+void intel_uc_runtime_suspend(struct drm_i915_private *dev_priv);
+int intel_uc_runtime_resume(struct drm_i915_private *dev_priv);
+void intel_uc_system_suspend(struct drm_i915_private *dev_priv);
+int intel_uc_system_resume(struct drm_i915_private *dev_priv);
 
 #endif
-- 
1.9.1

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

  parent reply	other threads:[~2017-09-15 21:03 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-15 21:06 [PATCH 00/11] GuC code restructuring and fixes Sagar Arun Kamble
2017-09-15 21:05 ` ✗ Fi.CI.BAT: failure for GuC code restructuring and fixes (rev2) Patchwork
2017-09-15 21:06 ` [PATCH 01/11] drm/i915/guc: Pass intel_guc to intel_guc_suspend/resume instead of drm_i915_private Sagar Arun Kamble
2017-09-16 11:40   ` Michal Wajdeczko
2017-09-15 21:06 ` [PATCH 02/11] drm/i915/guc: Create intel_guc.c for defining GuC specific functionality Sagar Arun Kamble
2017-09-15 21:06 ` [PATCH 03/11] drm/i915/guc: Move guc_send_* functions to intel_guc.c Sagar Arun Kamble
2017-09-15 21:06 ` [PATCH 04/11] drm/i915/guc: Move guc_sample_forcewake " Sagar Arun Kamble
2017-09-15 21:06 ` [PATCH 05/11] drm/i915: Reorganize HuC authentication Sagar Arun Kamble
2017-09-16 11:25   ` Michal Wajdeczko
2017-09-15 21:06 ` [PATCH 06/11] drm/i915/guc: Move GuC specific declarations from intel_uc.h to intel_guc.h Sagar Arun Kamble
2017-09-15 21:06 ` [PATCH 07/11] drm/i915/huc: Move HuC specific declarations from intel_uc.h to intel_huc.h Sagar Arun Kamble
2017-09-15 21:06 ` Sagar Arun Kamble [this message]
2017-09-15 21:06 ` [PATCH 09/11] drm/i915/guc: Fix GuC HW/SW state cleanup in unload path Sagar Arun Kamble
2017-09-15 21:06 ` [PATCH 10/11] drm/i915/guc: Enable default/critical logging in GuC by default from GuC v9 Sagar Arun Kamble
2017-09-16 10:03   ` Michal Wajdeczko
2017-09-15 21:06 ` [PATCH 11/11] drm/i915/guc: Remove i915_guc_log_unregister Sagar Arun Kamble
2017-09-16 10:03   ` Michal Wajdeczko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1505509589-5730-9-git-send-email-sagar.a.kamble@intel.com \
    --to=sagar.a.kamble@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.