Merge tag 'drm-intel-gt-next-2023-09-28' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

Driver Changes:

Fixes/improvements/new stuff:

- Fix TLB-Invalidation seqno store [mtl] (Alan Previn)
- Force a reset on internal GuC error [guc] (John Harrison)
- Define GSC fw [gsc] (Daniele Ceraolo Spurio)
- Update workaround 14016712196 [dg2/mtl] (Tejas Upadhyay)
- Mark requests for GuC virtual engines to avoid use-after-free (Andrzej Hajda)
- Add Wa_14015150844 [dg2/mtl] (Shekhar Chauhan)
- Prevent error pointer dereference (Dan Carpenter)
- Add Wa_18022495364 [tgl,adl,rpl] (Dnyaneshwar Bhadane)
- Fix GuC PMU by moving execlist stats initialization to execlist specific setup (Umesh Nerlige Ramappa)
- Fix PXP firmware load [pxp/mtl] (Alan Previn)
- Fix execution/context state of PXP contexts (Alan Previn)
- Limit the length of an sg list to the requested length (Matthew Wilcox)
- Fix reservation address in ggtt_reserve_guc_top [guc] (Javier Pello)
- Add Wa_18028616096 [dg2] (Shekhar Chauhan)
- Get runtime pm in busyness worker only if already active [guc/pmu] (Umesh Nerlige Ramappa)
- Don't set PIPE_CONTROL_FLUSH_L3 for aux inval (Nirmoy Das)

Future platform enablement:

- Fix and consolidate some workaround checks, make others IP version based [mtl] (Matt Roper)
- Replace Meteorlake subplatforms with IP version checks (Matt Roper)
- Adding DeviceID for Arrowlake-S under MTL [mtl] (Nemesa Garg)
- Run relevant bits of debugfs drop_caches per GT (Tvrtko Ursulin)

Miscellaneous:

- Remove Wa_15010599737 [dg2] (Shekhar Chauhan)
- Align igt_spinner_create_request with hangcheck [selftests] (Jonathan Cavitt)
- Remove pre-production workarounds [dg2] (Matt Roper)
- Tidy some workaround definitions (Matt Roper)
- Wait longer for tasks in migrate selftest [gt] (Jonathan Cavitt)
- Skip WA verification for GEN7_MISCCPCTL on DG2 [gt] (Andrzej Hajda)
- Silence injected failure in the load via GSC path [huc] (Daniele Ceraolo Spurio)
- Refactor deprecated strncpy (Justin Stitt)
- Update RC6 mask for mtl_drpc [debugfs/mtl] (Badal Nilawar)
- Remove a static inline that requires including i915_drv.h [gt] (Jani Nikula)
- Remove inlines from i915_gem_execbuffer.c [gem] (Jani Nikula)
- Remove gtt_offset from stream->oa_buffer.head/.tail [perf] (Ashutosh Dixit)
- Do not disable preemption for resets (Tvrtko Ursulin)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZRVzL02VFuwIkcGl@tursulin-desk
This commit is contained in:
Dave Airlie 2023-10-03 06:02:29 +10:00
commit caacbdc28f
46 changed files with 525 additions and 705 deletions

View File

@ -20,6 +20,7 @@
#include "skl_scaler.h"
#include "skl_universal_plane.h"
#include "skl_watermark.h"
#include "gt/intel_gt.h"
#include "pxp/intel_pxp.h"
static const u32 skl_plane_formats[] = {
@ -2168,11 +2169,6 @@ skl_plane_disable_flip_done(struct intel_plane *plane)
static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
enum pipe pipe, enum plane_id plane_id)
{
/* Wa_14017240301 */
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
return false;
/* Wa_22011186057 */
if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
return false;

View File

@ -405,8 +405,8 @@ static int ext_set_pat(struct i915_user_extension __user *base, void *data)
BUILD_BUG_ON(sizeof(struct drm_i915_gem_create_ext_set_pat) !=
offsetofend(struct drm_i915_gem_create_ext_set_pat, rsvd));
/* Limiting the extension only to Meteor Lake */
if (!IS_METEORLAKE(i915))
/* Limiting the extension only to Xe_LPG and beyond */
if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 70))
return -ENODEV;
if (copy_from_user(&ext, base, sizeof(ext)))

View File

@ -321,7 +321,7 @@ static int eb_pin_engine(struct i915_execbuffer *eb, bool throttle);
static void eb_unpin_engine(struct i915_execbuffer *eb);
static void eb_capture_release(struct i915_execbuffer *eb);
static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
static bool eb_use_cmdparser(const struct i915_execbuffer *eb)
{
return intel_engine_requires_cmd_parser(eb->context->engine) ||
(intel_engine_using_cmd_parser(eb->context->engine) &&
@ -433,7 +433,7 @@ static u64 eb_pin_flags(const struct drm_i915_gem_exec_object2 *entry,
return pin_flags;
}
static inline int
static int
eb_pin_vma(struct i915_execbuffer *eb,
const struct drm_i915_gem_exec_object2 *entry,
struct eb_vma *ev)
@ -486,7 +486,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
return 0;
}
static inline void
static void
eb_unreserve_vma(struct eb_vma *ev)
{
if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
@ -548,7 +548,7 @@ eb_validate_vma(struct i915_execbuffer *eb,
return 0;
}
static inline bool
static bool
is_batch_buffer(struct i915_execbuffer *eb, unsigned int buffer_idx)
{
return eb->args->flags & I915_EXEC_BATCH_FIRST ?
@ -628,8 +628,8 @@ eb_add_vma(struct i915_execbuffer *eb,
return 0;
}
static inline int use_cpu_reloc(const struct reloc_cache *cache,
const struct drm_i915_gem_object *obj)
static int use_cpu_reloc(const struct reloc_cache *cache,
const struct drm_i915_gem_object *obj)
{
if (!i915_gem_object_has_struct_page(obj))
return false;
@ -1107,7 +1107,7 @@ static void eb_destroy(const struct i915_execbuffer *eb)
kfree(eb->buckets);
}
static inline u64
static u64
relocation_target(const struct drm_i915_gem_relocation_entry *reloc,
const struct i915_vma *target)
{
@ -1128,19 +1128,19 @@ static void reloc_cache_init(struct reloc_cache *cache,
cache->node.flags = 0;
}
static inline void *unmask_page(unsigned long p)
static void *unmask_page(unsigned long p)
{
return (void *)(uintptr_t)(p & PAGE_MASK);
}
static inline unsigned int unmask_flags(unsigned long p)
static unsigned int unmask_flags(unsigned long p)
{
return p & ~PAGE_MASK;
}
#define KMAP 0x4 /* after CLFLUSH_FLAGS */
static inline struct i915_ggtt *cache_to_ggtt(struct reloc_cache *cache)
static struct i915_ggtt *cache_to_ggtt(struct reloc_cache *cache)
{
struct drm_i915_private *i915 =
container_of(cache, struct i915_execbuffer, reloc_cache)->i915;

View File

@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
st->nents = 0;
for (i = 0; i < page_count; i++) {
struct folio *folio;
unsigned long nr_pages;
const unsigned int shrink[] = {
I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
0,
@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
}
} while (1);
nr_pages = min_t(unsigned long,
folio_nr_pages(folio), page_count - i);
if (!i ||
sg->length >= max_segment ||
folio_pfn(folio) != next_pfn) {
@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
sg = sg_next(sg);
st->nents++;
sg_set_folio(sg, folio, folio_size(folio), 0);
sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
} else {
/* XXX: could overflow? */
sg->length += folio_size(folio);
sg->length += nr_pages * PAGE_SIZE;
}
next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
i += folio_nr_pages(folio) - 1;
next_pfn = folio_pfn(folio) + nr_pages;
i += nr_pages - 1;
/* Check that the i965g/gm workaround works. */
GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL);

View File

@ -36,7 +36,7 @@ mock_context(struct drm_i915_private *i915,
if (name) {
struct i915_ppgtt *ppgtt;
strncpy(ctx->name, name, sizeof(ctx->name) - 1);
strscpy(ctx->name, name, sizeof(ctx->name));
ppgtt = mock_ppgtt(i915, name);
if (!ppgtt)

View File

@ -4,9 +4,9 @@
*/
#include "gen8_engine_cs.h"
#include "i915_drv.h"
#include "intel_engine_regs.h"
#include "intel_gpu_commands.h"
#include "intel_gt.h"
#include "intel_lrc.h"
#include "intel_ring.h"
@ -226,8 +226,8 @@ u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs)
static int mtl_dummy_pipe_control(struct i915_request *rq)
{
/* Wa_14016712196 */
if (IS_MTL_GRAPHICS_STEP(rq->i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(rq->i915, P, STEP_A0, STEP_B0)) {
if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 71)) ||
IS_DG2(rq->i915)) {
u32 *cs;
/* dummy PIPE_CONTROL + depth flush */
@ -271,8 +271,17 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode)
if (GRAPHICS_VER_FULL(rq->i915) >= IP_VER(12, 70))
bit_group_0 |= PIPE_CONTROL_CCS_FLUSH;
/*
* L3 fabric flush is needed for AUX CCS invalidation
* which happens as part of pipe-control so we can
* ignore PIPE_CONTROL_FLUSH_L3. Also PIPE_CONTROL_FLUSH_L3
* deals with Protected Memory which is not needed for
* AUX CCS invalidation and lead to unwanted side effects.
*/
if (mode & EMIT_FLUSH)
bit_group_1 |= PIPE_CONTROL_FLUSH_L3;
bit_group_1 |= PIPE_CONTROL_TILE_CACHE_FLUSH;
bit_group_1 |= PIPE_CONTROL_FLUSH_L3;
bit_group_1 |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
bit_group_1 |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
/* Wa_1409600907:tgl,adl-p */
@ -799,6 +808,7 @@ u32 *gen12_emit_fini_breadcrumb_xcs(struct i915_request *rq, u32 *cs)
u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs)
{
struct drm_i915_private *i915 = rq->i915;
struct intel_gt *gt = rq->engine->gt;
u32 flags = (PIPE_CONTROL_CS_STALL |
PIPE_CONTROL_TLB_INVALIDATE |
PIPE_CONTROL_TILE_CACHE_FLUSH |
@ -809,8 +819,7 @@ u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs)
PIPE_CONTROL_FLUSH_ENABLE);
/* Wa_14016712196 */
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))
/* dummy PIPE_CONTROL + depth flush */
cs = gen12_emit_pipe_control(cs, 0,
PIPE_CONTROL_DEPTH_CACHE_FLUSH, 0);

View File

@ -558,7 +558,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
DRIVER_CAPS(i915)->has_logical_contexts = true;
ewma__engine_latency_init(&engine->latency);
seqcount_init(&engine->stats.execlists.lock);
ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
@ -1617,9 +1616,7 @@ static int __intel_engine_stop_cs(struct intel_engine_cs *engine,
* Wa_22011802037: Prior to doing a reset, ensure CS is
* stopped, set ring stop bit and prefetch disable bit to halt CS
*/
if (IS_MTL_GRAPHICS_STEP(engine->i915, M, STEP_A0, STEP_B0) ||
(GRAPHICS_VER(engine->i915) >= 11 &&
GRAPHICS_VER_FULL(engine->i915) < IP_VER(12, 70)))
if (intel_engine_reset_needs_wa_22011802037(engine->gt))
intel_uncore_write_fw(uncore, RING_MODE_GEN7(engine->mmio_base),
_MASKED_BIT_ENABLE(GEN12_GFX_PREFETCH_DISABLE));

View File

@ -21,7 +21,7 @@ static void intel_gsc_idle_msg_enable(struct intel_engine_cs *engine)
{
struct drm_i915_private *i915 = engine->i915;
if (IS_METEORLAKE(i915) && engine->id == GSC0) {
if (MEDIA_VER(i915) >= 13 && engine->id == GSC0) {
intel_uncore_write(engine->gt->uncore,
RC_PSMI_CTRL_GSCCS,
_MASKED_BIT_DISABLE(IDLE_MSG_DISABLE));

View File

@ -177,6 +177,7 @@
#define CTX_CTRL_RS_CTX_ENABLE REG_BIT(1)
#define CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT REG_BIT(2)
#define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH REG_BIT(3)
#define GEN12_CTX_CTRL_RUNALONE_MODE REG_BIT(7)
#define GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE REG_BIT(8)
#define RING_CTX_SR_CTL(base) _MMIO((base) + 0x244)
#define RING_SEMA_WAIT_POLL(base) _MMIO((base) + 0x24c)

View File

@ -3001,9 +3001,7 @@ static void execlists_reset_prepare(struct intel_engine_cs *engine)
* Wa_22011802037: In addition to stopping the cs, we need
* to wait for any pending mi force wakeups
*/
if (IS_MTL_GRAPHICS_STEP(engine->i915, M, STEP_A0, STEP_B0) ||
(GRAPHICS_VER(engine->i915) >= 11 &&
GRAPHICS_VER_FULL(engine->i915) < IP_VER(12, 70)))
if (intel_engine_reset_needs_wa_22011802037(engine->gt))
intel_engine_wait_for_pending_mi_fw(engine);
engine->execlists.reset_ccid = active_ccid(engine);
@ -3550,6 +3548,8 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine)
logical_ring_default_vfuncs(engine);
logical_ring_default_irqs(engine);
seqcount_init(&engine->stats.execlists.lock);
if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)
rcs_submission_override(engine);

View File

@ -511,20 +511,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm,
vm->clear_range(vm, vma_res->start, vma_res->vma_size);
}
/*
* Reserve the top of the GuC address space for firmware images. Addresses
* beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC,
* which makes for a suitable range to hold GuC/HuC firmware images if the
* size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT
* is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk
* of the same size anyway, which is far more than needed, to keep the logic
* in uc_fw_ggtt_offset() simple.
*/
#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP)
static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
{
u64 size;
u64 offset;
int ret;
if (!intel_uc_uses_guc(&ggtt->vm.gt->uc))
return 0;
GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);
size = ggtt->vm.total - GUC_GGTT_TOP;
GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE);
offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE;
ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size,
GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
PIN_NOEVICT);
ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw,
GUC_TOP_RESERVE_SIZE, offset,
I915_COLOR_UNEVICTABLE, PIN_NOEVICT);
if (ret)
drm_dbg(&ggtt->vm.i915->drm,
"Failed to reserve top of GGTT for GuC\n");

View File

@ -1019,3 +1019,8 @@ enum i915_map_type intel_gt_coherent_map_type(struct intel_gt *gt,
else
return I915_MAP_WC;
}
bool intel_gt_needs_wa_22016122933(struct intel_gt *gt)
{
return MEDIA_VER_FULL(gt->i915) == IP_VER(13, 0) && gt->type == GT_MEDIA;
}

View File

@ -6,7 +6,6 @@
#ifndef __INTEL_GT__
#define __INTEL_GT__
#include "i915_drv.h"
#include "intel_engine_types.h"
#include "intel_gt_types.h"
#include "intel_reset.h"
@ -14,6 +13,69 @@
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), \
@ -25,10 +87,7 @@ static inline bool gt_is_root(struct intel_gt *gt)
return !gt->info.id;
}
static inline bool intel_gt_needs_wa_22016122933(struct intel_gt *gt)
{
return MEDIA_VER_FULL(gt->i915) == IP_VER(13, 0) && gt->type == GT_MEDIA;
}
bool intel_gt_needs_wa_22016122933(struct intel_gt *gt);
static inline struct intel_gt *uc_to_gt(struct intel_uc *uc)
{

View File

@ -4,7 +4,7 @@
*/
#include "i915_drv.h"
#include "intel_gt.h"
#include "intel_gt_mcr.h"
#include "intel_gt_print.h"
#include "intel_gt_regs.h"
@ -166,8 +166,8 @@ void intel_gt_mcr_init(struct intel_gt *gt)
gt->steering_table[OADDRM] = xelpmp_oaddrm_steering_table;
} else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) {
/* Wa_14016747170 */
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
if (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_A0, STEP_B0))
fuse = REG_FIELD_GET(MTL_GT_L3_EXC_MASK,
intel_uncore_read(gt->uncore,
MTL_GT_ACTIVITY_FACTOR));

View File

@ -290,7 +290,6 @@ static int mtl_drpc(struct seq_file *m)
seq_puts(m, "RC6\n");
break;
default:
MISSING_CASE(REG_FIELD_GET(MTL_CC_MASK, gt_core_status));
seq_puts(m, "Unknown\n");
break;
}

View File

@ -26,7 +26,7 @@
#define MTL_CAGF_MASK REG_GENMASK(8, 0)
#define MTL_CC0 0x0
#define MTL_CC6 0x3
#define MTL_CC_MASK REG_GENMASK(12, 9)
#define MTL_CC_MASK REG_GENMASK(10, 9)
/* RPM unit config (Gen8+) */
#define RPM_CONFIG0 _MMIO(0xd00)
@ -164,6 +164,8 @@
#define GEN9_CSFE_CHICKEN1_RCS _MMIO(0x20d4)
#define GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE (1 << 2)
#define GEN11_ENABLE_32_PLANE_MODE (1 << 7)
#define GEN12_CS_DEBUG_MODE2 _MMIO(0x20d8)
#define INSTRUCTION_STATE_CACHE_INVALIDATE REG_BIT(6)
#define GEN7_FF_SLICE_CS_CHICKEN1 _MMIO(0x20e0)
#define GEN9_FFSC_PERCTX_PREEMPT_CTRL (1 << 14)
@ -412,9 +414,6 @@
#define XEHP_CULLBIT1 MCR_REG(0x6100)
#define CHICKEN_RASTER_1 MCR_REG(0x6204)
#define DIS_SF_ROUND_NEAREST_EVEN REG_BIT(8)
#define CHICKEN_RASTER_2 MCR_REG(0x6208)
#define TBIMR_FAST_CLIP REG_BIT(5)
@ -1221,6 +1220,8 @@
#define XEHP_HDC_CHICKEN0 MCR_REG(0xe5f0)
#define LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK REG_GENMASK(13, 11)
#define DIS_ATOMIC_CHAINING_TYPED_WRITES REG_BIT(3)
#define ICL_HDC_MODE MCR_REG(0xe5f4)
#define EU_PERF_CNTL2 PERF_REG(0xe658)
@ -1231,6 +1232,7 @@
#define DISABLE_D8_D16_COASLESCE REG_BIT(30)
#define FORCE_1_SUB_MESSAGE_PER_FRAGMENT REG_BIT(15)
#define LSC_CHICKEN_BIT_0_UDW MCR_REG(0xe7c8 + 4)
#define UGM_FRAGMENT_THRESHOLD_TO_3 REG_BIT(58 - 32)
#define DIS_CHAIN_2XSIMD8 REG_BIT(55 - 32)
#define FORCE_SLM_FENCE_SCOPE_TO_TILE REG_BIT(42 - 32)
#define FORCE_UGM_FENCE_SCOPE_TO_TILE REG_BIT(41 - 32)

View File

@ -845,6 +845,27 @@ lrc_setup_indirect_ctx(u32 *regs,
lrc_ring_indirect_offset_default(engine) << 6;
}
static bool ctx_needs_runalone(const struct intel_context *ce)
{
struct i915_gem_context *gem_ctx;
bool ctx_is_protected = false;
/*
* On MTL and newer platforms, protected contexts require setting
* the LRC run-alone bit or else the encryption will not happen.
*/
if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
(ce->engine->class == COMPUTE_CLASS || ce->engine->class == RENDER_CLASS)) {
rcu_read_lock();
gem_ctx = rcu_dereference(ce->gem_context);
if (gem_ctx)
ctx_is_protected = gem_ctx->uses_protected_content;
rcu_read_unlock();
}
return ctx_is_protected;
}
static void init_common_regs(u32 * const regs,
const struct intel_context *ce,
const struct intel_engine_cs *engine,
@ -860,6 +881,8 @@ static void init_common_regs(u32 * const regs,
if (GRAPHICS_VER(engine->i915) < 11)
ctl |= _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT |
CTX_CTRL_RS_CTX_ENABLE);
if (ctx_needs_runalone(ce))
ctl |= _MASKED_BIT_ENABLE(GEN12_CTX_CTRL_RUNALONE_MODE);
regs[CTX_CONTEXT_CONTROL] = ctl;
regs[CTX_TIMESTAMP] = ce->stats.runtime.last;
@ -1094,6 +1117,9 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine)
I915_BO_ALLOC_PM_VOLATILE);
if (IS_ERR(obj)) {
obj = i915_gem_object_create_shmem(engine->i915, context_size);
if (IS_ERR(obj))
return ERR_CAST(obj);
/*
* Wa_22016122933: For Media version 13.0, all Media GT shared
* memory needs to be mapped as WC on CPU side and UC (PAT
@ -1102,8 +1128,6 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine)
if (intel_gt_needs_wa_22016122933(engine->gt))
i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
}
if (IS_ERR(obj))
return ERR_CAST(obj);
vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
if (IS_ERR(vma)) {
@ -1315,29 +1339,6 @@ gen12_emit_cmd_buf_wa(const struct intel_context *ce, u32 *cs)
return cs;
}
/*
* On DG2 during context restore of a preempted context in GPGPU mode,
* RCS restore hang is detected. This is extremely timing dependent.
* To address this below sw wabb is implemented for DG2 A steppings.
*/
static u32 *
dg2_emit_rcs_hang_wabb(const struct intel_context *ce, u32 *cs)
{
*cs++ = MI_LOAD_REGISTER_IMM(1);
*cs++ = i915_mmio_reg_offset(GEN12_STATE_ACK_DEBUG(ce->engine->mmio_base));
*cs++ = 0x21;
*cs++ = MI_LOAD_REGISTER_REG;
*cs++ = i915_mmio_reg_offset(RING_NOPID(ce->engine->mmio_base));
*cs++ = i915_mmio_reg_offset(XEHP_CULLBIT1);
*cs++ = MI_LOAD_REGISTER_REG;
*cs++ = i915_mmio_reg_offset(RING_NOPID(ce->engine->mmio_base));
*cs++ = i915_mmio_reg_offset(XEHP_CULLBIT2);
return cs;
}
/*
* The bspec's tuning guide asks us to program a vertical watermark value of
* 0x3FF. However this register is not saved/restored properly by the
@ -1355,6 +1356,15 @@ dg2_emit_draw_watermark_setting(u32 *cs)
return cs;
}
static u32 *
gen12_invalidate_state_cache(u32 *cs)
{
*cs++ = MI_LOAD_REGISTER_IMM(1);
*cs++ = i915_mmio_reg_offset(GEN12_CS_DEBUG_MODE2);
*cs++ = _MASKED_BIT_ENABLE(INSTRUCTION_STATE_CACHE_INVALIDATE);
return cs;
}
static u32 *
gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs)
{
@ -1362,21 +1372,19 @@ gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs)
cs = gen12_emit_cmd_buf_wa(ce, cs);
cs = gen12_emit_restore_scratch(ce, cs);
/* Wa_22011450934:dg2 */
if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_A0, STEP_B0) ||
IS_DG2_GRAPHICS_STEP(ce->engine->i915, G11, STEP_A0, STEP_B0))
cs = dg2_emit_rcs_hang_wabb(ce, cs);
/* Wa_16013000631:dg2 */
if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_B0, STEP_C0) ||
IS_DG2_G11(ce->engine->i915))
if (IS_DG2_G11(ce->engine->i915))
cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, 0);
cs = gen12_emit_aux_table_inv(ce->engine, cs);
/* Wa_18022495364 */
if (IS_GFX_GT_IP_RANGE(ce->engine->gt, IP_VER(12, 0), IP_VER(12, 10)))
cs = gen12_invalidate_state_cache(cs);
/* Wa_16014892111 */
if (IS_MTL_GRAPHICS_STEP(ce->engine->i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(ce->engine->i915, P, STEP_A0, STEP_B0) ||
if (IS_GFX_GT_IP_STEP(ce->engine->gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
IS_GFX_GT_IP_STEP(ce->engine->gt, IP_VER(12, 71), STEP_A0, STEP_B0) ||
IS_DG2(ce->engine->i915))
cs = dg2_emit_draw_watermark_setting(cs);
@ -1390,8 +1398,7 @@ gen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs)
cs = gen12_emit_restore_scratch(ce, cs);
/* Wa_16013000631:dg2 */
if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_B0, STEP_C0) ||
IS_DG2_G11(ce->engine->i915))
if (IS_DG2_G11(ce->engine->i915))
if (ce->engine->class == COMPUTE_CLASS)
cs = gen8_emit_pipe_control(cs,
PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE,

View File

@ -404,18 +404,6 @@ static const struct drm_i915_mocs_entry dg2_mocs_table[] = {
MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)),
};
static const struct drm_i915_mocs_entry dg2_mocs_table_g10_ax[] = {
/* Wa_14011441408: Set Go to Memory for MOCS#0 */
MOCS_ENTRY(0, 0, L3_1_UC | L3_GLBGO(1) | L3_LKUP(1)),
/* UC - Coherent; GO:Memory */
MOCS_ENTRY(1, 0, L3_1_UC | L3_GLBGO(1) | L3_LKUP(1)),
/* UC - Non-Coherent; GO:Memory */
MOCS_ENTRY(2, 0, L3_1_UC | L3_GLBGO(1)),
/* WB - LC */
MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)),
};
static const struct drm_i915_mocs_entry pvc_mocs_table[] = {
/* Error */
MOCS_ENTRY(0, 0, L3_3_WB),
@ -507,7 +495,7 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915,
memset(table, 0, sizeof(struct drm_i915_mocs_table));
table->unused_entries_index = I915_MOCS_PTE;
if (IS_METEORLAKE(i915)) {
if (IS_GFX_GT_IP_RANGE(&i915->gt0, IP_VER(12, 70), IP_VER(12, 71))) {
table->size = ARRAY_SIZE(mtl_mocs_table);
table->table = mtl_mocs_table;
table->n_entries = MTL_NUM_MOCS_ENTRIES;
@ -521,13 +509,8 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915,
table->wb_index = 2;
table->unused_entries_index = 2;
} else if (IS_DG2(i915)) {
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
table->size = ARRAY_SIZE(dg2_mocs_table_g10_ax);
table->table = dg2_mocs_table_g10_ax;
} else {
table->size = ARRAY_SIZE(dg2_mocs_table);
table->table = dg2_mocs_table;
}
table->size = ARRAY_SIZE(dg2_mocs_table);
table->table = dg2_mocs_table;
table->uc_index = 1;
table->n_entries = GEN9_NUM_MOCS_ENTRIES;
table->unused_entries_index = 3;

View File

@ -118,14 +118,12 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
GEN6_RC_CTL_EI_MODE(1);
/*
* Wa_16011777198 and BSpec 52698 - Render powergating must be off.
* BSpec 52698 - Render powergating must be off.
* FIXME BSpec is outdated, disabling powergating for MTL is just
* temporary wa and should be removed after fixing real cause
* of forcewake timeouts.
*/
if (IS_METEORLAKE(gt->i915) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0))
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
pg_enable =
GEN9_MEDIA_PG_ENABLE |
GEN11_MEDIA_SAMPLER_PG_ENABLE;
@ -526,8 +524,7 @@ static bool rc6_supported(struct intel_rc6 *rc6)
return false;
}
if (IS_MTL_MEDIA_STEP(gt->i915, STEP_A0, STEP_B0) &&
gt->type == GT_MEDIA) {
if (IS_MEDIA_GT_IP_STEP(gt, IP_VER(13, 0), STEP_A0, STEP_B0)) {
drm_notice(&i915->drm,
"Media RC6 disabled on A step\n");
return false;

View File

@ -161,16 +161,16 @@ static int i915_do_reset(struct intel_gt *gt,
struct pci_dev *pdev = to_pci_dev(gt->i915->drm.dev);
int err;
/* Assert reset for at least 20 usec, and wait for acknowledgement. */
/* Assert reset for at least 50 usec, and wait for acknowledgement. */
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
udelay(50);
err = wait_for_atomic(i915_in_reset(pdev), 50);
err = _wait_for_atomic(i915_in_reset(pdev), 50000, 0);
/* Clear the reset request. */
pci_write_config_byte(pdev, I915_GDRST, 0);
udelay(50);
if (!err)
err = wait_for_atomic(!i915_in_reset(pdev), 50);
err = _wait_for_atomic(!i915_in_reset(pdev), 50000, 0);
return err;
}
@ -190,7 +190,7 @@ static int g33_do_reset(struct intel_gt *gt,
struct pci_dev *pdev = to_pci_dev(gt->i915->drm.dev);
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
return wait_for_atomic(g4x_reset_complete(pdev), 50);
return _wait_for_atomic(g4x_reset_complete(pdev), 50000, 0);
}
static int g4x_do_reset(struct intel_gt *gt,
@ -207,7 +207,7 @@ static int g4x_do_reset(struct intel_gt *gt,
pci_write_config_byte(pdev, I915_GDRST,
GRDOM_MEDIA | GRDOM_RESET_ENABLE);
ret = wait_for_atomic(g4x_reset_complete(pdev), 50);
ret = _wait_for_atomic(g4x_reset_complete(pdev), 50000, 0);
if (ret) {
GT_TRACE(gt, "Wait for media reset failed\n");
goto out;
@ -215,7 +215,7 @@ static int g4x_do_reset(struct intel_gt *gt,
pci_write_config_byte(pdev, I915_GDRST,
GRDOM_RENDER | GRDOM_RESET_ENABLE);
ret = wait_for_atomic(g4x_reset_complete(pdev), 50);
ret = _wait_for_atomic(g4x_reset_complete(pdev), 50000, 0);
if (ret) {
GT_TRACE(gt, "Wait for render reset failed\n");
goto out;
@ -705,7 +705,7 @@ static int __reset_guc(struct intel_gt *gt)
static bool needs_wa_14015076503(struct intel_gt *gt, intel_engine_mask_t engine_mask)
{
if (!IS_METEORLAKE(gt->i915) || !HAS_ENGINE(gt, GSC0))
if (MEDIA_VER_FULL(gt->i915) != IP_VER(13, 0) || !HAS_ENGINE(gt, GSC0))
return false;
if (!__HAS_ENGINE(engine_mask, GSC0))
@ -785,9 +785,7 @@ int __intel_gt_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask)
reset_mask = wa_14015076503_start(gt, engine_mask, !retry);
GT_TRACE(gt, "engine_mask=%x\n", reset_mask);
preempt_disable();
ret = reset(gt, reset_mask, retry);
preempt_enable();
wa_14015076503_end(gt, reset_mask);
}
@ -1632,6 +1630,24 @@ void __intel_fini_wedge(struct intel_wedge_me *w)
w->gt = NULL;
}
/*
* Wa_22011802037 requires that we (or the GuC) ensure that no command
* streamers are executing MI_FORCE_WAKE while an engine reset is initiated.
*/
bool intel_engine_reset_needs_wa_22011802037(struct intel_gt *gt)
{
if (GRAPHICS_VER(gt->i915) < 11)
return false;
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0))
return true;
if (GRAPHICS_VER_FULL(gt->i915) >= IP_VER(12, 70))
return false;
return true;
}
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftest_reset.c"
#include "selftest_hangcheck.c"

View File

@ -78,4 +78,6 @@ void __intel_fini_wedge(struct intel_wedge_me *w);
bool intel_has_gpu_reset(const struct intel_gt *gt);
bool intel_has_reset_engine(const struct intel_gt *gt);
bool intel_engine_reset_needs_wa_22011802037(struct intel_gt *gt);
#endif /* I915_RESET_H */

View File

@ -1161,7 +1161,7 @@ void gen6_rps_get_freq_caps(struct intel_rps *rps, struct intel_rps_freq_caps *c
{
struct drm_i915_private *i915 = rps_to_i915(rps);
if (IS_METEORLAKE(i915))
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))
return mtl_get_freq_caps(rps, caps);
else
return __gen6_rps_get_freq_caps(rps, caps);

View File

@ -764,68 +764,41 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine,
{
dg2_ctx_gt_tuning_init(engine, wal);
/* Wa_16011186671:dg2_g11 */
if (IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) {
wa_mcr_masked_dis(wal, VFLSKPD, DIS_MULT_MISS_RD_SQUASH);
wa_mcr_masked_en(wal, VFLSKPD, DIS_OVER_FETCH_CACHE);
}
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0)) {
/* Wa_14010469329:dg2_g10 */
wa_mcr_masked_en(wal, XEHP_COMMON_SLICE_CHICKEN3,
XEHP_DUAL_SIMD8_SEQ_MERGE_DISABLE);
/*
* Wa_22010465075:dg2_g10
* Wa_22010613112:dg2_g10
* Wa_14010698770:dg2_g10
*/
wa_mcr_masked_en(wal, XEHP_COMMON_SLICE_CHICKEN3,
GEN12_DISABLE_CPS_AWARE_COLOR_PIPE);
}
/* Wa_16013271637:dg2 */
wa_mcr_masked_en(wal, XEHP_SLICE_COMMON_ECO_CHICKEN1,
MSC_MSAA_REODER_BUF_BYPASS_DISABLE);
/* Wa_14014947963:dg2 */
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_B0, STEP_FOREVER) ||
IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915))
wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);
wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);
/* Wa_18018764978:dg2 */
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_C0, STEP_FOREVER) ||
IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915))
wa_mcr_masked_en(wal, XEHP_PSS_MODE2, SCOREBOARD_STALL_FLUSH_CONTROL);
/* Wa_15010599737:dg2 */
wa_mcr_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
wa_mcr_masked_en(wal, XEHP_PSS_MODE2, SCOREBOARD_STALL_FLUSH_CONTROL);
/* Wa_18019271663:dg2 */
wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);
}
static void mtl_ctx_gt_tuning_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
static void xelpg_ctx_gt_tuning_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
{
struct drm_i915_private *i915 = engine->i915;
struct intel_gt *gt = engine->gt;
dg2_ctx_gt_tuning_init(engine, wal);
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER))
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))
wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);
}
static void mtl_ctx_workarounds_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
static void xelpg_ctx_workarounds_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
{
struct drm_i915_private *i915 = engine->i915;
struct intel_gt *gt = engine->gt;
mtl_ctx_gt_tuning_init(engine, wal);
xelpg_ctx_gt_tuning_init(engine, wal);
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0)) {
if (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_A0, STEP_B0)) {
/* Wa_14014947963 */
wa_masked_field_set(wal, VF_PREEMPTION,
PREEMPTION_VERTEX_COUNT, 0x4000);
@ -931,8 +904,8 @@ __intel_engine_init_ctx_wa(struct intel_engine_cs *engine,
if (engine->class != RENDER_CLASS)
goto done;
if (IS_METEORLAKE(i915))
mtl_ctx_workarounds_init(engine, wal);
if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
xelpg_ctx_workarounds_init(engine, wal);
else if (IS_PONTEVECCHIO(i915))
; /* noop; none at this time */
else if (IS_DG2(i915))
@ -1606,31 +1579,11 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
static void
dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
{
struct intel_engine_cs *engine;
int id;
xehp_init_mcr(gt, wal);
/* Wa_14011060649:dg2 */
wa_14011060649(gt, wal);
/*
* Although there are per-engine instances of these registers,
* they technically exist outside the engine itself and are not
* impacted by engine resets. Furthermore, they're part of the
* GuC blacklist so trying to treat them as engine workarounds
* will result in GuC initialization failure and a wedged GPU.
*/
for_each_engine(engine, gt, id) {
if (engine->class != VIDEO_DECODE_CLASS)
continue;
/* Wa_16010515920:dg2_g10 */
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0))
wa_write_or(wal, VDBOX_CGCTL3F18(engine->mmio_base),
ALNUNIT_CLKGATE_DIS);
}
if (IS_DG2_G10(gt->i915)) {
/* Wa_22010523718:dg2 */
wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
@ -1641,70 +1594,15 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
DSS_ROUTER_CLKGATE_DIS);
}
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0)) {
/* Wa_14012362059:dg2 */
wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
}
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0)) {
/* Wa_14010948348:dg2_g10 */
wa_write_or(wal, UNSLCGCTL9430, MSQDUNIT_CLKGATE_DIS);
/* Wa_14011037102:dg2_g10 */
wa_write_or(wal, UNSLCGCTL9444, LTCDD_CLKGATE_DIS);
/* Wa_14011371254:dg2_g10 */
wa_mcr_write_or(wal, XEHP_SLICE_UNIT_LEVEL_CLKGATE, NODEDSS_CLKGATE_DIS);
/* Wa_14011431319:dg2_g10 */
wa_write_or(wal, UNSLCGCTL9440, GAMTLBOACS_CLKGATE_DIS |
GAMTLBVDBOX7_CLKGATE_DIS |
GAMTLBVDBOX6_CLKGATE_DIS |
GAMTLBVDBOX5_CLKGATE_DIS |
GAMTLBVDBOX4_CLKGATE_DIS |
GAMTLBVDBOX3_CLKGATE_DIS |
GAMTLBVDBOX2_CLKGATE_DIS |
GAMTLBVDBOX1_CLKGATE_DIS |
GAMTLBVDBOX0_CLKGATE_DIS |
GAMTLBKCR_CLKGATE_DIS |
GAMTLBGUC_CLKGATE_DIS |
GAMTLBBLT_CLKGATE_DIS);
wa_write_or(wal, UNSLCGCTL9444, GAMTLBGFXA0_CLKGATE_DIS |
GAMTLBGFXA1_CLKGATE_DIS |
GAMTLBCOMPA0_CLKGATE_DIS |
GAMTLBCOMPA1_CLKGATE_DIS |
GAMTLBCOMPB0_CLKGATE_DIS |
GAMTLBCOMPB1_CLKGATE_DIS |
GAMTLBCOMPC0_CLKGATE_DIS |
GAMTLBCOMPC1_CLKGATE_DIS |
GAMTLBCOMPD0_CLKGATE_DIS |
GAMTLBCOMPD1_CLKGATE_DIS |
GAMTLBMERT_CLKGATE_DIS |
GAMTLBVEBOX3_CLKGATE_DIS |
GAMTLBVEBOX2_CLKGATE_DIS |
GAMTLBVEBOX1_CLKGATE_DIS |
GAMTLBVEBOX0_CLKGATE_DIS);
/* Wa_14010569222:dg2_g10 */
wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
GAMEDIA_CLKGATE_DIS);
/* Wa_14011028019:dg2_g10 */
wa_mcr_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS);
/* Wa_14010680813:dg2_g10 */
wa_mcr_write_or(wal, XEHP_GAMSTLB_CTRL,
CONTROL_BLOCK_CLKGATE_DIS |
EGRESS_BLOCK_CLKGATE_DIS |
TAG_BLOCK_CLKGATE_DIS);
}
/* Wa_14014830051:dg2 */
wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);
/* Wa_14015795083 */
wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
/*
* Wa_14015795083
* Skip verification for possibly locked register.
*/
wa_add(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE,
0, 0, false);
/* Wa_18018781329 */
wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
@ -1747,8 +1645,8 @@ xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
/* Wa_22016670082 */
wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);
if (IS_MTL_GRAPHICS_STEP(gt->i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0)) {
if (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_A0, STEP_B0)) {
/* Wa_14014830051 */
wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);
@ -1791,10 +1689,8 @@ xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
*/
static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)
{
if (IS_METEORLAKE(gt->i915)) {
if (gt->type != GT_MEDIA)
wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);
}
@ -1818,15 +1714,15 @@ gt_init_workarounds(struct intel_gt *gt, struct i915_wa_list *wal)
gt_tuning_settings(gt, wal);
if (gt->type == GT_MEDIA) {
if (MEDIA_VER(i915) >= 13)
if (MEDIA_VER_FULL(i915) == IP_VER(13, 0))
xelpmp_gt_workarounds_init(gt, wal);
else
MISSING_CASE(MEDIA_VER(i915));
MISSING_CASE(MEDIA_VER_FULL(i915));
return;
}
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
xelpg_gt_workarounds_init(gt, wal);
else if (IS_PONTEVECCHIO(i915))
pvc_gt_workarounds_init(gt, wal);
@ -2242,29 +2138,10 @@ static void dg2_whitelist_build(struct intel_engine_cs *engine)
switch (engine->class) {
case RENDER_CLASS:
/*
* Wa_1507100340:dg2_g10
*
* This covers 4 registers which are next to one another :
* - PS_INVOCATION_COUNT
* - PS_INVOCATION_COUNT_UDW
* - PS_DEPTH_COUNT
* - PS_DEPTH_COUNT_UDW
*/
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0))
whitelist_reg_ext(w, PS_INVOCATION_COUNT,
RING_FORCE_TO_NONPRIV_ACCESS_RD |
RING_FORCE_TO_NONPRIV_RANGE_4);
/* Required by recommended tuning setting (not a workaround) */
whitelist_mcr_reg(w, XEHP_COMMON_SLICE_CHICKEN3);
break;
case COMPUTE_CLASS:
/* Wa_16011157294:dg2_g10 */
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0))
whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
break;
default:
break;
}
@ -2294,7 +2171,7 @@ static void pvc_whitelist_build(struct intel_engine_cs *engine)
blacklist_trtt(engine);
}
static void mtl_whitelist_build(struct intel_engine_cs *engine)
static void xelpg_whitelist_build(struct intel_engine_cs *engine)
{
struct i915_wa_list *w = &engine->whitelist;
@ -2316,8 +2193,10 @@ void intel_engine_init_whitelist(struct intel_engine_cs *engine)
wa_init_start(w, engine->gt, "whitelist", engine->name);
if (IS_METEORLAKE(i915))
mtl_whitelist_build(engine);
if (engine->gt->type == GT_MEDIA)
; /* none yet */
else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
xelpg_whitelist_build(engine);
else if (IS_PONTEVECCHIO(i915))
pvc_whitelist_build(engine);
else if (IS_DG2(i915))
@ -2415,62 +2294,35 @@ engine_fake_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
}
}
static bool needs_wa_1308578152(struct intel_engine_cs *engine)
{
return intel_sseu_find_first_xehp_dss(&engine->gt->info.sseu, 0, 0) >=
GEN_DSS_PER_GSLICE;
}
static void
rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
{
struct drm_i915_private *i915 = engine->i915;
struct intel_gt *gt = engine->gt;
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0)) {
if (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_A0, STEP_B0)) {
/* Wa_22014600077 */
wa_mcr_masked_en(wal, GEN10_CACHE_MODE_SS,
ENABLE_EU_COUNT_FOR_TDL_FLUSH);
}
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0) ||
IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
IS_DG2_G11(i915) || IS_DG2_G12(i915)) {
if (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_A0, STEP_B0) ||
IS_DG2(i915)) {
/* Wa_1509727124 */
wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,
SC_DISABLE_POWER_OPTIMIZATION_EBB);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
IS_DG2_G11(i915) || IS_DG2_G12(i915) ||
IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0)) {
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
IS_DG2(i915)) {
/* Wa_22012856258 */
wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2,
GEN12_DISABLE_READ_SUPPRESSION);
}
if (IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) {
/* Wa_14013392000:dg2_g11 */
wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2, GEN12_ENABLE_LARGE_GRF_MODE);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0) ||
IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) {
/* Wa_14012419201:dg2 */
wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4,
GEN12_DISABLE_HDR_PAST_PAYLOAD_HOLD_FIX);
}
/* Wa_1308578152:dg2_g10 when first gslice is fused off */
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) &&
needs_wa_1308578152(engine)) {
wa_masked_dis(wal, GEN12_CS_DEBUG_MODE1_CCCSUNIT_BE_COMMON,
GEN12_REPLAY_MODE_GRANULARITY);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
IS_DG2_G11(i915) || IS_DG2_G12(i915)) {
if (IS_DG2(i915)) {
/*
* Wa_22010960976:dg2
* Wa_14013347512:dg2
@ -2479,34 +2331,15 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
/*
* Wa_1608949956:dg2_g10
* Wa_14010198302:dg2_g10
*/
wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN,
MDQ_ARBITRATION_MODE | UGM_BACKUP_MODE);
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) ||
IS_DG2(i915)) {
/* Wa_14015150844 */
wa_mcr_add(wal, XEHP_HDC_CHICKEN0, 0,
_MASKED_BIT_ENABLE(DIS_ATOMIC_CHAINING_TYPED_WRITES),
0, true);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0))
/* Wa_22010430635:dg2 */
wa_mcr_masked_en(wal,
GEN9_ROW_CHICKEN4,
GEN12_DISABLE_GRF_CLEAR);
/* Wa_14013202645:dg2 */
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0))
wa_mcr_write_or(wal, RT_CTRL, DIS_NULL_QUERY);
/* Wa_22012532006:dg2 */
if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0))
wa_mcr_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,
DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA);
if (IS_DG2_GRAPHICS_STEP(i915, G11, STEP_B0, STEP_FOREVER) ||
IS_DG2_G10(i915)) {
if (IS_DG2_G11(i915) || IS_DG2_G10(i915)) {
/* Wa_22014600077:dg2 */
wa_mcr_add(wal, GEN10_CACHE_MODE_SS, 0,
_MASKED_BIT_ENABLE(ENABLE_EU_COUNT_FOR_TDL_FLUSH),
@ -2514,6 +2347,19 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
true);
}
if (IS_DG2(i915) || IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) ||
IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
/*
* Wa_1606700617:tgl,dg1,adl-p
* Wa_22010271021:tgl,rkl,dg1,adl-s,adl-p
* Wa_14010826681:tgl,dg1,rkl,adl-p
* Wa_18019627453:dg2
*/
wa_masked_en(wal,
GEN9_CS_DEBUG_MODE1,
FF_DOP_CLOCK_GATE_DISABLE);
}
if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) || IS_DG1(i915) ||
IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
/* Wa_1606931601:tgl,rkl,dg1,adl-s,adl-p */
@ -2527,19 +2373,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
*/
wa_write_or(wal, GEN7_FF_THREAD_MODE,
GEN12_FF_TESSELATION_DOP_GATE_DISABLE);
}
if (IS_ALDERLAKE_P(i915) || IS_DG2(i915) || IS_ALDERLAKE_S(i915) ||
IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
/*
* Wa_1606700617:tgl,dg1,adl-p
* Wa_22010271021:tgl,rkl,dg1,adl-s,adl-p
* Wa_14010826681:tgl,dg1,rkl,adl-p
* Wa_18019627453:dg2
*/
wa_masked_en(wal,
GEN9_CS_DEBUG_MODE1,
FF_DOP_CLOCK_GATE_DISABLE);
/* Wa_1406941453:tgl,rkl,dg1,adl-s,adl-p */
wa_mcr_masked_en(wal,
GEN10_SAMPLER_MODE,
ENABLE_SMALLPL);
}
if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) ||
@ -2566,14 +2404,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
GEN8_RC_SEMA_IDLE_MSG_DISABLE);
}
if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) ||
IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) {
/* Wa_1406941453:tgl,rkl,dg1,adl-s,adl-p */
wa_mcr_masked_en(wal,
GEN10_SAMPLER_MODE,
ENABLE_SMALLPL);
}
if (GRAPHICS_VER(i915) == 11) {
/* This is not an Wa. Enable for better image quality */
wa_masked_en(wal,
@ -2975,10 +2805,12 @@ ccs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
* function invoked by __intel_engine_init_ctx_wa().
*/
static void
add_render_compute_tuning_settings(struct drm_i915_private *i915,
add_render_compute_tuning_settings(struct intel_gt *gt,
struct i915_wa_list *wal)
{
if (IS_METEORLAKE(i915) || IS_DG2(i915))
struct drm_i915_private *i915 = gt->i915;
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))
wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);
/*
@ -3007,8 +2839,9 @@ static void
general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
{
struct drm_i915_private *i915 = engine->i915;
struct intel_gt *gt = engine->gt;
add_render_compute_tuning_settings(i915, wal);
add_render_compute_tuning_settings(gt, wal);
if (GRAPHICS_VER(i915) >= 11) {
/* This is not a Wa (although referred to as
@ -3029,13 +2862,13 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE);
}
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER))
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))
/* Wa_14017856879 */
wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
if (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_A0, STEP_B0))
/*
* Wa_14017066071
* Wa_14017654203
@ -3043,37 +2876,47 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,
MTL_DISABLE_SAMPLER_SC_OOO);
if (IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0))
/* Wa_22015279794 */
wa_mcr_masked_en(wal, GEN10_CACHE_MODE_SS,
DISABLE_PREFETCH_INTO_IC);
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0) ||
IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
IS_DG2_G11(i915) || IS_DG2_G12(i915)) {
if (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_A0, STEP_B0) ||
IS_DG2(i915)) {
/* Wa_22013037850 */
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW,
DISABLE_128B_EVICTION_COMMAND_UDW);
/* Wa_18017747507 */
wa_masked_en(wal, VFG_PREEMPTION_CHICKEN, POLYGON_TRIFAN_LINELOOP_DISABLE);
}
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0) ||
if (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_A0, STEP_B0) ||
IS_PONTEVECCHIO(i915) ||
IS_DG2(i915)) {
/* Wa_22014226127 */
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0, DISABLE_D8_D16_COASLESCE);
}
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0) ||
IS_DG2(i915)) {
/* Wa_18017747507 */
wa_masked_en(wal, VFG_PREEMPTION_CHICKEN, POLYGON_TRIFAN_LINELOOP_DISABLE);
if (IS_PONTEVECCHIO(i915) || IS_DG2(i915)) {
/* Wa_14015227452:dg2,pvc */
wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE);
/* Wa_16015675438:dg2,pvc */
wa_masked_en(wal, FF_SLICE_CS_CHICKEN2, GEN12_PERF_FIX_BALANCING_CFE_DISABLE);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) ||
IS_DG2_G11(i915)) {
if (IS_DG2(i915)) {
/*
* Wa_16011620976:dg2_g11
* Wa_22015475538:dg2
*/
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW, DIS_CHAIN_2XSIMD8);
}
if (IS_DG2_G11(i915)) {
/*
* Wa_22012826095:dg2
* Wa_22013059131:dg2
@ -3085,18 +2928,23 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
/* Wa_22013059131:dg2 */
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0,
FORCE_1_SUB_MESSAGE_PER_FRAGMENT);
/*
* Wa_22012654132
*
* Note that register 0xE420 is write-only and cannot be read
* back for verification on DG2 (due to Wa_14012342262), so
* we need to explicitly skip the readback.
*/
wa_mcr_add(wal, GEN10_CACHE_MODE_SS, 0,
_MASKED_BIT_ENABLE(ENABLE_PREFETCH_INTO_IC),
0 /* write-only, so skip validation */,
true);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
/*
* Wa_14010918519:dg2_g10
*
* LSC_CHICKEN_BIT_0 always reads back as 0 is this stepping,
* so ignoring verification.
*/
wa_mcr_add(wal, LSC_CHICKEN_BIT_0_UDW, 0,
FORCE_SLM_FENCE_SCOPE_TO_TILE | FORCE_UGM_FENCE_SCOPE_TO_TILE,
0, false);
if (IS_DG2_G10(i915) || IS_DG2_G12(i915)) {
/* Wa_18028616096 */
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW, UGM_FRAGMENT_THRESHOLD_TO_3);
}
if (IS_XEHPSDV(i915)) {
@ -3114,35 +2962,6 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
wa_mcr_masked_en(wal, GEN8_HALF_SLICE_CHICKEN1,
GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
}
if (IS_DG2(i915) || IS_PONTEVECCHIO(i915)) {
/* Wa_14015227452:dg2,pvc */
wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE);
/* Wa_16015675438:dg2,pvc */
wa_masked_en(wal, FF_SLICE_CS_CHICKEN2, GEN12_PERF_FIX_BALANCING_CFE_DISABLE);
}
if (IS_DG2(i915)) {
/*
* Wa_16011620976:dg2_g11
* Wa_22015475538:dg2
*/
wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW, DIS_CHAIN_2XSIMD8);
}
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_C0) || IS_DG2_G11(i915))
/*
* Wa_22012654132
*
* Note that register 0xE420 is write-only and cannot be read
* back for verification on DG2 (due to Wa_14012342262), so
* we need to explicitly skip the readback.
*/
wa_mcr_add(wal, GEN10_CACHE_MODE_SS, 0,
_MASKED_BIT_ENABLE(ENABLE_PREFETCH_INTO_IC),
0 /* write-only, so skip validation */,
true);
}
static void

View File

@ -710,7 +710,7 @@ static int threaded_migrate(struct intel_migrate *migrate,
thread[i].tsk = tsk;
}
msleep(10); /* start all threads before we kthread_stop() */
msleep(10 * n_cpus); /* start all threads before we kthread_stop() */
for (i = 0; i < n_cpus; ++i) {
struct task_struct *tsk = thread[i].tsk;

View File

@ -81,8 +81,17 @@ out_rq:
i915_request_add(rq);
if (!err && i915_request_wait(rq, 0, msecs_to_jiffies(500)) < 0)
err = -ETIME;
if (!err) {
/*
* Start timeout for i915_request_wait only after considering one possible
* pending GSC-HECI submission cycle on the other (non-privileged) path.
*/
if (wait_for(i915_request_started(rq), GSC_HECI_REPLY_LATENCY_MS))
drm_dbg(&gsc_uc_to_gt(gsc)->i915->drm,
"Delay in gsc-heci-priv submission to gsccs-hw");
if (i915_request_wait(rq, 0, msecs_to_jiffies(GSC_HECI_REPLY_LATENCY_MS)) < 0)
err = -ETIME;
}
i915_request_put(rq);
@ -186,6 +195,13 @@ out_rq:
i915_request_add(rq);
if (!err) {
/*
* Start timeout for i915_request_wait only after considering one possible
* pending GSC-HECI submission cycle on the other (privileged) path.
*/
if (wait_for(i915_request_started(rq), GSC_HECI_REPLY_LATENCY_MS))
drm_dbg(&gsc_uc_to_gt(gsc)->i915->drm,
"Delay in gsc-heci-non-priv submission to gsccs-hw");
if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
msecs_to_jiffies(timeout_ms)) < 0)
err = -ETIME;

View File

@ -12,6 +12,12 @@ struct i915_vma;
struct intel_context;
struct intel_gsc_uc;
#define GSC_HECI_REPLY_LATENCY_MS 500
/*
* Max FW response time is 500ms, but this should be counted from the time the
* command has hit the GSC-CS hardware, not the preceding handoff to GuC CTB.
*/
struct intel_gsc_mtl_header {
u32 validity_marker;
#define GSC_HECI_VALIDITY_MARKER 0xA578875A

View File

@ -159,6 +159,21 @@ static void gen11_disable_guc_interrupts(struct intel_guc *guc)
gen11_reset_guc_interrupts(guc);
}
static void guc_dead_worker_func(struct work_struct *w)
{
struct intel_guc *guc = container_of(w, struct intel_guc, dead_guc_worker);
struct intel_gt *gt = guc_to_gt(guc);
unsigned long last = guc->last_dead_guc_jiffies;
unsigned long delta = jiffies_to_msecs(jiffies - last);
if (delta < 500) {
intel_gt_set_wedged(gt);
} else {
intel_gt_handle_error(gt, ALL_ENGINES, I915_ERROR_CAPTURE, "dead GuC");
guc->last_dead_guc_jiffies = jiffies;
}
}
void intel_guc_init_early(struct intel_guc *guc)
{
struct intel_gt *gt = guc_to_gt(guc);
@ -171,6 +186,8 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_slpc_init_early(&guc->slpc);
intel_guc_rc_init_early(guc);
INIT_WORK(&guc->dead_guc_worker, guc_dead_worker_func);
mutex_init(&guc->send_mutex);
spin_lock_init(&guc->irq_lock);
if (GRAPHICS_VER(i915) >= 11) {
@ -272,18 +289,14 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
flags |= GUC_WA_POLLCS;
/* Wa_16011759253:dg2_g10:a0 */
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0))
flags |= GUC_WA_GAM_CREDITS;
/* Wa_14014475959 */
if (IS_MTL_GRAPHICS_STEP(gt->i915, M, STEP_A0, STEP_B0) ||
if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
/*
* Wa_14012197797:dg2_g10:a0,dg2_g11:a0
* Wa_22011391025:dg2_g10,dg2_g11,dg2_g12
* Wa_14012197797
* Wa_22011391025
*
* The same WA bit is used for both and 22011391025 is applicable to
* all DG2.
@ -292,22 +305,14 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_DUAL_QUEUE;
/* Wa_22011802037: graphics version 11/12 */
if (IS_MTL_GRAPHICS_STEP(gt->i915, M, STEP_A0, STEP_B0) ||
(GRAPHICS_VER(gt->i915) >= 11 &&
GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 70)))
if (intel_engine_reset_needs_wa_22011802037(gt))
flags |= GUC_WA_PRE_PARSER;
/* Wa_16011777198:dg2 */
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0))
flags |= GUC_WA_RCS_RESET_BEFORE_RC6;
/*
* Wa_22012727170:dg2_g10[a0-c0), dg2_g11[a0..)
* Wa_22012727685:dg2_g11[a0..)
* Wa_22012727170
* Wa_22012727685
*/
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_FOREVER))
if (IS_DG2_G11(gt->i915))
flags |= GUC_WA_CONTEXT_ISOLATION;
/* Wa_16015675438 */
@ -461,6 +466,8 @@ void intel_guc_fini(struct intel_guc *guc)
if (!intel_uc_fw_is_loadable(&guc->fw))
return;
flush_work(&guc->dead_guc_worker);
if (intel_guc_slpc_is_used(guc))
intel_guc_slpc_fini(&guc->slpc);
@ -585,6 +592,20 @@ out:
return ret;
}
int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action)
{
if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED)
guc_err(guc, "Crash dump notification\n");
else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION)
guc_err(guc, "Exception notification\n");
else
guc_err(guc, "Unknown crash notification: 0x%04X\n", action);
queue_work(system_unbound_wq, &guc->dead_guc_worker);
return 0;
}
int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
const u32 *payload, u32 len)
{
@ -601,6 +622,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
guc_err(guc, "Received early exception notification!\n");
if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | INTEL_GUC_RECV_MSG_EXCEPTION))
queue_work(system_unbound_wq, &guc->dead_guc_worker);
return 0;
}
@ -640,6 +664,8 @@ int intel_guc_suspend(struct intel_guc *guc)
return 0;
if (intel_guc_submission_is_used(guc)) {
flush_work(&guc->dead_guc_worker);
/*
* This H2G MMIO command tears down the GuC in two steps. First it will
* generate a G2H CTB for every active context indicating a reset. In

View File

@ -266,6 +266,20 @@ struct intel_guc {
unsigned long last_stat_jiffies;
} timestamp;
/**
* @dead_guc_worker: Asynchronous worker thread for forcing a GuC reset.
* Specifically used when the G2H handler wants to issue a reset. Resets
* require flushing the G2H queue. So, the G2H processing itself must not
* trigger a reset directly. Instead, go via this worker.
*/
struct work_struct dead_guc_worker;
/**
* @last_dead_guc_jiffies: timestamp of previous 'dead guc' occurrance
* used to prevent a fundamentally broken system from continuously
* reloading the GuC.
*/
unsigned long last_dead_guc_jiffies;
#ifdef CONFIG_DRM_I915_SELFTEST
/**
* @number_guc_id_stolen: The number of guc_ids that have been stolen
@ -476,6 +490,7 @@ int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
const u32 *msg, u32 len);
int intel_guc_error_capture_process_msg(struct intel_guc *guc,
const u32 *msg, u32 len);
int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action);
struct intel_engine_cs *
intel_guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance);

View File

@ -1112,12 +1112,8 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
ret = 0;
break;
case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
CT_ERROR(ct, "Received GuC crash dump notification!\n");
ret = 0;
break;
case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
CT_ERROR(ct, "Received GuC exception notification!\n");
ret = 0;
ret = intel_guc_crash_process_msg(guc, action);
break;
default:
ret = -EOPNOTSUPP;

View File

@ -138,17 +138,6 @@ static int guc_action_slpc_set_param(struct intel_guc *guc, u8 id, u32 value)
return ret > 0 ? -EPROTO : ret;
}
static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id)
{
u32 request[] = {
GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1),
id,
};
return intel_guc_send(guc, request, ARRAY_SIZE(request));
}
static bool slpc_is_running(struct intel_guc_slpc *slpc)
{
return slpc_get_state(slpc) == SLPC_GLOBAL_STATE_RUNNING;
@ -199,15 +188,6 @@ static int slpc_set_param(struct intel_guc_slpc *slpc, u8 id, u32 value)
return ret;
}
static int slpc_unset_param(struct intel_guc_slpc *slpc, u8 id)
{
struct intel_guc *guc = slpc_to_guc(slpc);
GEM_BUG_ON(id >= SLPC_MAX_PARAM);
return guc_action_slpc_unset_param(guc, id);
}
static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq)
{
struct intel_guc *guc = slpc_to_guc(slpc);
@ -672,49 +652,6 @@ static void slpc_get_rp_values(struct intel_guc_slpc *slpc)
slpc->boost_freq = slpc->rp0_freq;
}
/**
* intel_guc_slpc_override_gucrc_mode() - override GUCRC mode
* @slpc: pointer to intel_guc_slpc.
* @mode: new value of the mode.
*
* This function will override the GUCRC mode.
*
* Return: 0 on success, non-zero error code on failure.
*/
int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode)
{
int ret;
struct drm_i915_private *i915 = slpc_to_i915(slpc);
intel_wakeref_t wakeref;
if (mode >= SLPC_GUCRC_MODE_MAX)
return -EINVAL;
with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
ret = slpc_set_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE, mode);
if (ret)
guc_err(slpc_to_guc(slpc), "Override RC mode %d failed: %pe\n",
mode, ERR_PTR(ret));
}
return ret;
}
int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc)
{
struct drm_i915_private *i915 = slpc_to_i915(slpc);
intel_wakeref_t wakeref;
int ret = 0;
with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
ret = slpc_unset_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE);
if (ret)
guc_err(slpc_to_guc(slpc), "Unsetting RC mode failed: %pe\n", ERR_PTR(ret));
}
return ret;
}
/*
* intel_guc_slpc_enable() - Start SLPC
* @slpc: pointer to intel_guc_slpc.

View File

@ -44,8 +44,6 @@ int intel_guc_slpc_set_media_ratio_mode(struct intel_guc_slpc *slpc, u32 val);
void intel_guc_pm_intrmsk_enable(struct intel_gt *gt);
void intel_guc_slpc_boost(struct intel_guc_slpc *slpc);
void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc);
int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc);
int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode);
int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val);
#endif

View File

@ -1432,6 +1432,36 @@ static void guc_timestamp_ping(struct work_struct *wrk)
unsigned long index;
int srcu, ret;
/*
* Ideally the busyness worker should take a gt pm wakeref because the
* worker only needs to be active while gt is awake. However, the
* gt_park path cancels the worker synchronously and this complicates
* the flow if the worker is also running at the same time. The cancel
* waits for the worker and when the worker releases the wakeref, that
* would call gt_park and would lead to a deadlock.
*
* The resolution is to take the global pm wakeref if runtime pm is
* already active. If not, we don't need to update the busyness stats as
* the stats would already be updated when the gt was parked.
*
* Note:
* - We do not requeue the worker if we cannot take a reference to runtime
* pm since intel_guc_busyness_unpark would requeue the worker in the
* resume path.
*
* - If the gt was parked longer than time taken for GT timestamp to roll
* over, we ignore those rollovers since we don't care about tracking
* the exact GT time. We only care about roll overs when the gt is
* active and running workloads.
*
* - There is a window of time between gt_park and runtime suspend,
* where the worker may run. This is acceptable since the worker will
* not find any new data to update busyness.
*/
wakeref = intel_runtime_pm_get_if_active(&gt->i915->runtime_pm);
if (!wakeref)
return;
/*
* Synchronize with gt reset to make sure the worker does not
* corrupt the engine/guc stats. NB: can't actually block waiting
@ -1440,10 +1470,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
*/
ret = intel_gt_reset_trylock(gt, &srcu);
if (ret)
return;
goto err_trylock;
with_intel_runtime_pm(&gt->i915->runtime_pm, wakeref)
__update_guc_busyness_stats(guc);
__update_guc_busyness_stats(guc);
/* adjust context stats for overflow */
xa_for_each(&guc->context_lookup, index, ce)
@ -1452,6 +1481,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
intel_gt_reset_unlock(gt, srcu);
guc_enable_busyness_worker(guc);
err_trylock:
intel_runtime_pm_put(&gt->i915->runtime_pm, wakeref);
}
static int guc_action_enable_usage_stats(struct intel_guc *guc)
@ -1658,9 +1690,7 @@ static void guc_engine_reset_prepare(struct intel_engine_cs *engine)
* Wa_22011802037: In addition to stopping the cs, we need
* to wait for any pending mi force wakeups
*/
if (IS_MTL_GRAPHICS_STEP(engine->i915, M, STEP_A0, STEP_B0) ||
(GRAPHICS_VER(engine->i915) >= 11 &&
GRAPHICS_VER_FULL(engine->i915) < IP_VER(12, 70))) {
if (intel_engine_reset_needs_wa_22011802037(engine->gt)) {
intel_engine_stop_cs(engine);
intel_engine_wait_for_pending_mi_fw(engine);
}
@ -4267,7 +4297,7 @@ static void guc_default_vfuncs(struct intel_engine_cs *engine)
/* Wa_14014475959:dg2 */
if (engine->class == COMPUTE_CLASS)
if (IS_MTL_GRAPHICS_STEP(engine->i915, M, STEP_A0, STEP_B0) ||
if (IS_GFX_GT_IP_STEP(engine->gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
IS_DG2(engine->i915))
engine->flags |= I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;

View File

@ -131,6 +131,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON, 0, huc_mmp(bxt, 2, 0, 0)) \
fw_def(SKYLAKE, 0, huc_mmp(skl, 2, 0, 0))
/*
* The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
* we care about is the interface, we use the compatibility version in the
* binary names.
* Same as with the GuC, a major version bump indicate a
* backward-incompatible change, while a minor version bump indicates a
* backward-compatible one, so we use only the former in the file name.
*/
#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
fw_def(METEORLAKE, 0, gsc_def(mtl, 1, 0))
/*
* Set of macros for producing a list of filenames from the above table.
*/
@ -166,6 +177,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
#define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
/*
* All blobs need to be declared via MODULE_FIRMWARE().
* This first expansion of the table macros is solely to provide
@ -176,6 +190,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, MAKE_GUC_FW_PATH_MMP)
INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
/*
* The next expansion of the table macros (in __uc_fw_auto_select below) provides
@ -225,6 +240,10 @@ struct __packed uc_fw_blob {
#define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
#define GSC_FW_BLOB(prefix_, major_, minor_) \
UC_FW_BLOB_NEW(major_, minor_, 0, true, \
MAKE_GSC_FW_PATH(prefix_, major_, minor_))
struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@ -251,9 +270,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] = {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
};
static const struct uc_fw_platform_requirement blobs_gsc[] = {
INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
};
static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
[INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
};
static void
@ -266,14 +290,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
int i;
bool found;
/*
* GSC FW support is still not fully in place, so we're not defining
* the FW blob yet because we don't want the driver to attempt to load
* it until we're ready for it.
*/
if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
return;
/*
* The only difference between the ADL GuC FWs is the HWConfig support.
* ADL-N does not support HWConfig, so we should use the same binary as

View File

@ -144,7 +144,7 @@ static const char *i915_cache_level_str(struct drm_i915_gem_object *obj)
{
struct drm_i915_private *i915 = obj_to_i915(obj);
if (IS_METEORLAKE(i915)) {
if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 71))) {
switch (obj->pat_index) {
case 0: return " WB";
case 1: return " WT";
@ -740,15 +740,19 @@ static int
i915_drop_caches_set(void *data, u64 val)
{
struct drm_i915_private *i915 = data;
struct intel_gt *gt;
unsigned int flags;
unsigned int i;
int ret;
drm_dbg(&i915->drm, "Dropping caches: 0x%08llx [0x%08llx]\n",
val, val & DROP_ALL);
ret = gt_drop_caches(to_gt(i915), val);
if (ret)
return ret;
for_each_gt(gt, i915, i) {
ret = gt_drop_caches(gt, val);
if (ret)
return ret;
}
fs_reclaim_acquire(GFP_KERNEL);
flags = memalloc_noreclaim_save();

View File

@ -573,10 +573,6 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_PONTEVECCHIO(i915) IS_PLATFORM(i915, INTEL_PONTEVECCHIO)
#define IS_METEORLAKE(i915) IS_PLATFORM(i915, INTEL_METEORLAKE)
#define IS_METEORLAKE_M(i915) \
IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_M)
#define IS_METEORLAKE_P(i915) \
IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_P)
#define IS_DG2_G10(i915) \
IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10)
#define IS_DG2_G11(i915) \
@ -658,37 +654,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_XEHPSDV_GRAPHICS_STEP(__i915, since, until) \
(IS_XEHPSDV(__i915) && IS_GRAPHICS_STEP(__i915, since, until))
#define IS_MTL_GRAPHICS_STEP(__i915, variant, since, until) \
(IS_SUBPLATFORM(__i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_##variant) && \
IS_GRAPHICS_STEP(__i915, since, until))
#define IS_MTL_DISPLAY_STEP(__i915, since, until) \
(IS_METEORLAKE(__i915) && \
IS_DISPLAY_STEP(__i915, since, until))
#define IS_MTL_MEDIA_STEP(__i915, since, until) \
(IS_METEORLAKE(__i915) && \
IS_MEDIA_STEP(__i915, since, until))
/*
* DG2 hardware steppings are a bit unusual. The hardware design was forked to
* create three variants (G10, G11, and G12) which each have distinct
* workaround sets. The G11 and G12 forks of the DG2 design reset the GT
* stepping back to "A0" for their first iterations, even though they're more
* similar to a G10 B0 stepping and G10 C0 stepping respectively in terms of
* functionality and workarounds. However the display stepping does not reset
* in the same manner --- a specific stepping like "B0" has a consistent
* meaning regardless of whether it belongs to a G10, G11, or G12 DG2.
*
* TLDR: All GT workarounds and stepping-specific logic must be applied in
* relation to a specific subplatform (G10/G11/G12), whereas display workarounds
* and stepping-specific logic will be applied with a general DG2-wide stepping
* number.
*/
#define IS_DG2_GRAPHICS_STEP(__i915, variant, since, until) \
(IS_SUBPLATFORM(__i915, INTEL_DG2, INTEL_SUBPLATFORM_##variant) && \
IS_GRAPHICS_STEP(__i915, since, until))
#define IS_DG2_DISPLAY_STEP(__i915, since, until) \
(IS_DG2(__i915) && \
IS_DISPLAY_STEP(__i915, since, until))

View File

@ -543,10 +543,9 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
{
u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
int report_size = stream->oa_buffer.format->size;
u32 head, tail, read_tail;
u32 tail, hw_tail;
unsigned long flags;
bool pollin;
u32 hw_tail;
u32 partial_report_size;
/* We have to consider the (unlikely) possibility that read() errors
@ -556,6 +555,7 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
hw_tail = stream->perf->ops.oa_hw_tail_read(stream);
hw_tail -= gtt_offset;
/* The tail pointer increases in 64 byte increments, not in report_size
* steps. Also the report size may not be a power of 2. Compute
@ -567,13 +567,6 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
/* Subtract partial amount off the tail */
hw_tail = OA_TAKEN(hw_tail, partial_report_size);
/* NB: The head we observe here might effectively be a little
* out of date. If a read() is in progress, the head could be
* anywhere between this head and stream->oa_buffer.tail.
*/
head = stream->oa_buffer.head - gtt_offset;
read_tail = stream->oa_buffer.tail - gtt_offset;
tail = hw_tail;
/* Walk the stream backward until we find a report with report
@ -587,7 +580,7 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
* memory in the order they were written to.
* If not : (°°
*/
while (OA_TAKEN(tail, read_tail) >= report_size) {
while (OA_TAKEN(tail, stream->oa_buffer.tail) >= report_size) {
void *report = stream->oa_buffer.vaddr + tail;
if (oa_report_id(stream, report) ||
@ -601,9 +594,9 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
__ratelimit(&stream->perf->tail_pointer_race))
drm_notice(&stream->uncore->i915->drm,
"unlanded report(s) head=0x%x tail=0x%x hw_tail=0x%x\n",
head, tail, hw_tail);
stream->oa_buffer.head, tail, hw_tail);
stream->oa_buffer.tail = gtt_offset + tail;
stream->oa_buffer.tail = tail;
pollin = OA_TAKEN(stream->oa_buffer.tail,
stream->oa_buffer.head) >= report_size;
@ -753,13 +746,6 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
/*
* NB: oa_buffer.head/tail include the gtt_offset which we don't want
* while indexing relative to oa_buf_base.
*/
head -= gtt_offset;
tail -= gtt_offset;
/*
* An out of bounds or misaligned head or tail pointer implies a driver
* bug since we validate + align the tail pointers we read from the
@ -895,9 +881,8 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
* We removed the gtt_offset for the copy loop above, indexing
* relative to oa_buf_base so put back here...
*/
head += gtt_offset;
intel_uncore_write(uncore, oaheadptr,
head & GEN12_OAG_OAHEADPTR_MASK);
(head + gtt_offset) & GEN12_OAG_OAHEADPTR_MASK);
stream->oa_buffer.head = head;
spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
@ -1042,12 +1027,6 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
/* NB: oa_buffer.head/tail include the gtt_offset which we don't want
* while indexing relative to oa_buf_base.
*/
head -= gtt_offset;
tail -= gtt_offset;
/* An out of bounds or misaligned head or tail pointer implies a driver
* bug since we validate + align the tail pointers we read from the
* hardware and we are in full control of the head pointer which should
@ -1110,13 +1089,8 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
if (start_offset != *offset) {
spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
/* We removed the gtt_offset for the copy loop above, indexing
* relative to oa_buf_base so put back here...
*/
head += gtt_offset;
intel_uncore_write(uncore, GEN7_OASTATUS2,
(head & GEN7_OASTATUS2_HEAD_MASK) |
((head + gtt_offset) & GEN7_OASTATUS2_HEAD_MASK) |
GEN7_OASTATUS2_MEM_SELECT_GGTT);
stream->oa_buffer.head = head;
@ -1675,13 +1649,6 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
free_oa_buffer(stream);
/*
* Wa_16011777198:dg2: Unset the override of GUCRC mode to enable rc6.
*/
if (stream->override_gucrc)
drm_WARN_ON(&gt->i915->drm,
intel_guc_slpc_unset_gucrc_mode(&gt->uc.guc.slpc));
intel_uncore_forcewake_put(stream->uncore, FORCEWAKE_ALL);
intel_engine_pm_put(stream->engine);
@ -1711,7 +1678,7 @@ static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
*/
intel_uncore_write(uncore, GEN7_OASTATUS2, /* head */
gtt_offset | GEN7_OASTATUS2_MEM_SELECT_GGTT);
stream->oa_buffer.head = gtt_offset;
stream->oa_buffer.head = 0;
intel_uncore_write(uncore, GEN7_OABUFFER, gtt_offset);
@ -1719,7 +1686,7 @@ static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
gtt_offset | OABUFFER_SIZE_16M);
/* Mark that we need updated tail pointers to read from... */
stream->oa_buffer.tail = gtt_offset;
stream->oa_buffer.tail = 0;
spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
@ -1753,7 +1720,7 @@ static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
intel_uncore_write(uncore, GEN8_OASTATUS, 0);
intel_uncore_write(uncore, GEN8_OAHEADPTR, gtt_offset);
stream->oa_buffer.head = gtt_offset;
stream->oa_buffer.head = 0;
intel_uncore_write(uncore, GEN8_OABUFFER_UDW, 0);
@ -1770,7 +1737,7 @@ static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
intel_uncore_write(uncore, GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
/* Mark that we need updated tail pointers to read from... */
stream->oa_buffer.tail = gtt_offset;
stream->oa_buffer.tail = 0;
/*
* Reset state used to recognise context switches, affecting which
@ -1807,7 +1774,7 @@ static void gen12_init_oa_buffer(struct i915_perf_stream *stream)
intel_uncore_write(uncore, __oa_regs(stream)->oa_status, 0);
intel_uncore_write(uncore, __oa_regs(stream)->oa_head_ptr,
gtt_offset & GEN12_OAG_OAHEADPTR_MASK);
stream->oa_buffer.head = gtt_offset;
stream->oa_buffer.head = 0;
/*
* PRM says:
@ -1823,7 +1790,7 @@ static void gen12_init_oa_buffer(struct i915_perf_stream *stream)
gtt_offset & GEN12_OAG_OATAILPTR_MASK);
/* Mark that we need updated tail pointers to read from... */
stream->oa_buffer.tail = gtt_offset;
stream->oa_buffer.tail = 0;
/*
* Reset state used to recognise context switches, affecting which
@ -3227,11 +3194,10 @@ get_sseu_config(struct intel_sseu *out_sseu,
*/
u32 i915_perf_oa_timestamp_frequency(struct drm_i915_private *i915)
{
/*
* Wa_18013179988:dg2
* Wa_14015846243:mtl
*/
if (IS_DG2(i915) || IS_METEORLAKE(i915)) {
struct intel_gt *gt = to_gt(i915);
/* Wa_18013179988 */
if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
intel_wakeref_t wakeref;
u32 reg, shift;
@ -3272,7 +3238,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
struct drm_i915_private *i915 = stream->perf->i915;
struct i915_perf *perf = stream->perf;
struct i915_perf_group *g;
struct intel_gt *gt;
int ret;
if (!props->engine) {
@ -3280,7 +3245,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
"OA engine not specified\n");
return -EINVAL;
}
gt = props->engine->gt;
g = props->engine->oa_group;
/*
@ -3381,25 +3345,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
intel_engine_pm_get(stream->engine);
intel_uncore_forcewake_get(stream->uncore, FORCEWAKE_ALL);
/*
* Wa_16011777198:dg2: GuC resets render as part of the Wa. This causes
* OA to lose the configuration state. Prevent this by overriding GUCRC
* mode.
*/
if (intel_uc_uses_guc_rc(&gt->uc) &&
(IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0))) {
ret = intel_guc_slpc_override_gucrc_mode(&gt->uc.guc.slpc,
SLPC_GUCRC_MODE_GUCRC_NO_RC6);
if (ret) {
drm_dbg(&stream->perf->i915->drm,
"Unable to override gucrc mode\n");
goto err_gucrc;
}
stream->override_gucrc = true;
}
ret = alloc_oa_buffer(stream);
if (ret)
goto err_oa_buf_alloc;
@ -3436,10 +3381,6 @@ err_enable:
free_oa_buffer(stream);
err_oa_buf_alloc:
if (stream->override_gucrc)
intel_guc_slpc_unset_gucrc_mode(&gt->uc.guc.slpc);
err_gucrc:
intel_uncore_forcewake_put(stream->uncore, FORCEWAKE_ALL);
intel_engine_pm_put(stream->engine);
@ -4223,7 +4164,7 @@ static int read_properties_unlocked(struct i915_perf *perf,
* C6 disable in BIOS. Fail if Media C6 is enabled on steppings where OAM
* does not work as expected.
*/
if (IS_MTL_MEDIA_STEP(props->engine->i915, STEP_A0, STEP_C0) &&
if (IS_MEDIA_GT_IP_STEP(props->engine->gt, IP_VER(13, 0), STEP_A0, STEP_C0) &&
props->engine->oa_group->type == TYPE_OAM &&
intel_check_bios_c6_setup(&props->engine->gt->rc6)) {
drm_dbg(&perf->i915->drm,
@ -4539,7 +4480,7 @@ static bool xehp_is_valid_b_counter_addr(struct i915_perf *perf, u32 addr)
static bool gen12_is_valid_mux_addr(struct i915_perf *perf, u32 addr)
{
if (IS_METEORLAKE(perf->i915))
if (GRAPHICS_VER_FULL(perf->i915) >= IP_VER(12, 70))
return reg_in_range_table(addr, mtl_oa_mux_regs);
else
return reg_in_range_table(addr, gen12_oa_mux_regs);
@ -5332,16 +5273,9 @@ int i915_perf_ioctl_version(struct drm_i915_private *i915)
* C6 disable in BIOS. If Media C6 is enabled in BIOS, return version 6
* to indicate that OA media is not supported.
*/
if (IS_MTL_MEDIA_STEP(i915, STEP_A0, STEP_C0)) {
struct intel_gt *gt;
int i;
for_each_gt(gt, i915, i) {
if (gt->type == GT_MEDIA &&
intel_check_bios_c6_setup(&gt->rc6))
return 6;
}
}
if (IS_MEDIA_GT_IP_STEP(i915->media_gt, IP_VER(13, 0), STEP_A0, STEP_C0) &&
intel_check_bios_c6_setup(&i915->media_gt->rc6))
return 6;
return 7;
}

View File

@ -338,12 +338,6 @@ struct i915_perf_stream {
* buffer should be checked for available data.
*/
u64 poll_oa_period;
/**
* @override_gucrc: GuC RC has been overridden for the perf stream,
* and we need to restore the default configuration on release.
*/
bool override_gucrc;
};
/**

View File

@ -396,14 +396,6 @@ static void dg2_init_clock_gating(struct drm_i915_private *i915)
/* Wa_22010954014:dg2 */
intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0,
SGSI_SIDECLK_DIS);
/*
* Wa_14010733611:dg2_g10
* Wa_22010146351:dg2_g10
*/
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0))
intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0,
SGR_DIS | SGGI_DIS);
}
static void pvc_init_clock_gating(struct drm_i915_private *i915)

View File

@ -206,14 +206,6 @@ static const u16 subplatform_g12_ids[] = {
INTEL_DG2_G12_IDS(0),
};
static const u16 subplatform_m_ids[] = {
INTEL_MTL_M_IDS(0),
};
static const u16 subplatform_p_ids[] = {
INTEL_MTL_P_IDS(0),
};
static bool find_devid(u16 id, const u16 *p, unsigned int num)
{
for (; num; num--, p++) {
@ -275,12 +267,6 @@ static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
} else if (find_devid(devid, subplatform_g12_ids,
ARRAY_SIZE(subplatform_g12_ids))) {
mask = BIT(INTEL_SUBPLATFORM_G12);
} else if (find_devid(devid, subplatform_m_ids,
ARRAY_SIZE(subplatform_m_ids))) {
mask = BIT(INTEL_SUBPLATFORM_M);
} else if (find_devid(devid, subplatform_p_ids,
ARRAY_SIZE(subplatform_p_ids))) {
mask = BIT(INTEL_SUBPLATFORM_P);
}
GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK);

View File

@ -129,10 +129,6 @@ enum intel_platform {
#define INTEL_SUBPLATFORM_N 1
#define INTEL_SUBPLATFORM_RPLU 2
/* MTL */
#define INTEL_SUBPLATFORM_M 0
#define INTEL_SUBPLATFORM_P 1
enum intel_ppgtt_type {
INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE,
INTEL_PPGTT_ALIASING = I915_GEM_PPGTT_ALIASING,

View File

@ -14,8 +14,8 @@
#define PXP43_CMDID_NEW_HUC_AUTH 0x0000003F /* MTL+ */
#define PXP43_CMDID_INIT_SESSION 0x00000036
/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */
#define PXP43_MAX_HECI_INOUT_SIZE (SZ_32K)
/* PXP-Packet sizes for MTL's GSCCS-HECI instruction is spec'd at 65K before page alignment*/
#define PXP43_MAX_HECI_INOUT_SIZE (PAGE_ALIGN(SZ_64K + SZ_1K))
/* PXP-Packet size for MTL's NEW_HUC_AUTH instruction */
#define PXP43_HUC_AUTH_INOUT_SIZE (SZ_4K)

View File

@ -111,7 +111,7 @@ gsccs_send_message(struct intel_pxp *pxp,
ret = intel_gsc_uc_heci_cmd_submit_nonpriv(&gt->uc.gsc,
exec_res->ce, &pkt, exec_res->bb_vaddr,
GSC_REPLY_LATENCY_MS);
GSC_HECI_REPLY_LATENCY_MS);
if (ret) {
drm_err(&i915->drm, "failed to send gsc PXP msg (%d)\n", ret);
goto unlock;

View File

@ -8,16 +8,14 @@
#include <linux/types.h>
#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
struct intel_pxp;
#define GSC_REPLY_LATENCY_MS 210
/*
* Max FW response time is 200ms, to which we add 10ms to account for overhead
* such as request preparation, GuC submission to hw and pipeline completion times.
*/
#define GSC_PENDING_RETRY_MAXCOUNT 40
#define GSC_PENDING_RETRY_PAUSE_MS 50
#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS)
#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_HECI_REPLY_LATENCY_MS + \
(GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS))
#ifdef CONFIG_DRM_I915_PXP
void intel_pxp_gsccs_fini(struct intel_pxp *pxp);

View File

@ -9,6 +9,7 @@
#include <drm/i915_component.h>
#include "gem/i915_gem_lmem.h"
#include "gt/intel_gt_print.h"
#include "i915_drv.h"
#include "gt/intel_gt.h"
@ -155,7 +156,8 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
{
struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
struct intel_pxp *pxp = i915->pxp;
struct intel_uc *uc = &pxp->ctrl_gt->uc;
struct intel_gt *gt = pxp->ctrl_gt;
struct intel_uc *uc = &gt->uc;
intel_wakeref_t wakeref;
int ret = 0;
@ -175,7 +177,7 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
/* load huc via pxp */
ret = intel_huc_fw_load_and_auth_via_gsc(&uc->huc);
if (ret < 0)
drm_err(&i915->drm, "failed to load huc via gsc %d\n", ret);
gt_probe_error(gt, "failed to load huc via gsc %d\n", ret);
}
}

View File

@ -179,6 +179,9 @@ igt_spinner_create_request(struct igt_spinner *spin,
*batch++ = arbitration_command;
memset32(batch, MI_NOOP, 128);
batch += 128;
if (GRAPHICS_VER(rq->i915) >= 8)
*batch++ = MI_BATCH_BUFFER_START | BIT(8) | 1;
else if (IS_HASWELL(rq->i915))

View File

@ -738,18 +738,14 @@
#define INTEL_ATS_M_IDS(info) \
INTEL_ATS_M150_IDS(info), \
INTEL_ATS_M75_IDS(info)
/* MTL */
#define INTEL_MTL_M_IDS(info) \
INTEL_VGA_DEVICE(0x7D40, info), \
INTEL_VGA_DEVICE(0x7D60, info)
#define INTEL_MTL_P_IDS(info) \
/* MTL */
#define INTEL_MTL_IDS(info) \
INTEL_VGA_DEVICE(0x7D40, info), \
INTEL_VGA_DEVICE(0x7D45, info), \
INTEL_VGA_DEVICE(0x7D55, info), \
INTEL_VGA_DEVICE(0x7D60, info), \
INTEL_VGA_DEVICE(0x7D67, info), \
INTEL_VGA_DEVICE(0x7DD5, info)
#define INTEL_MTL_IDS(info) \
INTEL_MTL_M_IDS(info), \
INTEL_MTL_P_IDS(info)
#endif /* _I915_PCIIDS_H */