UAPI Changes: - drm/i915/guc: Use context hints for GT frequency Allow user to provide a low latency context hint. When set, KMD sends a hint to GuC which results in special handling for this context. SLPC will ramp the GT frequency aggressively every time it switches to this context. The down freq threshold will also be lower so GuC will ramp down the GT freq for this context more slowly. We also disable waitboost for this context as that will interfere with the strategy. We need to enable the use of SLPC Compute strategy during init, but it will apply only to contexts that set this bit during context creation. Userland can check whether this feature is supported using a new param- I915_PARAM_HAS_CONTEXT_FREQ_HINT. This flag is true for all guc submission enabled platforms as they use SLPC for frequency management. The Mesa usage model for this flag is here - https://gitlab.freedesktop.org/sushmave/mesa/-/commits/compute_hint - drm/i915/gt: Enable only one CCS for compute workload Enable only one CCS engine by default with all the compute sices allocated to it. While generating the list of UABI engines to be exposed to the user, exclude any additional CCS engines beyond the first instance *** NOTE: This W/A will make all DG2 SKUs appear like single CCS SKUs by default to mitigate a hardware bug. All the EUs will still remain usable, and all the userspace drivers have been confirmed to be able to dynamically detect the change in number of CCS engines and adjust. For the smaller percent of applications that get perf benefit from letting the userspace driver dispatch across all 4 CCS engines we will be introducing a sysfs control as a later patch to choose 4 CCS each with 25% EUs (or 50% if 2 CCS). NOTE: A regression has been reported at https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10895 However Andi has been triaging the issue and we're closing in a fix to the gap in the W/A implementation: https://lists.freedesktop.org/archives/intel-gfx/2024-April/348747.html Driver Changes: - Add new and fix to existing workarounds: Wa_14018575942 (MTL), Wa_16019325821 (Gen12.70), Wa_14019159160 (MTL), Wa_16015675438, Wa_14020495402 (Gen12.70) (Tejas, John, Lucas) - Fix UAF on destroy against retire race and remove two earlier partial fixes (Janusz) - Limit the reserved VM space to only the platforms that need it (Andi) - Reset queue_priority_hint on parking for execlist platforms (Chris) - Fix gt reset with GuC submission is disabled (Nirmoy) - Correct capture of EIR register on hang (John) - Remove usage of the deprecated ida_simple_xx() API - Refactor confusing __intel_gt_reset() (Nirmoy) - Fix the fix for GuC reset lock confusion (John) - Simplify/extend platform check for Wa_14018913170 (John) - Replace dev_priv with i915 (Andi) - Add and use gt_to_guc() wrapper (Andi) - Remove bogus null check (Rodrigo, Dan) . Selftest improvements (Janusz, Nirmoy, Daniele) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/ZitVBTvZmityDi7D@jlahtine-mobl.ger.corp.intel.com
211 lines
7 KiB
C
211 lines
7 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Copyright © 2019 Intel Corporation
|
|
*/
|
|
|
|
#ifndef __INTEL_GT__
|
|
#define __INTEL_GT__
|
|
|
|
#include "intel_engine_types.h"
|
|
#include "intel_gt_types.h"
|
|
#include "intel_reset.h"
|
|
|
|
struct drm_i915_private;
|
|
struct drm_printer;
|
|
|
|
/*
|
|
* Check that the GT is a graphics GT and has an IP version within the
|
|
* specified range (inclusive).
|
|
*/
|
|
#define IS_GFX_GT_IP_RANGE(gt, from, until) ( \
|
|
BUILD_BUG_ON_ZERO((from) < IP_VER(2, 0)) + \
|
|
BUILD_BUG_ON_ZERO((until) < (from)) + \
|
|
((gt)->type != GT_MEDIA && \
|
|
GRAPHICS_VER_FULL((gt)->i915) >= (from) && \
|
|
GRAPHICS_VER_FULL((gt)->i915) <= (until)))
|
|
|
|
/*
|
|
* Check that the GT is a media GT and has an IP version within the
|
|
* specified range (inclusive).
|
|
*
|
|
* Only usable on platforms with a standalone media design (i.e., IP version 13
|
|
* and higher).
|
|
*/
|
|
#define IS_MEDIA_GT_IP_RANGE(gt, from, until) ( \
|
|
BUILD_BUG_ON_ZERO((from) < IP_VER(13, 0)) + \
|
|
BUILD_BUG_ON_ZERO((until) < (from)) + \
|
|
((gt) && (gt)->type == GT_MEDIA && \
|
|
MEDIA_VER_FULL((gt)->i915) >= (from) && \
|
|
MEDIA_VER_FULL((gt)->i915) <= (until)))
|
|
|
|
/*
|
|
* Check that the GT is a graphics GT with a specific IP version and has
|
|
* a stepping in the range [from, until). The lower stepping bound is
|
|
* inclusive, the upper bound is exclusive. The most common use-case of this
|
|
* macro is for checking bounds for workarounds, which usually have a stepping
|
|
* ("from") at which the hardware issue is first present and another stepping
|
|
* ("until") at which a hardware fix is present and the software workaround is
|
|
* no longer necessary. E.g.,
|
|
*
|
|
* IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0)
|
|
* IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B1, STEP_FOREVER)
|
|
*
|
|
* "STEP_FOREVER" can be passed as "until" for workarounds that have no upper
|
|
* stepping bound for the specified IP version.
|
|
*/
|
|
#define IS_GFX_GT_IP_STEP(gt, ipver, from, until) ( \
|
|
BUILD_BUG_ON_ZERO((until) <= (from)) + \
|
|
(IS_GFX_GT_IP_RANGE((gt), (ipver), (ipver)) && \
|
|
IS_GRAPHICS_STEP((gt)->i915, (from), (until))))
|
|
|
|
/*
|
|
* Check that the GT is a media GT with a specific IP version and has
|
|
* a stepping in the range [from, until). The lower stepping bound is
|
|
* inclusive, the upper bound is exclusive. The most common use-case of this
|
|
* macro is for checking bounds for workarounds, which usually have a stepping
|
|
* ("from") at which the hardware issue is first present and another stepping
|
|
* ("until") at which a hardware fix is present and the software workaround is
|
|
* no longer necessary. "STEP_FOREVER" can be passed as "until" for
|
|
* workarounds that have no upper stepping bound for the specified IP version.
|
|
*
|
|
* This macro may only be used to match on platforms that have a standalone
|
|
* media design (i.e., media version 13 or higher).
|
|
*/
|
|
#define IS_MEDIA_GT_IP_STEP(gt, ipver, from, until) ( \
|
|
BUILD_BUG_ON_ZERO((until) <= (from)) + \
|
|
(IS_MEDIA_GT_IP_RANGE((gt), (ipver), (ipver)) && \
|
|
IS_MEDIA_STEP((gt)->i915, (from), (until))))
|
|
|
|
#define GT_TRACE(gt, fmt, ...) do { \
|
|
const struct intel_gt *gt__ __maybe_unused = (gt); \
|
|
GEM_TRACE("%s " fmt, dev_name(gt__->i915->drm.dev), \
|
|
##__VA_ARGS__); \
|
|
} while (0)
|
|
|
|
static inline bool gt_is_root(struct intel_gt *gt)
|
|
{
|
|
return !gt->info.id;
|
|
}
|
|
|
|
bool intel_gt_needs_wa_16018031267(struct intel_gt *gt);
|
|
bool intel_gt_needs_wa_22016122933(struct intel_gt *gt);
|
|
|
|
#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \
|
|
intel_gt_needs_wa_16018031267(engine->gt) && \
|
|
engine->class == COPY_ENGINE_CLASS && engine->instance == 0)
|
|
|
|
static inline struct intel_gt *uc_to_gt(struct intel_uc *uc)
|
|
{
|
|
return container_of(uc, struct intel_gt, uc);
|
|
}
|
|
|
|
static inline struct intel_gt *guc_to_gt(struct intel_guc *guc)
|
|
{
|
|
return container_of(guc, struct intel_gt, uc.guc);
|
|
}
|
|
|
|
static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
|
|
{
|
|
return container_of(huc, struct intel_gt, uc.huc);
|
|
}
|
|
|
|
static inline struct intel_gt *gsc_uc_to_gt(struct intel_gsc_uc *gsc_uc)
|
|
{
|
|
return container_of(gsc_uc, struct intel_gt, uc.gsc);
|
|
}
|
|
|
|
static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
|
|
{
|
|
return container_of(gsc, struct intel_gt, gsc);
|
|
}
|
|
|
|
static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
|
|
{
|
|
return guc_to_gt(guc)->i915;
|
|
}
|
|
|
|
static inline struct intel_guc *gt_to_guc(struct intel_gt *gt)
|
|
{
|
|
return >->uc.guc;
|
|
}
|
|
|
|
void intel_gt_common_init_early(struct intel_gt *gt);
|
|
int intel_root_gt_init_early(struct drm_i915_private *i915);
|
|
int intel_gt_assign_ggtt(struct intel_gt *gt);
|
|
int intel_gt_init_mmio(struct intel_gt *gt);
|
|
int __must_check intel_gt_init_hw(struct intel_gt *gt);
|
|
int intel_gt_init(struct intel_gt *gt);
|
|
void intel_gt_driver_register(struct intel_gt *gt);
|
|
|
|
void intel_gt_driver_unregister(struct intel_gt *gt);
|
|
void intel_gt_driver_remove(struct intel_gt *gt);
|
|
void intel_gt_driver_release(struct intel_gt *gt);
|
|
void intel_gt_driver_late_release_all(struct drm_i915_private *i915);
|
|
|
|
int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);
|
|
|
|
void intel_gt_check_and_clear_faults(struct intel_gt *gt);
|
|
i915_reg_t intel_gt_perf_limit_reasons_reg(struct intel_gt *gt);
|
|
void intel_gt_clear_error_registers(struct intel_gt *gt,
|
|
intel_engine_mask_t engine_mask);
|
|
|
|
void intel_gt_flush_ggtt_writes(struct intel_gt *gt);
|
|
void intel_gt_chipset_flush(struct intel_gt *gt);
|
|
|
|
static inline u32 intel_gt_scratch_offset(const struct intel_gt *gt,
|
|
enum intel_gt_scratch_field field)
|
|
{
|
|
return i915_ggtt_offset(gt->scratch) + field;
|
|
}
|
|
|
|
static inline bool intel_gt_has_unrecoverable_error(const struct intel_gt *gt)
|
|
{
|
|
return test_bit(I915_WEDGED_ON_INIT, >->reset.flags) ||
|
|
test_bit(I915_WEDGED_ON_FINI, >->reset.flags);
|
|
}
|
|
|
|
static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
|
|
{
|
|
GEM_BUG_ON(intel_gt_has_unrecoverable_error(gt) &&
|
|
!test_bit(I915_WEDGED, >->reset.flags));
|
|
|
|
return unlikely(test_bit(I915_WEDGED, >->reset.flags));
|
|
}
|
|
|
|
int intel_gt_probe_all(struct drm_i915_private *i915);
|
|
int intel_gt_tiles_init(struct drm_i915_private *i915);
|
|
void intel_gt_release_all(struct drm_i915_private *i915);
|
|
|
|
#define for_each_gt(gt__, i915__, id__) \
|
|
for ((id__) = 0; \
|
|
(id__) < I915_MAX_GT; \
|
|
(id__)++) \
|
|
for_each_if(((gt__) = (i915__)->gt[(id__)]))
|
|
|
|
/* Simple iterator over all initialised engines */
|
|
#define for_each_engine(engine__, gt__, id__) \
|
|
for ((id__) = 0; \
|
|
(id__) < I915_NUM_ENGINES; \
|
|
(id__)++) \
|
|
for_each_if ((engine__) = (gt__)->engine[(id__)])
|
|
|
|
/* Iterator over subset of engines selected by mask */
|
|
#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
|
|
for ((tmp__) = (mask__) & (gt__)->info.engine_mask; \
|
|
(tmp__) ? \
|
|
((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
|
|
0;)
|
|
|
|
void intel_gt_info_print(const struct intel_gt_info *info,
|
|
struct drm_printer *p);
|
|
|
|
void intel_gt_watchdog_work(struct work_struct *work);
|
|
|
|
enum i915_map_type intel_gt_coherent_map_type(struct intel_gt *gt,
|
|
struct drm_i915_gem_object *obj,
|
|
bool always_coherent);
|
|
|
|
void intel_gt_bind_context_set_ready(struct intel_gt *gt);
|
|
void intel_gt_bind_context_set_unready(struct intel_gt *gt);
|
|
bool intel_gt_is_bind_context_ready(struct intel_gt *gt);
|
|
#endif /* __INTEL_GT_H__ */
|