drm/i915/uc: Fetch GuC/HuC firmwares from guc/huc specific init
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Thu, 28 Jun 2018 14:15:21 +0000 (14:15 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Jun 2018 21:51:33 +0000 (22:51 +0100)
We're fetching GuC/HuC firmwares directly from uc level during
init_early stage but this breaks guc/huc struct isolation and
also strict SW-only initialization rule for init_early. Move fw
fetching to init phase and do it separately per guc/huc struct.

v2: don't forget to move wopcm_init - Michele
v3: fetch in init_misc phase - Michal

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Michel Thierry <michel.thierry@intel.com>
Reviewed-by: Michel Thierry <michel.thierry@intel.com> #2
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20180628141522.62788-2-michal.wajdeczko@intel.com
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_guc.c
drivers/gpu/drm/i915/intel_huc.c
drivers/gpu/drm/i915/intel_huc.h
drivers/gpu/drm/i915/intel_uc.c

index 5a9cae604e2b839204a55fb55a5e5040549ba6be..8954db6ab083b1f0deedb508b4db3998add05580 100644 (file)
@@ -5459,13 +5459,13 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
        if (ret)
                return ret;
 
-       ret = intel_wopcm_init(&dev_priv->wopcm);
+       ret = intel_uc_init_misc(dev_priv);
        if (ret)
                return ret;
 
-       ret = intel_uc_init_misc(dev_priv);
+       ret = intel_wopcm_init(&dev_priv->wopcm);
        if (ret)
-               return ret;
+               goto err_uc_misc;
 
        /* This is just a security blanket to placate dragons.
         * On some systems, we very sporadically observe that the first TLBs
@@ -5563,6 +5563,7 @@ err_unlock:
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
        mutex_unlock(&dev_priv->drm.struct_mutex);
 
+err_uc_misc:
        intel_uc_fini_misc(dev_priv);
 
        if (ret != -EIO)
index 0b06f27d3e1ad18d31036710b92399018eb000f7..53b43bc73c017d29cf7fe1840cd0cdd3b63d6256 100644 (file)
@@ -139,6 +139,7 @@ static void guc_fini_wq(struct intel_guc *guc)
 
 int intel_guc_init_misc(struct intel_guc *guc)
 {
+       struct drm_i915_private *i915 = guc_to_i915(guc);
        int ret;
 
        guc_init_ggtt_pin_bias(guc);
@@ -147,11 +148,14 @@ int intel_guc_init_misc(struct intel_guc *guc)
        if (ret)
                return ret;
 
+       intel_uc_fw_fetch(i915, &guc->fw);
+
        return 0;
 }
 
 void intel_guc_fini_misc(struct intel_guc *guc)
 {
+       intel_uc_fw_fini(&guc->fw);
        guc_fini_wq(guc);
 }
 
@@ -189,7 +193,7 @@ int intel_guc_init(struct intel_guc *guc)
 
        ret = guc_shared_data_create(guc);
        if (ret)
-               return ret;
+               goto err_fetch;
        GEM_BUG_ON(!guc->shared_data);
 
        ret = intel_guc_log_create(&guc->log);
@@ -210,6 +214,8 @@ err_log:
        intel_guc_log_destroy(&guc->log);
 err_shared:
        guc_shared_data_destroy(guc);
+err_fetch:
+       intel_uc_fw_fini(&guc->fw);
        return ret;
 }
 
@@ -221,6 +227,7 @@ void intel_guc_fini(struct intel_guc *guc)
        intel_guc_ads_destroy(guc);
        intel_guc_log_destroy(&guc->log);
        guc_shared_data_destroy(guc);
+       intel_uc_fw_fini(&guc->fw);
 }
 
 static u32 guc_ctl_debug_flags(struct intel_guc *guc)
index 29128527740350e63c79fa604c32185b3f8db319..ffcad5fad6a7b4e6a24b1e34d53964caaeebfaae 100644 (file)
@@ -32,6 +32,14 @@ void intel_huc_init_early(struct intel_huc *huc)
        intel_huc_fw_init_early(huc);
 }
 
+int intel_huc_init_misc(struct intel_huc *huc)
+{
+       struct drm_i915_private *i915 = huc_to_i915(huc);
+
+       intel_uc_fw_fetch(i915, &huc->fw);
+       return 0;
+}
+
 /**
  * intel_huc_auth() - Authenticate HuC uCode
  * @huc: intel_huc structure
index aa854907abac82b47f69d32d22a9e5cdddad7900..7e41d870b509cfa3c2736827c07f00a9159be2af 100644 (file)
@@ -36,9 +36,15 @@ struct intel_huc {
 };
 
 void intel_huc_init_early(struct intel_huc *huc);
+int intel_huc_init_misc(struct intel_huc *huc);
 int intel_huc_auth(struct intel_huc *huc);
 int intel_huc_check_status(struct intel_huc *huc);
 
+static inline void intel_huc_fini_misc(struct intel_huc *huc)
+{
+       intel_uc_fw_fini(&huc->fw);
+}
+
 static inline int intel_huc_sanitize(struct intel_huc *huc)
 {
        intel_uc_fw_sanitize(&huc->fw);
index cd49b4f510f0ab79cd728cea6b42215110e39529..7c95697e1a358d90a56509fa7d5e66ca2e6cb747 100644 (file)
@@ -171,24 +171,11 @@ void intel_uc_init_early(struct drm_i915_private *i915)
        intel_huc_init_early(huc);
 
        sanitize_options_early(i915);
-
-       if (USES_GUC(i915))
-               intel_uc_fw_fetch(i915, &guc->fw);
-
-       if (USES_HUC(i915))
-               intel_uc_fw_fetch(i915, &huc->fw);
 }
 
 void intel_uc_cleanup_early(struct drm_i915_private *i915)
 {
        struct intel_guc *guc = &i915->guc;
-       struct intel_huc *huc = &i915->huc;
-
-       if (USES_HUC(i915))
-               intel_uc_fw_fini(&huc->fw);
-
-       if (USES_GUC(i915))
-               intel_uc_fw_fini(&guc->fw);
 
        guc_free_load_err_log(guc);
 }
@@ -252,6 +239,7 @@ static void guc_disable_communication(struct intel_guc *guc)
 int intel_uc_init_misc(struct drm_i915_private *i915)
 {
        struct intel_guc *guc = &i915->guc;
+       struct intel_huc *huc = &i915->huc;
        int ret;
 
        if (!USES_GUC(i915))
@@ -261,16 +249,30 @@ int intel_uc_init_misc(struct drm_i915_private *i915)
        if (ret)
                return ret;
 
+       if (USES_HUC(i915)) {
+               ret = intel_huc_init_misc(huc);
+               if (ret)
+                       goto err_guc;
+       }
+
        return 0;
+
+err_guc:
+       intel_guc_fini_misc(guc);
+       return ret;
 }
 
 void intel_uc_fini_misc(struct drm_i915_private *i915)
 {
        struct intel_guc *guc = &i915->guc;
+       struct intel_huc *huc = &i915->huc;
 
        if (!USES_GUC(i915))
                return;
 
+       if (USES_HUC(i915))
+               intel_huc_fini_misc(huc);
+
        intel_guc_fini_misc(guc);
 }