intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Dave Gordon <david.s.gordon@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 2/7] drm/i915/guc: always reset GuC before loading firmware
Date: Mon, 21 Mar 2016 10:16:35 +0000	[thread overview]
Message-ID: <1458555400-22859-3-git-send-email-david.s.gordon@intel.com> (raw)
In-Reply-To: <1458555400-22859-1-git-send-email-david.s.gordon@intel.com>

After a suspend-resume cycle, the resumed kernel has no idea what the
booted kernel may have done to the GuC before replacing itself with the
resumed image. In particular, it may have already loaded the GuC with
firmware, which will then cause this kernel's attempt to (re)load the
firmware to fail (GuC program memory is write-once!).

So here we choose to always reset the GuC just before (re)loading the
firmware, so the hardware should then be in a well-known state, and we
may even avoid some of the issues arising from unpredictable timing.

Also added some more fields & values to the definition of the GUC_STATUS
register, which is the key diagnostic indicator if the GuC load fails.

Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Cc: Arun Siluvery <arun.siluvery@linux.intel.com>
Cc: Alex Dai <yu.dai@intel.com>

---
 drivers/gpu/drm/i915/i915_guc_reg.h     | 12 ++++++++--
 drivers/gpu/drm/i915/intel_guc_loader.c | 40 ++++++++++++++++-----------------
 2 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h
index 94ceee5..80786d9 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ b/drivers/gpu/drm/i915/i915_guc_reg.h
@@ -27,10 +27,12 @@
 /* Definitions of GuC H/W registers, bits, etc */
 
 #define GUC_STATUS			_MMIO(0xc000)
-#define   GS_MIA_IN_RESET		(1 << 0)
+#define   GS_RESET_SHIFT		0
+#define   GS_MIA_IN_RESET		  (0x01 << GS_RESET_SHIFT)
 #define   GS_BOOTROM_SHIFT		1
 #define   GS_BOOTROM_MASK		  (0x7F << GS_BOOTROM_SHIFT)
 #define   GS_BOOTROM_RSA_FAILED		  (0x50 << GS_BOOTROM_SHIFT)
+#define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
 #define   GS_UKERNEL_SHIFT		8
 #define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
 #define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
@@ -38,7 +40,13 @@
 #define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
 #define   GS_MIA_SHIFT			16
 #define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
-#define   GS_MIA_CORE_STATE		  (1 << GS_MIA_SHIFT)
+#define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
+#define   GS_MIA_HALT_REQUESTED		  (0x02 << GS_MIA_SHIFT)
+#define   GS_MIA_ISR_ENTRY		  (0x04 << GS_MIA_SHIFT)
+#define   GS_AUTH_STATUS_SHIFT		30
+#define   GS_AUTH_STATUS_MASK		  (0x03 << GS_AUTH_STATUS_SHIFT)
+#define   GS_AUTH_STATUS_BAD		  (0x01 << GS_AUTH_STATUS_SHIFT)
+#define   GS_AUTH_STATUS_GOOD		  (0x02 << GS_AUTH_STATUS_SHIFT)
 
 #define SOFT_SCRATCH(n)			_MMIO(0xc180 + (n) * 4)
 #define SOFT_SCRATCH_COUNT		16
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index a07c228..a875936 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -387,7 +387,7 @@ int intel_guc_ucode_load(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
-	int err = 0;
+	int retries, err = 0;
 
 	if (!i915.enable_guc_submission)
 		return 0;
@@ -441,29 +441,26 @@ int intel_guc_ucode_load(struct drm_device *dev)
 	 * steppings also so this is extended as well.
 	 */
 	/* WaEnableGuCBootHashCheckNotSet:skl,bxt */
-	err = guc_ucode_xfer(dev_priv);
-	if (err) {
-		int retries = 3;
-
-		DRM_ERROR("GuC fw load failed, err=%d, attempting reset and retry\n", err);
-
-		while (retries--) {
-			err = i915_reset_guc(dev_priv);
-			if (err)
-				break;
-
-			err = guc_ucode_xfer(dev_priv);
-			if (!err) {
-				DRM_DEBUG_DRIVER("GuC fw reload succeeded after reset\n");
-				break;
-			}
-			DRM_DEBUG_DRIVER("GuC fw reload retries left: %d\n", retries);
-		}
-
+	for (retries = 3; ; ) {
+		/*
+		 * Always reset the GuC just before (re)loading, so
+		 * that the state and timing are fairly predictable
+		 */
+		err = i915_reset_guc(dev_priv);
 		if (err) {
-			DRM_ERROR("GuC fw reload attempt failed, ret=%d\n", err);
+			DRM_ERROR("GuC reset failed, err %d\n", err);
 			goto fail;
 		}
+
+		err = guc_ucode_xfer(dev_priv);
+		if (!err)
+			break;
+
+		if (--retries == 0)
+			goto fail;
+
+		DRM_INFO("GuC fw load failed, err %d; will reset and "
+			"retry %d more time(s)\n", err, retries);
 	}
 
 	guc_fw->guc_fw_load_status = GUC_FIRMWARE_SUCCESS;
@@ -485,6 +482,7 @@ int intel_guc_ucode_load(struct drm_device *dev)
 	return 0;
 
 fail:
+	DRM_ERROR("GuC firmware load failed, err %d\n", err);
 	if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
 		guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
 
-- 
1.9.1

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

  parent reply	other threads:[~2016-03-21 10:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-21 10:16 [PATCH 0/7] Fixes and worarounds for GuC issues Dave Gordon
2016-03-21 10:16 ` [PATCH 1/7] drm/i915/guc: Reset GuC and retry on firmware load failure Dave Gordon
2016-03-21 16:58   ` Arun Siluvery
2016-03-23 16:03     ` Dave Gordon
2016-03-21 10:16 ` Dave Gordon [this message]
2016-03-22 13:32   ` [PATCH 2/7] drm/i915/guc: always reset GuC before loading firmware Arun Siluvery
2016-03-22 18:42     ` Arun Siluvery
2016-03-23 17:05       ` [PATCH v2 1/2] drm/i915/guc: Reset GuC and retry on firmware load failure Dave Gordon
2016-03-23 17:05       ` [PATCH v2 2/2] drm/i915/guc: always reset GuC before loading firmware Dave Gordon
2016-03-21 10:16 ` [PATCH 3/7] drm/i915/guc: add doorbell map to debugfs/i915_guc_info Dave Gordon
2016-03-21 10:16 ` [PATCH 4/7] drm/i915/guc: move guc_ring_doorbell() nearer to callsite Dave Gordon
2016-03-21 10:16 ` [PATCH 5/7] drm/i915/guc: refactor doorbell management code Dave Gordon
2016-03-21 10:16 ` [PATCH 6/7] drm/i915/guc: (re)initialise doorbell h/w when enabling GuC submission Dave Gordon
2016-03-21 10:16 ` [PATCH 7/7] drm/i915/guc: disable GuC submission earlier during GuC (re)load Dave Gordon
2016-03-21 16:23 ` ✗ Fi.CI.BAT: warning for Fixes and worarounds for GuC issues Patchwork
2016-03-24  8:13 ` ✗ Fi.CI.BAT: failure for Fixes and worarounds for GuC issues (rev3) Patchwork

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=1458555400-22859-3-git-send-email-david.s.gordon@intel.com \
    --to=david.s.gordon@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).