drm/i915/wopcm: Don't fail on WOPCM partitioning failure
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Fri, 2 Aug 2019 18:40:55 +0000 (18:40 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 2 Aug 2019 20:14:32 +0000 (21:14 +0100)
We don't have to immediately fail on WOPCM partitioning, we can wait
until we will start programming WOPCM registers. This should give us
more options if we decide to restore fallback in case of GuC failures.

v3: rebased

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190802184055.31988-7-michal.wajdeczko@intel.com
drivers/gpu/drm/i915/gt/uc/intel_uc.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_wopcm.c
drivers/gpu/drm/i915/intel_wopcm.h

index 66d6e0775c236dea8a03db962be1491ed96d5a9c..fe526698eee2d7cfc72da136c5ad16de68e0e1b0 100644 (file)
@@ -378,6 +378,11 @@ static int uc_init_wopcm(struct intel_uc *uc)
        u32 mask;
        int err;
 
+       if (unlikely(!base || !size)) {
+               i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n");
+               return -E2BIG;
+       }
+
        GEM_BUG_ON(!intel_uc_supports_guc(uc));
        GEM_BUG_ON(!(base & GUC_WOPCM_OFFSET_MASK));
        GEM_BUG_ON(base & ~GUC_WOPCM_OFFSET_MASK);
index 2436cd598e6ecc8b23ee4f1e5d049db47160f57b..deaca3c2416df87d2bfaba596752c4e870e682b1 100644 (file)
@@ -1441,10 +1441,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
@@ -1568,7 +1565,6 @@ err_unlock:
        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) {
index 291881937d97fe7b5677db02d722c13f35d1e4f1..4c22143ee84faf9160c1500aa0910b14e42f883e 100644 (file)
@@ -156,12 +156,10 @@ static inline int check_hw_restriction(struct drm_i915_private *i915,
  * This function will partition WOPCM space based on GuC and HuC firmware sizes
  * and will allocate max remaining for use by GuC. This function will also
  * 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.
+ * size. It will fail the WOPCM init if any of these checks fail, so that the
+ * following WOPCM registers setup and GuC firmware uploading would be aborted.
  */
-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);
@@ -173,23 +171,25 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
        int err;
 
        if (!USES_GUC(i915))
-               return 0;
+               return;
 
        GEM_BUG_ON(!wopcm->size);
+       GEM_BUG_ON(wopcm->guc.base);
+       GEM_BUG_ON(wopcm->guc.size);
 
        if (i915_inject_probe_failure(i915))
-               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;
+               return;
        }
 
        if (huc_fw_size >= wopcm->size) {
                DRM_ERROR("HuC FW (%uKiB) is too big to fit in WOPCM.",
                          huc_fw_size / 1024);
-               return -E2BIG;
+               return;
        }
 
        guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
@@ -197,7 +197,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;
+               return;
        }
 
        guc_wopcm_size = wopcm->size - guc_wopcm_base - ctx_rsvd;
@@ -211,16 +211,16 @@ 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;
+               return;
        }
 
        err = check_hw_restriction(i915, guc_wopcm_base, guc_wopcm_size,
                                   huc_fw_size);
        if (err)
-               return err;
+               return;
 
        wopcm->guc.base = guc_wopcm_base;
        wopcm->guc.size = guc_wopcm_size;
-
-       return 0;
+       GEM_BUG_ON(!wopcm->guc.base);
+       GEM_BUG_ON(!wopcm->guc.size);
 }
index f9b603205bb156bc27e99cd40b732f74066fc3ab..17d6aa86008a99202f9ce149459223c4002e5910 100644 (file)
@@ -55,6 +55,6 @@ 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);
+void intel_wopcm_init(struct intel_wopcm *wopcm);
 
 #endif