[PATCH 2/2] drm/i915/wopcm: Don't fail on WOPCM partitioning failure
Michal Wajdeczko
michal.wajdeczko at intel.com
Fri Jul 26 19:27:12 UTC 2019
From: mwajdecz <mwajdecz at MWAJDECZ-MOBL1>
We shouldn't immediately fail on WOPCM partitioning or
programming as there might be some fallback available
(not now, but in the near future).
Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
---
drivers/gpu/drm/i915/gt/uc/intel_uc.c | 3 ++
drivers/gpu/drm/i915/i915_gem.c | 12 ++------
drivers/gpu/drm/i915/intel_wopcm.c | 41 +++++++++++++--------------
drivers/gpu/drm/i915/intel_wopcm.h | 11 +++++--
4 files changed, 34 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index fafa9be1e12a..4e1fdb31d7b0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -400,6 +400,9 @@ int intel_uc_init_hw(struct intel_uc *uc)
if (!intel_uc_is_using_guc(uc))
return 0;
+ if (!intel_wopcm_is_ready(&i915->wopcm))
+ return -EIO;
+
GEM_BUG_ON(!intel_uc_fw_supported(&guc->fw));
guc_reset_interrupts(guc);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 01dd0d1d9bf6..e9a7c7485284 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1239,11 +1239,7 @@ int i915_gem_init_hw(struct drm_i915_private *i915)
goto out;
}
- ret = intel_wopcm_init_hw(&i915->wopcm, gt);
- if (ret) {
- DRM_ERROR("Enabling WOPCM failed (%d)\n", ret);
- goto out;
- }
+ intel_wopcm_init_hw(&i915->wopcm, gt);
/* We can't enable contexts until all firmware is loaded */
ret = intel_uc_init_hw(&i915->gt.uc);
@@ -1432,10 +1428,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
return ret;
intel_uc_fetch_firmwares(&dev_priv->gt.uc);
-
- ret = intel_wopcm_init(&dev_priv->wopcm);
- if (ret)
- goto err_uc_fw;
+ intel_wopcm_init(&dev_priv->wopcm);
/* This is just a security blanket to placate dragons.
* On some systems, we very sporadically observe that the first TLBs
@@ -1561,7 +1554,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
mutex_unlock(&dev_priv->drm.struct_mutex);
-err_uc_fw:
intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
if (ret != -EIO) {
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
index 7e419e9ee7b0..edbb22f01cf3 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -158,10 +158,8 @@ static inline int check_hw_restriction(struct drm_i915_private *i915,
* enforce platform dependent hardware restrictions on GuC WOPCM offset and
* size. It will fail the WOPCM init if any of these checks were failed, so that
* the following GuC firmware uploading would be aborted.
- *
- * Return: 0 on success, non-zero error code on failure.
*/
-int intel_wopcm_init(struct intel_wopcm *wopcm)
+void intel_wopcm_init(struct intel_wopcm *wopcm)
{
struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->gt.uc.guc.fw);
@@ -172,24 +170,24 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
u32 guc_wopcm_rsvd;
int err;
- if (!USES_GUC(i915))
- return 0;
+ if (!intel_uc_fw_is_available(&i915->gt.uc.guc.fw))
+ return;
GEM_BUG_ON(!wopcm->size);
if (i915_inject_probe_failure())
- return -E2BIG;
+ return;
if (guc_fw_size >= wopcm->size) {
DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.",
guc_fw_size / 1024);
- return -E2BIG;
+ goto fail;
}
if (huc_fw_size >= wopcm->size) {
DRM_ERROR("HuC FW (%uKiB) is too big to fit in WOPCM.",
huc_fw_size / 1024);
- return -E2BIG;
+ goto fail;
}
guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
@@ -197,7 +195,7 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
if ((guc_wopcm_base + ctx_rsvd) >= wopcm->size) {
DRM_ERROR("GuC WOPCM base (%uKiB) is too big.\n",
guc_wopcm_base / 1024);
- return -E2BIG;
+ goto fail;
}
guc_wopcm_size = wopcm->size - guc_wopcm_base - ctx_rsvd;
@@ -211,18 +209,20 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
DRM_ERROR("Need %uKiB WOPCM for GuC, %uKiB available.\n",
(guc_fw_size + guc_wopcm_rsvd) / 1024,
guc_wopcm_size / 1024);
- return -E2BIG;
+ goto fail;
}
err = check_hw_restriction(i915, guc_wopcm_base, guc_wopcm_size,
huc_fw_size);
if (err)
- return err;
+ goto fail;
wopcm->guc.base = guc_wopcm_base;
wopcm->guc.size = guc_wopcm_size;
-
- return 0;
+ return;
+fail:
+ dev_warn(i915->drm.dev,
+ "WOPCM partitioning failed, GuC will not load!\n");
}
static int
@@ -249,10 +249,8 @@ write_and_verify(struct intel_gt *gt,
* Setup the GuC WOPCM size and offset registers with the calculated values. It
* will verify the register values to make sure the registers are locked with
* correct values.
- *
- * Return: 0 on success. -EIO if registers were locked with incorrect values.
*/
-int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt)
+void intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt)
{
struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
struct intel_uncore *uncore = gt->uncore;
@@ -260,8 +258,8 @@ int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt)
u32 mask;
int err;
- if (!USES_GUC(i915))
- return 0;
+ if (!intel_wopcm_guc_size(wopcm))
+ return;
GEM_BUG_ON(!HAS_GT_UC(i915));
GEM_BUG_ON(!wopcm->guc.size);
@@ -281,7 +279,8 @@ int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt)
if (err)
goto err_out;
- return 0;
+ wopcm->ready = true;
+ return;
err_out:
DRM_ERROR("Failed to init WOPCM registers:\n");
@@ -289,6 +288,6 @@ int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt)
intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
DRM_ERROR("GUC_WOPCM_SIZE=%#x\n",
intel_uncore_read(uncore, GUC_WOPCM_SIZE));
-
- return err;
+ dev_warn(i915->drm.dev,
+ "WOPCM programming failed, GuC will not load!\n");
}
diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/intel_wopcm.h
index 56aaed4d64ff..daf9c1dbe20b 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.h
+++ b/drivers/gpu/drm/i915/intel_wopcm.h
@@ -17,6 +17,7 @@ struct intel_gt;
* @guc: GuC WOPCM Region info.
* @guc.base: GuC WOPCM base which is offset from WOPCM base.
* @guc.size: Size of the GuC WOPCM region.
+ * @ready: indicates that WOPCM registers are correctly programmed.
*/
struct intel_wopcm {
u32 size;
@@ -24,6 +25,7 @@ struct intel_wopcm {
u32 base;
u32 size;
} guc;
+ bool ready;
};
/**
@@ -42,7 +44,12 @@ static inline u32 intel_wopcm_guc_size(struct intel_wopcm *wopcm)
}
void intel_wopcm_init_early(struct intel_wopcm *wopcm);
-int intel_wopcm_init(struct intel_wopcm *wopcm);
-int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt);
+void intel_wopcm_init(struct intel_wopcm *wopcm);
+void intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt);
+
+static inline bool intel_wopcm_is_ready(struct intel_wopcm *wopcm)
+{
+ return wopcm->ready;
+}
#endif
--
2.19.2
More information about the Intel-gfx-trybot
mailing list