diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_uc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_uc.c | 90 |
1 files changed, 63 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 25b80ffe71ad..63fc12cbc25d 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -22,11 +22,11 @@ * */ +#include "gt/intel_reset.h" #include "intel_uc.h" #include "intel_guc_submission.h" #include "intel_guc.h" #include "i915_drv.h" -#include "i915_reset.h" static void guc_free_load_err_log(struct intel_guc *guc); @@ -224,6 +224,17 @@ static int guc_enable_communication(struct intel_guc *guc) return 0; } +static void guc_stop_communication(struct intel_guc *guc) +{ + struct drm_i915_private *i915 = guc_to_i915(guc); + + if (HAS_GUC_CT(i915)) + intel_guc_ct_stop(&guc->ct); + + guc->send = intel_guc_send_nop; + guc->handler = intel_guc_to_host_event_handler_nop; +} + static void guc_disable_communication(struct intel_guc *guc) { struct drm_i915_private *i915 = guc_to_i915(guc); @@ -280,6 +291,7 @@ void intel_uc_fini_misc(struct drm_i915_private *i915) int intel_uc_init(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; + struct intel_huc *huc = &i915->huc; int ret; if (!USES_GUC(i915)) @@ -292,19 +304,30 @@ int intel_uc_init(struct drm_i915_private *i915) if (ret) return ret; + if (USES_HUC(i915)) { + ret = intel_huc_init(huc); + if (ret) + goto err_guc; + } + if (USES_GUC_SUBMISSION(i915)) { /* * This is stuff we need to have available at fw load time * if we are planning to enable submission later */ ret = intel_guc_submission_init(guc); - if (ret) { - intel_guc_fini(guc); - return ret; - } + if (ret) + goto err_huc; } return 0; + +err_huc: + if (USES_HUC(i915)) + intel_huc_fini(huc); +err_guc: + intel_guc_fini(guc); + return ret; } void intel_uc_fini(struct drm_i915_private *i915) @@ -319,17 +342,17 @@ void intel_uc_fini(struct drm_i915_private *i915) if (USES_GUC_SUBMISSION(i915)) intel_guc_submission_fini(guc); + if (USES_HUC(i915)) + intel_huc_fini(&i915->huc); + intel_guc_fini(guc); } -void intel_uc_sanitize(struct drm_i915_private *i915) +static void __uc_sanitize(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; struct intel_huc *huc = &i915->huc; - if (!USES_GUC(i915)) - return; - GEM_BUG_ON(!HAS_GUC(i915)); intel_huc_sanitize(huc); @@ -338,6 +361,14 @@ void intel_uc_sanitize(struct drm_i915_private *i915) __intel_uc_reset_hw(i915); } +void intel_uc_sanitize(struct drm_i915_private *i915) +{ + if (!USES_GUC(i915)) + return; + + __uc_sanitize(i915); +} + int intel_uc_init_hw(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; @@ -423,6 +454,8 @@ err_communication: err_log_capture: guc_capture_load_err_log(guc); err_out: + __uc_sanitize(i915); + /* * Note that there is no fallback as either user explicitly asked for * the GuC or driver default option was to run with the GuC enabled. @@ -438,7 +471,7 @@ void intel_uc_fini_hw(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; - if (!USES_GUC(i915)) + if (!intel_guc_is_loaded(guc)) return; GEM_BUG_ON(!HAS_GUC(i915)); @@ -447,6 +480,7 @@ void intel_uc_fini_hw(struct drm_i915_private *i915) intel_guc_submission_disable(guc); guc_disable_communication(guc); + __uc_sanitize(i915); } /** @@ -459,33 +493,38 @@ void intel_uc_reset_prepare(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; - if (!USES_GUC(i915)) + if (!intel_guc_is_loaded(guc)) return; - guc_disable_communication(guc); - intel_uc_sanitize(i915); + guc_stop_communication(guc); + __uc_sanitize(i915); } -int intel_uc_suspend(struct drm_i915_private *i915) +void intel_uc_runtime_suspend(struct drm_i915_private *i915) { struct intel_guc *guc = &i915->guc; int err; - if (!USES_GUC(i915)) - return 0; - - if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) - return 0; + if (!intel_guc_is_loaded(guc)) + return; err = intel_guc_suspend(guc); - if (err) { + if (err) DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err); - return err; - } guc_disable_communication(guc); +} - return 0; +void intel_uc_suspend(struct drm_i915_private *i915) +{ + struct intel_guc *guc = &i915->guc; + intel_wakeref_t wakeref; + + if (!intel_guc_is_loaded(guc)) + return; + + with_intel_runtime_pm(i915, wakeref) + intel_uc_runtime_suspend(i915); } int intel_uc_resume(struct drm_i915_private *i915) @@ -493,10 +532,7 @@ int intel_uc_resume(struct drm_i915_private *i915) struct intel_guc *guc = &i915->guc; int err; - if (!USES_GUC(i915)) - return 0; - - if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) + if (!intel_guc_is_loaded(guc)) return 0; guc_enable_communication(guc); |