linux/drivers/gpu/drm/i915/gt/uc/intel_uc.h

100 lines
3.3 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2014-2019 Intel Corporation
*/
#ifndef _INTEL_UC_H_
#define _INTEL_UC_H_
#include "intel_guc.h"
#include "intel_guc_submission.h"
#include "intel_huc.h"
#include "i915_params.h"
struct intel_uc;
struct intel_uc_ops {
int (*sanitize)(struct intel_uc *uc);
void (*init_fw)(struct intel_uc *uc);
void (*fini_fw)(struct intel_uc *uc);
int (*init)(struct intel_uc *uc);
void (*fini)(struct intel_uc *uc);
int (*init_hw)(struct intel_uc *uc);
void (*fini_hw)(struct intel_uc *uc);
};
struct intel_uc {
struct intel_uc_ops const *ops;
struct intel_guc guc;
struct intel_huc huc;
drm/i915/uc: Move GuC error log to uc and release it on fini When we fail to load GuC and want to abort probe, we hit: <7> [229.915779] i915 0000:00:02.0: [drm:intel_uc_init_hw [i915]] GuC initialization failed -6 <7> [229.915813] i915 0000:00:02.0: [drm:i915_gem_init_hw [i915]] Enabling uc failed (-6) <4> [229.953354] ------------[ cut here ]------------ <4> [229.953355] WARN_ON(dev_priv->mm.shrink_count) <4> [229.953406] WARNING: CPU: 9 PID: 3287 at drivers/gpu/drm/i915/i915_gem.c:1684 i915_gem_cleanup_early+0xfc/0x110 [i915] <4> [229.953464] Call Trace: <4> [229.953489] i915_driver_late_release+0x19/0x60 [i915] <4> [229.953514] i915_driver_probe+0xb82/0x18a0 [i915] <4> [229.953519] ? __pm_runtime_resume+0x4f/0x80 <4> [229.953545] i915_pci_probe+0x43/0x1b0 [i915] ... <4> [229.962951] ------------[ cut here ]------------ <4> [229.962956] DEBUG_LOCKS_WARN_ON(lock->magic != lock) <4> [229.962959] WARNING: CPU: 8 PID: 2395 at kernel/locking/mutex.c:912 __mutex_lock+0x750/0x9b0 <4> [229.963091] Call Trace: <4> [229.963129] ? i915_vma_destroy+0x86/0x350 [i915] <4> [229.963166] ? i915_vma_destroy+0x86/0x350 [i915] <4> [229.963201] i915_vma_destroy+0x86/0x350 [i915] <4> [229.963236] __i915_gem_free_objects+0xb8/0x510 [i915] <4> [229.963270] __i915_gem_free_work+0x5a/0x90 [i915] <4> [229.963275] process_one_work+0x245/0x610 as since commit 6f76098fe0f3 ("drm/i915/uc: Move uC early functions inside the GT ones") we cleanup uc after gem. Move captured GuC load error log to uc struct and release it in intel_uc_fini() instead of intel_uc_driver_late_release() Note that intel_uc_driver_late_release() is now empty, but we can leave it as a placeholder for future code. 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-5-michal.wajdeczko@intel.com
2019-08-02 18:40:53 +00:00
/* Snapshot of GuC log from last failed load */
struct drm_i915_gem_object *load_err_log;
};
void intel_uc_init_early(struct intel_uc *uc);
void intel_uc_driver_late_release(struct intel_uc *uc);
void intel_uc_init_mmio(struct intel_uc *uc);
void intel_uc_reset_prepare(struct intel_uc *uc);
void intel_uc_suspend(struct intel_uc *uc);
void intel_uc_runtime_suspend(struct intel_uc *uc);
int intel_uc_resume(struct intel_uc *uc);
int intel_uc_runtime_resume(struct intel_uc *uc);
drm/i915/uc: Improve tracking of uC init status To be able to setup GuC submission functions during engine init we need to commit to using GuC as soon as possible. Currently, the only thing that can stop us from using the microcontrollers once we've fetched the blobs is a fundamental error (e.g. OOM); given that if we hit such an error we can't really fall-back to anything, we can "officialize" the FW fetching completion as the moment at which we're committing to using GuC. To better differentiate this case, the uses_guc check, which indicates that GuC is supported and was selected in modparam, is renamed to wants_guc and a new uses_guc is introduced to represent the case were we're committed to using the GuC. Note that uses_guc does still not imply that the blob is actually loaded on the HW (is_running is the check for that). Also, since we need to have attempted the fetch for the result of uses_guc to be meaningful, we need to make sure we've moved away from INTEL_UC_FIRMWARE_SELECTED. All the GuC changes have been mirrored on the HuC for coherency. v2: split fetch return changes and new macros to their own patches, support HuC only if GuC is wanted, improve "used" state description (Michal) v3: s/wants_huc/uses_huc in uc_init_wopcm Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Fernando Pacheco <fernando.pacheco@intel.com> #v1 Reviewed-by: John Harrison <John.C.Harrison@Intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20200218223327.11058-6-daniele.ceraolospurio@intel.com
2020-02-18 22:33:23 +00:00
/*
* We need to know as early as possible if we're going to use GuC or not to
* take the correct setup paths. Additionally, once we've started loading the
* GuC, it is unsafe to keep executing without it because some parts of the HW,
* a subset of which is not cleaned on GT reset, will start expecting the GuC FW
* to be running.
* To solve both these requirements, we commit to using the microcontrollers if
* the relevant modparam is set and the blobs are found on the system. At this
* stage, the only thing that can stop us from attempting to load the blobs on
* the HW and use them is a fundamental issue (e.g. no memory for our
* structures); if we hit such a problem during driver load we're broken even
* without GuC, so there is no point in trying to fall back.
*
* Given the above, we can be in one of 4 states, with the last one implying
* we're committed to using the microcontroller:
* - Not supported: not available in HW and/or firmware not defined.
* - Supported: available in HW and firmware defined.
* - Wanted: supported + enabled in modparam.
* - In use: wanted + firmware found on the system and successfully fetched.
*/
#define __uc_state_checker(x, func, state, required) \
static inline bool intel_uc_##state##_##func(struct intel_uc *uc) \
{ \
return intel_##func##_is_##required(&uc->x); \
}
#define uc_state_checkers(x, func) \
__uc_state_checker(x, func, supports, supported) \
__uc_state_checker(x, func, wants, wanted) \
__uc_state_checker(x, func, uses, used)
uc_state_checkers(guc, guc);
uc_state_checkers(huc, huc);
uc_state_checkers(guc, guc_submission);
#undef uc_state_checkers
#undef __uc_state_checker
#define intel_uc_ops_function(_NAME, _OPS, _TYPE, _RET) \
static inline _TYPE intel_uc_##_NAME(struct intel_uc *uc) \
{ \
if (uc->ops->_OPS) \
return uc->ops->_OPS(uc); \
return _RET; \
}
intel_uc_ops_function(sanitize, sanitize, int, 0);
intel_uc_ops_function(fetch_firmwares, init_fw, void, );
intel_uc_ops_function(cleanup_firmwares, fini_fw, void, );
intel_uc_ops_function(init, init, int, 0);
intel_uc_ops_function(fini, fini, void, );
intel_uc_ops_function(init_hw, init_hw, int, 0);
intel_uc_ops_function(fini_hw, fini_hw, void, );
#undef intel_uc_ops_function
#endif