Commit a78313bb authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-gt-next-2024-06-12' of...

Merge tag 'drm-intel-gt-next-2024-06-12' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

UAPI Changes:

- Support replaying GPU hangs with captured context image (Tvrtko Ursulin)

Driver Changes:

Fixes/improvements/new stuff:

- Automate CCS Mode setting during engine resets [gt] (Andi Shyti)
- Revert "drm/i915: Remove extra multi-gt pm-references" (Janusz Krzysztofik)
- Fix HAS_REGION() usage in intel_gt_probe_lmem() (Ville Syrjälä)
- Disarm breadcrumbs if engines are already idle [gt] (Chris Wilson)
- Shadow default engine context image in the context (Tvrtko Ursulin)
- Support replaying GPU hangs with captured context image (Tvrtko Ursulin)
- avoid FIELD_PREP warning [guc] (Arnd Bergmann)
- Fix CCS id's calculation for CCS mode setting [gt] (Andi Shyti)
- Increase FLR timeout from 3s to 9s (Andi Shyti)
- Update workaround 14018575942 [mtl] (Angus Chen)

Future platform enablement:

- Enable w/a 16021333562 for DG2, MTL and ARL [guc] (John Harrison)

Miscellaneous:

- Pass the region ID rather than a bitmask to HAS_REGION() (Ville Syrjälä)
- Remove counter productive REGION_* wrappers (Ville Syrjälä)
- Fix typo [gem/i915_gem_ttm_move] (Deming Wang)
- Delete the live_hearbeat_fast selftest [gt] (Krzysztof Niemiec)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Zmmazub+U9ewH9ts@linux
parents 365aa9f5 79655e86
......@@ -16,6 +16,23 @@ config DRM_I915_WERROR
If in doubt, say "N".
config DRM_I915_REPLAY_GPU_HANGS_API
bool "Enable GPU hang replay userspace API"
depends on DRM_I915
depends on EXPERT
default n
help
Choose this option if you want to enable special and unstable
userspace API used for replaying GPU hangs on a running system.
This API is intended to be used by userspace graphics stack developers
and provides no stability guarantees.
The API needs to be activated at boot time using the
enable_debug_only_api module parameter.
If in doubt, say "N".
config DRM_I915_DEBUG
bool "Enable additional driver debugging"
depends on DRM_I915
......
......@@ -78,6 +78,7 @@
#include "gt/intel_engine_user.h"
#include "gt/intel_gpu_commands.h"
#include "gt/intel_ring.h"
#include "gt/shmem_utils.h"
#include "pxp/intel_pxp.h"
......@@ -957,6 +958,7 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
case I915_CONTEXT_PARAM_NO_ZEROMAP:
case I915_CONTEXT_PARAM_BAN_PERIOD:
case I915_CONTEXT_PARAM_RINGSIZE:
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
default:
ret = -EINVAL;
break;
......@@ -2104,6 +2106,95 @@ static int get_protected(struct i915_gem_context *ctx,
return 0;
}
static int set_context_image(struct i915_gem_context *ctx,
struct drm_i915_gem_context_param *args)
{
struct i915_gem_context_param_context_image user;
struct intel_context *ce;
struct file *shmem_state;
unsigned long lookup;
void *state;
int ret = 0;
if (!IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API))
return -EINVAL;
if (!ctx->i915->params.enable_debug_only_api)
return -EINVAL;
if (args->size < sizeof(user))
return -EINVAL;
if (copy_from_user(&user, u64_to_user_ptr(args->value), sizeof(user)))
return -EFAULT;
if (user.mbz)
return -EINVAL;
if (user.flags & ~(I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX))
return -EINVAL;
lookup = 0;
if (user.flags & I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX)
lookup |= LOOKUP_USER_INDEX;
ce = lookup_user_engine(ctx, lookup, &user.engine);
if (IS_ERR(ce))
return PTR_ERR(ce);
if (user.size < ce->engine->context_size) {
ret = -EINVAL;
goto out_ce;
}
if (drm_WARN_ON_ONCE(&ctx->i915->drm,
test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
/*
* This is racy but for a debug only API, if userspace is keen
* to create and configure contexts, while simultaneously using
* them from a second thread, let them suffer by potentially not
* executing with the context image they just raced to apply.
*/
ret = -EBUSY;
goto out_ce;
}
state = kmalloc(ce->engine->context_size, GFP_KERNEL);
if (!state) {
ret = -ENOMEM;
goto out_ce;
}
if (copy_from_user(state, u64_to_user_ptr(user.image),
ce->engine->context_size)) {
ret = -EFAULT;
goto out_state;
}
shmem_state = shmem_create_from_data(ce->engine->name,
state, ce->engine->context_size);
if (IS_ERR(shmem_state)) {
ret = PTR_ERR(shmem_state);
goto out_state;
}
if (intel_context_set_own_state(ce)) {
ret = -EBUSY;
fput(shmem_state);
goto out_state;
}
ce->default_state = shmem_state;
args->size = sizeof(user);
out_state:
kfree(state);
out_ce:
intel_context_put(ce);
return ret;
}
static int ctx_setparam(struct drm_i915_file_private *fpriv,
struct i915_gem_context *ctx,
struct drm_i915_gem_context_param *args)
......@@ -2156,6 +2247,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
ret = set_persistence(ctx, args);
break;
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
ret = set_context_image(ctx, args);
break;
case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
case I915_CONTEXT_PARAM_NO_ZEROMAP:
case I915_CONTEXT_PARAM_BAN_PERIOD:
......@@ -2500,6 +2595,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
case I915_CONTEXT_PARAM_BAN_PERIOD:
case I915_CONTEXT_PARAM_ENGINES:
case I915_CONTEXT_PARAM_RINGSIZE:
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
default:
ret = -EINVAL;
break;
......@@ -2612,5 +2708,22 @@ int __init i915_gem_context_module_init(void)
if (!slab_luts)
return -ENOMEM;
if (IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)) {
pr_notice("**************************************************************\n");
pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
pr_notice("** **\n");
if (i915_modparams.enable_debug_only_api)
pr_notice("** i915.enable_debug_only_api is intended to be set **\n");
else
pr_notice("** CONFIG_DRM_I915_REPLAY_GPU_HANGS_API builds are intended **\n");
pr_notice("** for specific userspace graphics stack developers only! **\n");
pr_notice("** **\n");
pr_notice("** If you are seeing this message please report this to the **\n");
pr_notice("** provider of your kernel build. **\n");
pr_notice("** **\n");
pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
pr_notice("**************************************************************\n");
}
return 0;
}
......@@ -155,7 +155,7 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj)
* @bo: The ttm buffer object.
*
* This function prepares an object for move by removing all GPU bindings,
* removing all CPU mapings and finally releasing the pages sg-table.
* removing all CPU mappings and finally releasing the pages sg-table.
*
* Return: 0 if successful, negative error code on error.
*/
......
......@@ -27,6 +27,8 @@ static void rcu_context_free(struct rcu_head *rcu)
struct intel_context *ce = container_of(rcu, typeof(*ce), rcu);
trace_intel_context_free(ce);
if (intel_context_has_own_state(ce))
fput(ce->default_state);
kmem_cache_free(slab_ce, ce);
}
......
......@@ -375,6 +375,28 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, &ce->flags);
}
#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)
static inline bool intel_context_has_own_state(const struct intel_context *ce)
{
return test_bit(CONTEXT_OWN_STATE, &ce->flags);
}
static inline bool intel_context_set_own_state(struct intel_context *ce)
{
return test_and_set_bit(CONTEXT_OWN_STATE, &ce->flags);
}
#else
static inline bool intel_context_has_own_state(const struct intel_context *ce)
{
return false;
}
static inline bool intel_context_set_own_state(struct intel_context *ce)
{
return true;
}
#endif
u64 intel_context_get_total_runtime_ns(struct intel_context *ce);
u64 intel_context_get_avg_runtime_ns(struct intel_context *ce);
......
......@@ -99,6 +99,8 @@ struct intel_context {
struct i915_address_space *vm;
struct i915_gem_context __rcu *gem_context;
struct file *default_state;
/*
* @signal_lock protects the list of requests that need signaling,
* @signals. While there are any requests that need signaling,
......@@ -131,6 +133,7 @@ struct intel_context {
#define CONTEXT_IS_PARKING 12
#define CONTEXT_EXITING 13
#define CONTEXT_LOW_LATENCY 14
#define CONTEXT_OWN_STATE 15
struct {
u64 timeout_us;
......
......@@ -1017,9 +1017,8 @@ void lrc_init_state(struct intel_context *ce,
set_redzone(state, engine);
if (engine->default_state) {
shmem_read(engine->default_state, 0,
state, engine->context_size);
if (ce->default_state) {
shmem_read(ce->default_state, 0, state, engine->context_size);
__set_bit(CONTEXT_VALID_BIT, &ce->flags);
inhibit = false;
}
......@@ -1131,6 +1130,9 @@ int lrc_alloc(struct intel_context *ce, struct intel_engine_cs *engine)
GEM_BUG_ON(ce->state);
if (!intel_context_has_own_state(ce))
ce->default_state = engine->default_state;
vma = __lrc_alloc_state(ce, engine);
if (IS_ERR(vma))
return PTR_ERR(vma);
......
......@@ -474,8 +474,7 @@ static int ring_context_init_default_state(struct intel_context *ce,
if (IS_ERR(vaddr))
return PTR_ERR(vaddr);
shmem_read(ce->engine->default_state, 0,
vaddr, ce->engine->context_size);
shmem_read(ce->default_state, 0, vaddr, ce->engine->context_size);
i915_gem_object_flush_map(obj);
__i915_gem_object_release_map(obj);
......@@ -491,7 +490,7 @@ static int ring_context_pre_pin(struct intel_context *ce,
struct i915_address_space *vm;
int err = 0;
if (ce->engine->default_state &&
if (ce->default_state &&
!test_bit(CONTEXT_VALID_BIT, &ce->flags)) {
err = ring_context_init_default_state(ce, ww);
if (err)
......@@ -570,6 +569,9 @@ static int ring_context_alloc(struct intel_context *ce)
{
struct intel_engine_cs *engine = ce->engine;
if (!intel_context_has_own_state(ce))
ce->default_state = engine->default_state;
/* One ringbuffer to rule them all */
GEM_BUG_ON(!engine->legacy.ring);
ce->ring = engine->legacy.ring;
......
......@@ -1590,6 +1590,14 @@ xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
*/
wa_write_or(wal, XELPMP_GSC_MOD_CTRL, FORCE_MISS_FTLB);
/*
* Wa_14018575942
*
* Issue is seen on media KPI test running on VDBOX engine
* especially VP9 encoding WLs
*/
wa_write_or(wal, XELPMP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
/* Wa_22016670082 */
wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);
......
......@@ -193,115 +193,6 @@ static int live_idle_pulse(void *arg)
return err;
}
static int cmp_u32(const void *_a, const void *_b)
{
const u32 *a = _a, *b = _b;
return *a - *b;
}
static int __live_heartbeat_fast(struct intel_engine_cs *engine)
{
const unsigned int error_threshold = max(20000u, jiffies_to_usecs(6));
struct intel_context *ce;
struct i915_request *rq;
ktime_t t0, t1;
u32 times[5];
int err;
int i;
ce = intel_context_create(engine);
if (IS_ERR(ce))
return PTR_ERR(ce);
intel_engine_pm_get(engine);
err = intel_engine_set_heartbeat(engine, 1);
if (err)
goto err_pm;
for (i = 0; i < ARRAY_SIZE(times); i++) {
do {
/* Manufacture a tick */
intel_engine_park_heartbeat(engine);
GEM_BUG_ON(engine->heartbeat.systole);
engine->serial++; /* pretend we are not idle! */
intel_engine_unpark_heartbeat(engine);
flush_delayed_work(&engine->heartbeat.work);
if (!delayed_work_pending(&engine->heartbeat.work)) {
pr_err("%s: heartbeat %d did not start\n",
engine->name, i);
err = -EINVAL;
goto err_pm;
}
rcu_read_lock();
rq = READ_ONCE(engine->heartbeat.systole);
if (rq)
rq = i915_request_get_rcu(rq);
rcu_read_unlock();
} while (!rq);
t0 = ktime_get();
while (rq == READ_ONCE(engine->heartbeat.systole))
yield(); /* work is on the local cpu! */
t1 = ktime_get();
i915_request_put(rq);
times[i] = ktime_us_delta(t1, t0);
}
sort(times, ARRAY_SIZE(times), sizeof(times[0]), cmp_u32, NULL);
pr_info("%s: Heartbeat delay: %uus [%u, %u]\n",
engine->name,
times[ARRAY_SIZE(times) / 2],
times[0],
times[ARRAY_SIZE(times) - 1]);
/*
* Ideally, the upper bound on min work delay would be something like
* 2 * 2 (worst), +1 for scheduling, +1 for slack. In practice, we
* are, even with system_wq_highpri, at the mercy of the CPU scheduler
* and may be stuck behind some slow work for many millisecond. Such
* as our very own display workers.
*/
if (times[ARRAY_SIZE(times) / 2] > error_threshold) {
pr_err("%s: Heartbeat delay was %uus, expected less than %dus\n",
engine->name,
times[ARRAY_SIZE(times) / 2],
error_threshold);
err = -EINVAL;
}
reset_heartbeat(engine);
err_pm:
intel_engine_pm_put(engine);
intel_context_put(ce);
return err;
}
static int live_heartbeat_fast(void *arg)
{
struct intel_gt *gt = arg;
struct intel_engine_cs *engine;
enum intel_engine_id id;
int err = 0;
/* Check that the heartbeat ticks at the desired rate. */
if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
return 0;
for_each_engine(engine, gt, id) {
err = __live_heartbeat_fast(engine);
if (err)
break;
}
return err;
}
static int __live_heartbeat_off(struct intel_engine_cs *engine)
{
int err;
......@@ -372,7 +263,6 @@ int intel_heartbeat_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(live_idle_flush),
SUBTEST(live_idle_pulse),
SUBTEST(live_heartbeat_fast),
SUBTEST(live_heartbeat_off),
};
int saved_hangcheck;
......
......@@ -106,6 +106,7 @@ enum {
*/
enum {
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE = 0x9001,
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED = 0x9002,
};
#endif /* _ABI_GUC_KLVS_ABI_H */
......@@ -815,23 +815,23 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
}
/* Wa_14019159160 */
static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
static void guc_waklv_enable_simple(struct intel_guc *guc,
u32 klv_id, u32 *offset, u32 *remain)
{
u32 size;
u32 klv_entry[] = {
/* 16:16 key/length */
FIELD_PREP(GUC_KLV_0_KEY, GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
FIELD_PREP(GUC_KLV_0_LEN, 0),
/* 0 dwords data */
};
size = sizeof(klv_entry);
GEM_BUG_ON(remain < size);
GEM_BUG_ON(*remain < size);
iosys_map_memcpy_to(&guc->ads_map, offset, klv_entry, size);
return size;
iosys_map_memcpy_to(&guc->ads_map, *offset, klv_entry, size);
*offset += size;
*remain -= size;
}
static void guc_waklv_init(struct intel_guc *guc)
......@@ -850,11 +850,19 @@ static void guc_waklv_init(struct intel_guc *guc)
remain = guc_ads_waklv_size(guc);
/* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
size = guc_waklv_ra_mode(guc, offset, remain);
offset += size;
remain -= size;
}
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
guc_waklv_enable_simple(guc,
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE,
&offset, &remain);
/* Wa_16021333562 */
if ((GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 21, 1)) &&
(IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) ||
IS_MEDIA_GT_IP_RANGE(gt, IP_VER(13, 0), IP_VER(13, 0)) ||
IS_DG2(gt->i915)))
guc_waklv_enable_simple(guc,
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
&offset, &remain);
size = guc_ads_waklv_size(guc) - remain;
if (!size)
......
......@@ -724,8 +724,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
*/
#define HAS_64K_PAGES(i915) (INTEL_INFO(i915)->has_64k_pages)
#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
#define HAS_REGION(i915, id) (INTEL_INFO(i915)->memory_regions & BIT(id))
#define HAS_LMEM(i915) HAS_REGION(i915, INTEL_REGION_LMEM_0)
#define HAS_EXTRA_GT_LIST(i915) (INTEL_INFO(i915)->extra_gt_list)
......
......@@ -131,6 +131,11 @@ i915_param_named_unsafe(lmem_size, uint, 0400,
i915_param_named_unsafe(lmem_bar_size, uint, 0400,
"Set the lmem bar size(in MiB).");
#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)
i915_param_named(enable_debug_only_api, bool, 0400,
"Enable support for unstable debug only userspace API. (default:false)");
#endif
static void _param_print_bool(struct drm_printer *p, const char *name,
bool val)
{
......
......@@ -63,7 +63,8 @@ struct drm_printer;
/* leave bools at the end to not create holes */ \
param(bool, enable_hangcheck, true, 0600) \
param(bool, error_capture, true, IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) ? 0600 : 0) \
param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0)
param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) \
param(bool, enable_debug_only_api, false, IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API) ? 0400 : 0)
#define MEMBER(T, member, ...) T member;
struct i915_params {
......
......@@ -76,7 +76,7 @@ __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for d
.__runtime.page_sizes = I915_GTT_PAGE_SIZE_4K
#define GEN_DEFAULT_REGIONS \
.memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_STOLEN_SMEM)
#define I830_FEATURES \
GEN(2), \
......@@ -655,7 +655,7 @@ static const struct intel_device_info rkl_info = {
};
#define DGFX_FEATURES \
.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_LMEM_0) | BIT(INTEL_REGION_STOLEN_LMEM), \
.has_llc = 0, \
.has_pxp = 0, \
.has_snoop = 1, \
......@@ -781,7 +781,7 @@ static const struct intel_device_info mtl_info = {
.has_snoop = 1,
.max_pat_index = 4,
.has_pxp = 1,
.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_STOLEN_LMEM),
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
MTL_CACHELEVEL,
};
......
......@@ -332,7 +332,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
struct intel_memory_region *mem = ERR_PTR(-ENODEV);
u16 type, instance;
if (!HAS_REGION(i915, BIT(i)))
if (!HAS_REGION(i915, i))
continue;
type = intel_region_map[i].class;
......
......@@ -38,11 +38,6 @@ enum intel_region_id {
INTEL_REGION_UNKNOWN, /* Should be last */
};
#define REGION_SMEM BIT(INTEL_REGION_SMEM)
#define REGION_LMEM BIT(INTEL_REGION_LMEM_0)
#define REGION_STOLEN_SMEM BIT(INTEL_REGION_STOLEN_SMEM)
#define REGION_STOLEN_LMEM BIT(INTEL_REGION_STOLEN_LMEM)
#define I915_ALLOC_CONTIGUOUS BIT(0)
#define for_each_memory_region(mr, i915, id) \
......
......@@ -2614,11 +2614,18 @@ void intel_uncore_prune_engine_fw_domains(struct intel_uncore *uncore,
static void driver_initiated_flr(struct intel_uncore *uncore)
{
struct drm_i915_private *i915 = uncore->i915;
const unsigned int flr_timeout_ms = 3000; /* specs recommend a 3s wait */
unsigned int flr_timeout_ms;
int ret;
drm_dbg(&i915->drm, "Triggering Driver-FLR\n");
/*
* The specification recommends a 3 seconds FLR reset timeout. To be
* cautious, we will extend this to 9 seconds, three times the specified
* timeout.
*/
flr_timeout_ms = 9000;
/*
* Make sure any pending FLR requests have cleared by waiting for the
* FLR trigger bit to go to zero. Also clear GU_DEBUG's DRIVERFLR_STATUS
......
......@@ -122,7 +122,7 @@ static const struct intel_device_info mock_info = {
.__runtime.page_sizes = (I915_GTT_PAGE_SIZE_4K |
I915_GTT_PAGE_SIZE_64K |
I915_GTT_PAGE_SIZE_2M),
.memory_regions = REGION_SMEM,
.memory_regions = BIT(INTEL_REGION_SMEM),
.platform_engine_mask = BIT(0),
/* simply use legacy cache level for mock device */
......
......@@ -2163,6 +2163,15 @@ struct drm_i915_gem_context_param {
* supports this per context flag.
*/
#define I915_CONTEXT_PARAM_LOW_LATENCY 0xe
/*
* I915_CONTEXT_PARAM_CONTEXT_IMAGE:
*
* Allows userspace to provide own context images.
*
* Note that this is a debug API not available on production kernel builds.
*/
#define I915_CONTEXT_PARAM_CONTEXT_IMAGE 0xf
/* Must be kept compact -- no holes and well documented */
/** @value: Context parameter value to be set or queried */
......@@ -2564,6 +2573,24 @@ struct i915_context_param_engines {
struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
struct i915_gem_context_param_context_image {
/** @engine: Engine class & instance to be configured. */
struct i915_engine_class_instance engine;
/** @flags: One of the supported flags or zero. */
__u32 flags;
#define I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX (1u << 0)
/** @size: Size of the image blob pointed to by @image. */
__u32 size;
/** @mbz: Must be zero. */
__u32 mbz;
/** @image: Userspace memory containing the context image. */
__u64 image;
} __attribute__((packed));
/**
* struct drm_i915_gem_context_create_ext_setparam - Context parameter
* to set or query during context creation.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment