After GPU reset, GuC HW needs to be reinitialized (with FW reload). Unfortunately, we're doing some extra work there (mostly allocating stuff), work that can be moved to guc_init and called once at driver load time. As a side effect we're no longer hitting an assert in i915_ggtt_enable_guc on suspend/resume. v2: Do not duplicate disable_communication / reset_guc_interrupts References: 04f7b24eccdf ("drm/i915/guc: Assert that we switch between known ggtt->invalidate functions") Signed-off-by: Michał Winiarski <michal.winiarski@xxxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx> Cc: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx> Reviewed-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 4 +++ drivers/gpu/drm/i915/intel_uc.c | 71 ++++++++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_uc.h | 2 ++ 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 285c8b238bff..ca9f4b2862eb 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -617,6 +617,7 @@ static void i915_gem_fini(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->drm.struct_mutex); intel_uc_fini_hw(dev_priv); + intel_uc_fini(dev_priv); i915_gem_cleanup_engines(dev_priv); i915_gem_contexts_fini(dev_priv); mutex_unlock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4b2ca43a610f..77e4091a7c71 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5187,6 +5187,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv) intel_init_gt_powersave(dev_priv); + ret = intel_uc_init(dev_priv); + if (ret) + goto out_unlock; + ret = i915_gem_init_hw(dev_priv); if (ret) goto out_unlock; diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 785850838a44..907deac6e3fa 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -214,26 +214,20 @@ void intel_uc_fini_wq(struct drm_i915_private *dev_priv) intel_guc_fini_wq(&dev_priv->guc); } -int intel_uc_init_hw(struct drm_i915_private *dev_priv) +int intel_uc_init(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - struct intel_huc *huc = &dev_priv->huc; - int ret, attempts; + int ret; if (!USES_GUC(dev_priv)) return 0; - if (!HAS_GUC(dev_priv)) { - ret = -ENODEV; - goto err_out; - } - - guc_disable_communication(guc); - gen9_reset_guc_interrupts(dev_priv); + if (!HAS_GUC(dev_priv)) + return -ENODEV; ret = intel_guc_init(guc); if (ret) - goto err_out; + return ret; if (USES_GUC_SUBMISSION(dev_priv)) { /* @@ -241,10 +235,44 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) * if we are planning to enable submission later */ ret = intel_guc_submission_init(guc); - if (ret) - goto err_guc; + if (ret) { + intel_guc_fini(guc); + return ret; + } } + return 0; +} + +void intel_uc_fini(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + + if (!USES_GUC(dev_priv)) + return; + + GEM_BUG_ON(!HAS_GUC(dev_priv)); + + if (USES_GUC_SUBMISSION(dev_priv)) + intel_guc_submission_fini(guc); + + intel_guc_fini(guc); +} + +int intel_uc_init_hw(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + struct intel_huc *huc = &dev_priv->huc; + int ret, attempts; + + if (!USES_GUC(dev_priv)) + return 0; + + GEM_BUG_ON(!HAS_GUC(dev_priv)); + + guc_disable_communication(guc); + gen9_reset_guc_interrupts(dev_priv); + /* init WOPCM */ I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv)); I915_WRITE(DMA_GUC_WOPCM_OFFSET, @@ -264,12 +292,12 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) */ ret = __intel_uc_reset_hw(dev_priv); if (ret) - goto err_submission; + goto err_out; if (USES_HUC(dev_priv)) { ret = intel_huc_init_hw(huc); if (ret) - goto err_submission; + goto err_out; } intel_guc_init_params(guc); @@ -322,11 +350,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) guc_disable_communication(guc); err_log_capture: guc_capture_load_err_log(guc); -err_submission: - if (USES_GUC_SUBMISSION(dev_priv)) - intel_guc_submission_fini(guc); -err_guc: - intel_guc_fini(guc); err_out: /* * Note that there is no fallback as either user explicitly asked for @@ -348,15 +371,13 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) if (!USES_GUC(dev_priv)) return; + GEM_BUG_ON(!HAS_GUC(dev_priv)); + if (USES_GUC_SUBMISSION(dev_priv)) intel_guc_submission_disable(guc); guc_disable_communication(guc); - if (USES_GUC_SUBMISSION(dev_priv)) { + if (USES_GUC_SUBMISSION(dev_priv)) gen9_disable_guc_interrupts(dev_priv); - intel_guc_submission_fini(guc); - } - - intel_guc_fini(guc); } diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 53edfeaf56b0..8a7249722ef1 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -37,6 +37,8 @@ int intel_uc_init_wq(struct drm_i915_private *dev_priv); void intel_uc_fini_wq(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); +int intel_uc_init(struct drm_i915_private *dev_priv); +void intel_uc_fini(struct drm_i915_private *dev_priv); static inline bool intel_uc_is_using_guc(void) { -- 2.14.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx