/* SPDX-License-Identifier: MIT */ /* * Copyright © 2023 Intel Corporation */ #ifndef _UAPI_XE_DRM_H_ #define _UAPI_XE_DRM_H_ #include "drm.h" #if defined(__cplusplus) extern "C" { #endif /* * Please note that modifications to all structs defined here are * subject to backwards-compatibility constraints. * Sections in this file are organized as follows: * 1. IOCTL definition * 2. Extension definition and helper structs * 3. IOCTL's Query structs in the order of the Query's entries. * 4. The rest of IOCTL structs in the order of IOCTL declaration. */ /** * DOC: Xe Device Block Diagram * * The diagram below represents a high-level simplification of a discrete * GPU supported by the Xe driver. It shows some device components which * are necessary to understand this API, as well as how their relations * to each other. This diagram does not represent real hardware:: * * ┌──────────────────────────────────────────────────────────────────┐ * │ ┌──────────────────────────────────────────────────┐ ┌─────────┐ │ * │ │ ┌───────────────────────┐ ┌─────┐ │ │ ┌─────┐ │ │ * │ │ │ VRAM0 ├───┤ ... │ │ │ │VRAM1│ │ │ * │ │ └───────────┬───────────┘ └─GT1─┘ │ │ └──┬──┘ │ │ * │ │ ┌──────────────────┴───────────────────────────┐ │ │ ┌──┴──┐ │ │ * │ │ │ ┌─────────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ * │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ * │ │ │ │ │EU│ │EU│ │EU│ │EU│ │ │ │RCS0 │ │BCS0 │ │ │ │ │ │ │ │ │ * │ │ │ │ └──┘ └──┘ └──┘ └──┘ │ │ └─────┘ └─────┘ │ │ │ │ │ │ │ │ * │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ * │ │ │ │ │EU│ │EU│ │EU│ │EU│ │ │ │VCS0 │ │VCS1 │ │ │ │ │ │ │ │ │ * │ │ │ │ └──┘ └──┘ └──┘ └──┘ │ │ └─────┘ └─────┘ │ │ │ │ │ │ │ │ * │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ * │ │ │ │ │EU│ │EU│ │EU│ │EU│ │ │ │VECS0│ │VECS1│ │ │ │ │ │ ... │ │ │ * │ │ │ │ └──┘ └──┘ └──┘ └──┘ │ │ └─────┘ └─────┘ │ │ │ │ │ │ │ │ * │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ * │ │ │ │ │EU│ │EU│ │EU│ │EU│ │ │ │CCS0 │ │CCS1 │ │ │ │ │ │ │ │ │ * │ │ │ │ └──┘ └──┘ └──┘ └──┘ │ │ └─────┘ └─────┘ │ │ │ │ │ │ │ │ * │ │ │ └─────────DSS─────────┘ │ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ * │ │ │ │ │CCS2 │ │CCS3 │ │ │ │ │ │ │ │ │ * │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ └─────┘ └─────┘ │ │ │ │ │ │ │ │ * │ │ │ │ ... │ │ ... │ │ ... │ │ │ │ │ │ │ │ │ │ * │ │ │ └─DSS─┘ └─DSS─┘ └─DSS─┘ └─────Engines─────┘ │ │ │ │ │ │ │ * │ │ └───────────────────────────GT0────────────────┘ │ │ └─GT2─┘ │ │ * │ └────────────────────────────Tile0─────────────────┘ └─ Tile1──┘ │ * └─────────────────────────────Device0───────┬──────────────────────┘ * │ * ───────────────────────┴────────── PCI bus */ /** * DOC: Xe uAPI Overview * * This section aims to describe the Xe's IOCTL entries, its structs, and other * Xe related uAPI such as uevents and PMU (Platform Monitoring Unit) related * entries and usage. * * List of supported IOCTLs: * - &DRM_IOCTL_XE_DEVICE_QUERY * - &DRM_IOCTL_XE_GEM_CREATE * - &DRM_IOCTL_XE_GEM_MMAP_OFFSET * - &DRM_IOCTL_XE_VM_CREATE * - &DRM_IOCTL_XE_VM_DESTROY * - &DRM_IOCTL_XE_VM_BIND * - &DRM_IOCTL_XE_EXEC_QUEUE_CREATE * - &DRM_IOCTL_XE_EXEC_QUEUE_DESTROY * - &DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY * - &DRM_IOCTL_XE_EXEC * - &DRM_IOCTL_XE_WAIT_USER_FENCE * - &DRM_IOCTL_XE_OBSERVATION */ /* * xe specific ioctls. * * The device specific ioctl range is [DRM_COMMAND_BASE, DRM_COMMAND_END) ie * [0x40, 0xa0) (a0 is excluded). The numbers below are defined as offset * against DRM_COMMAND_BASE and should be between [0x0, 0x60). */ #define DRM_XE_DEVICE_QUERY … #define DRM_XE_GEM_CREATE … #define DRM_XE_GEM_MMAP_OFFSET … #define DRM_XE_VM_CREATE … #define DRM_XE_VM_DESTROY … #define DRM_XE_VM_BIND … #define DRM_XE_EXEC_QUEUE_CREATE … #define DRM_XE_EXEC_QUEUE_DESTROY … #define DRM_XE_EXEC_QUEUE_GET_PROPERTY … #define DRM_XE_EXEC … #define DRM_XE_WAIT_USER_FENCE … #define DRM_XE_OBSERVATION … /* Must be kept compact -- no holes */ #define DRM_IOCTL_XE_DEVICE_QUERY … #define DRM_IOCTL_XE_GEM_CREATE … #define DRM_IOCTL_XE_GEM_MMAP_OFFSET … #define DRM_IOCTL_XE_VM_CREATE … #define DRM_IOCTL_XE_VM_DESTROY … #define DRM_IOCTL_XE_VM_BIND … #define DRM_IOCTL_XE_EXEC_QUEUE_CREATE … #define DRM_IOCTL_XE_EXEC_QUEUE_DESTROY … #define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY … #define DRM_IOCTL_XE_EXEC … #define DRM_IOCTL_XE_WAIT_USER_FENCE … #define DRM_IOCTL_XE_OBSERVATION … /** * DOC: Xe IOCTL Extensions * * Before detailing the IOCTLs and its structs, it is important to highlight * that every IOCTL in Xe is extensible. * * Many interfaces need to grow over time. In most cases we can simply * extend the struct and have userspace pass in more data. Another option, * as demonstrated by Vulkan's approach to providing extensions for forward * and backward compatibility, is to use a list of optional structs to * provide those extra details. * * The key advantage to using an extension chain is that it allows us to * redefine the interface more easily than an ever growing struct of * increasing complexity, and for large parts of that interface to be * entirely optional. The downside is more pointer chasing; chasing across * the __user boundary with pointers encapsulated inside u64. * * Example chaining: * * .. code-block:: C * * struct drm_xe_user_extension ext3 { * .next_extension = 0, // end * .name = ..., * }; * struct drm_xe_user_extension ext2 { * .next_extension = (uintptr_t)&ext3, * .name = ..., * }; * struct drm_xe_user_extension ext1 { * .next_extension = (uintptr_t)&ext2, * .name = ..., * }; * * Typically the struct drm_xe_user_extension would be embedded in some uAPI * struct, and in this case we would feed it the head of the chain(i.e ext1), * which would then apply all of the above extensions. */ /** * struct drm_xe_user_extension - Base class for defining a chain of extensions */ struct drm_xe_user_extension { … }; /** * struct drm_xe_ext_set_property - Generic set property extension * * A generic struct that allows any of the Xe's IOCTL to be extended * with a set_property operation. */ struct drm_xe_ext_set_property { … }; /** * struct drm_xe_engine_class_instance - instance of an engine class * * It is returned as part of the @drm_xe_engine, but it also is used as * the input of engine selection for both @drm_xe_exec_queue_create and * @drm_xe_query_engine_cycles * * The @engine_class can be: * - %DRM_XE_ENGINE_CLASS_RENDER * - %DRM_XE_ENGINE_CLASS_COPY * - %DRM_XE_ENGINE_CLASS_VIDEO_DECODE * - %DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE * - %DRM_XE_ENGINE_CLASS_COMPUTE * - %DRM_XE_ENGINE_CLASS_VM_BIND - Kernel only classes (not actual * hardware engine class). Used for creating ordered queues of VM * bind operations. */ struct drm_xe_engine_class_instance { … }; /** * struct drm_xe_engine - describe hardware engine */ struct drm_xe_engine { … }; /** * struct drm_xe_query_engines - describe engines * * If a query is made with a struct @drm_xe_device_query where .query * is equal to %DRM_XE_DEVICE_QUERY_ENGINES, then the reply uses an array of * struct @drm_xe_query_engines in .data. */ struct drm_xe_query_engines { … }; /** * enum drm_xe_memory_class - Supported memory classes. */ enum drm_xe_memory_class { … }; /** * struct drm_xe_mem_region - Describes some region as known to * the driver. */ struct drm_xe_mem_region { … }; /** * struct drm_xe_query_mem_regions - describe memory regions * * If a query is made with a struct drm_xe_device_query where .query * is equal to DRM_XE_DEVICE_QUERY_MEM_REGIONS, then the reply uses * struct drm_xe_query_mem_regions in .data. */ struct drm_xe_query_mem_regions { … }; /** * struct drm_xe_query_config - describe the device configuration * * If a query is made with a struct drm_xe_device_query where .query * is equal to DRM_XE_DEVICE_QUERY_CONFIG, then the reply uses * struct drm_xe_query_config in .data. * * The index in @info can be: * - %DRM_XE_QUERY_CONFIG_REV_AND_DEVICE_ID - Device ID (lower 16 bits) * and the device revision (next 8 bits) * - %DRM_XE_QUERY_CONFIG_FLAGS - Flags describing the device * configuration, see list below * * - %DRM_XE_QUERY_CONFIG_FLAG_HAS_VRAM - Flag is set if the device * has usable VRAM * - %DRM_XE_QUERY_CONFIG_MIN_ALIGNMENT - Minimal memory alignment * required by this device, typically SZ_4K or SZ_64K * - %DRM_XE_QUERY_CONFIG_VA_BITS - Maximum bits of a virtual address * - %DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY - Value of the highest * available exec queue priority */ struct drm_xe_query_config { … }; /** * struct drm_xe_gt - describe an individual GT. * * To be used with drm_xe_query_gt_list, which will return a list with all the * existing GT individual descriptions. * Graphics Technology (GT) is a subset of a GPU/tile that is responsible for * implementing graphics and/or media operations. * * The index in @type can be: * - %DRM_XE_QUERY_GT_TYPE_MAIN * - %DRM_XE_QUERY_GT_TYPE_MEDIA */ struct drm_xe_gt { … }; /** * struct drm_xe_query_gt_list - A list with GT description items. * * If a query is made with a struct drm_xe_device_query where .query * is equal to DRM_XE_DEVICE_QUERY_GT_LIST, then the reply uses struct * drm_xe_query_gt_list in .data. */ struct drm_xe_query_gt_list { … }; /** * struct drm_xe_query_topology_mask - describe the topology mask of a GT * * This is the hardware topology which reflects the internal physical * structure of the GPU. * * If a query is made with a struct drm_xe_device_query where .query * is equal to DRM_XE_DEVICE_QUERY_GT_TOPOLOGY, then the reply uses * struct drm_xe_query_topology_mask in .data. * * The @type can be: * - %DRM_XE_TOPO_DSS_GEOMETRY - To query the mask of Dual Sub Slices * (DSS) available for geometry operations. For example a query response * containing the following in mask: * ``DSS_GEOMETRY ff ff ff ff 00 00 00 00`` * means 32 DSS are available for geometry. * - %DRM_XE_TOPO_DSS_COMPUTE - To query the mask of Dual Sub Slices * (DSS) available for compute operations. For example a query response * containing the following in mask: * ``DSS_COMPUTE ff ff ff ff 00 00 00 00`` * means 32 DSS are available for compute. * - %DRM_XE_TOPO_L3_BANK - To query the mask of enabled L3 banks * - %DRM_XE_TOPO_EU_PER_DSS - To query the mask of Execution Units (EU) * available per Dual Sub Slices (DSS). For example a query response * containing the following in mask: * ``EU_PER_DSS ff ff 00 00 00 00 00 00`` * means each DSS has 16 EU. */ struct drm_xe_query_topology_mask { … }; /** * struct drm_xe_query_engine_cycles - correlate CPU and GPU timestamps * * If a query is made with a struct drm_xe_device_query where .query is equal to * DRM_XE_DEVICE_QUERY_ENGINE_CYCLES, then the reply uses struct drm_xe_query_engine_cycles * in .data. struct drm_xe_query_engine_cycles is allocated by the user and * .data points to this allocated structure. * * The query returns the engine cycles, which along with GT's @reference_clock, * can be used to calculate the engine timestamp. In addition the * query returns a set of cpu timestamps that indicate when the command * streamer cycle count was captured. */ struct drm_xe_query_engine_cycles { … }; /** * struct drm_xe_query_uc_fw_version - query a micro-controller firmware version * * Given a uc_type this will return the branch, major, minor and patch version * of the micro-controller firmware. */ struct drm_xe_query_uc_fw_version { … }; /** * struct drm_xe_device_query - Input of &DRM_IOCTL_XE_DEVICE_QUERY - main * structure to query device information * * The user selects the type of data to query among DRM_XE_DEVICE_QUERY_* * and sets the value in the query member. This determines the type of * the structure provided by the driver in data, among struct drm_xe_query_*. * * The @query can be: * - %DRM_XE_DEVICE_QUERY_ENGINES * - %DRM_XE_DEVICE_QUERY_MEM_REGIONS * - %DRM_XE_DEVICE_QUERY_CONFIG * - %DRM_XE_DEVICE_QUERY_GT_LIST * - %DRM_XE_DEVICE_QUERY_HWCONFIG - Query type to retrieve the hardware * configuration of the device such as information on slices, memory, * caches, and so on. It is provided as a table of key / value * attributes. * - %DRM_XE_DEVICE_QUERY_GT_TOPOLOGY * - %DRM_XE_DEVICE_QUERY_ENGINE_CYCLES * * If size is set to 0, the driver fills it with the required size for * the requested type of data to query. If size is equal to the required * size, the queried information is copied into data. If size is set to * a value different from 0 and different from the required size, the * IOCTL call returns -EINVAL. * * For example the following code snippet allows retrieving and printing * information about the device engines with DRM_XE_DEVICE_QUERY_ENGINES: * * .. code-block:: C * * struct drm_xe_query_engines *engines; * struct drm_xe_device_query query = { * .extensions = 0, * .query = DRM_XE_DEVICE_QUERY_ENGINES, * .size = 0, * .data = 0, * }; * ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query); * engines = malloc(query.size); * query.data = (uintptr_t)engines; * ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query); * for (int i = 0; i < engines->num_engines; i++) { * printf("Engine %d: %s\n", i, * engines->engines[i].instance.engine_class == * DRM_XE_ENGINE_CLASS_RENDER ? "RENDER": * engines->engines[i].instance.engine_class == * DRM_XE_ENGINE_CLASS_COPY ? "COPY": * engines->engines[i].instance.engine_class == * DRM_XE_ENGINE_CLASS_VIDEO_DECODE ? "VIDEO_DECODE": * engines->engines[i].instance.engine_class == * DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE ? "VIDEO_ENHANCE": * engines->engines[i].instance.engine_class == * DRM_XE_ENGINE_CLASS_COMPUTE ? "COMPUTE": * "UNKNOWN"); * } * free(engines); */ struct drm_xe_device_query { … }; /** * struct drm_xe_gem_create - Input of &DRM_IOCTL_XE_GEM_CREATE - A structure for * gem creation * * The @flags can be: * - %DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING * - %DRM_XE_GEM_CREATE_FLAG_SCANOUT * - %DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM - When using VRAM as a * possible placement, ensure that the corresponding VRAM allocation * will always use the CPU accessible part of VRAM. This is important * for small-bar systems (on full-bar systems this gets turned into a * noop). * Note1: System memory can be used as an extra placement if the kernel * should spill the allocation to system memory, if space can't be made * available in the CPU accessible part of VRAM (giving the same * behaviour as the i915 interface, see * I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS). * Note2: For clear-color CCS surfaces the kernel needs to read the * clear-color value stored in the buffer, and on discrete platforms we * need to use VRAM for display surfaces, therefore the kernel requires * setting this flag for such objects, otherwise an error is thrown on * small-bar systems. * * @cpu_caching supports the following values: * - %DRM_XE_GEM_CPU_CACHING_WB - Allocate the pages with write-back * caching. On iGPU this can't be used for scanout surfaces. Currently * not allowed for objects placed in VRAM. * - %DRM_XE_GEM_CPU_CACHING_WC - Allocate the pages as write-combined. This * is uncached. Scanout surfaces should likely use this. All objects * that can be placed in VRAM must use this. */ struct drm_xe_gem_create { … }; /** * struct drm_xe_gem_mmap_offset - Input of &DRM_IOCTL_XE_GEM_MMAP_OFFSET */ struct drm_xe_gem_mmap_offset { … }; /** * struct drm_xe_vm_create - Input of &DRM_IOCTL_XE_VM_CREATE * * The @flags can be: * - %DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE * - %DRM_XE_VM_CREATE_FLAG_LR_MODE - An LR, or Long Running VM accepts * exec submissions to its exec_queues that don't have an upper time * limit on the job execution time. But exec submissions to these * don't allow any of the flags DRM_XE_SYNC_FLAG_SYNCOBJ, * DRM_XE_SYNC_FLAG_TIMELINE_SYNCOBJ, DRM_XE_SYNC_FLAG_DMA_BUF, * used as out-syncobjs, that is, together with DRM_XE_SYNC_FLAG_SIGNAL. * LR VMs can be created in recoverable page-fault mode using * DRM_XE_VM_CREATE_FLAG_FAULT_MODE, if the device supports it. * If that flag is omitted, the UMD can not rely on the slightly * different per-VM overcommit semantics that are enabled by * DRM_XE_VM_CREATE_FLAG_FAULT_MODE (see below), but KMD may * still enable recoverable pagefaults if supported by the device. * - %DRM_XE_VM_CREATE_FLAG_FAULT_MODE - Requires also * DRM_XE_VM_CREATE_FLAG_LR_MODE. It allows memory to be allocated on * demand when accessed, and also allows per-VM overcommit of memory. * The xe driver internally uses recoverable pagefaults to implement * this. */ struct drm_xe_vm_create { … }; /** * struct drm_xe_vm_destroy - Input of &DRM_IOCTL_XE_VM_DESTROY */ struct drm_xe_vm_destroy { … }; /** * struct drm_xe_vm_bind_op - run bind operations * * The @op can be: * - %DRM_XE_VM_BIND_OP_MAP * - %DRM_XE_VM_BIND_OP_UNMAP * - %DRM_XE_VM_BIND_OP_MAP_USERPTR * - %DRM_XE_VM_BIND_OP_UNMAP_ALL * - %DRM_XE_VM_BIND_OP_PREFETCH * * and the @flags can be: * - %DRM_XE_VM_BIND_FLAG_READONLY - Setup the page tables as read-only * to ensure write protection * - %DRM_XE_VM_BIND_FLAG_IMMEDIATE - On a faulting VM, do the * MAP operation immediately rather than deferring the MAP to the page * fault handler. This is implied on a non-faulting VM as there is no * fault handler to defer to. * - %DRM_XE_VM_BIND_FLAG_NULL - When the NULL flag is set, the page * tables are setup with a special bit which indicates writes are * dropped and all reads return zero. In the future, the NULL flags * will only be valid for DRM_XE_VM_BIND_OP_MAP operations, the BO * handle MBZ, and the BO offset MBZ. This flag is intended to * implement VK sparse bindings. */ struct drm_xe_vm_bind_op { … }; /** * struct drm_xe_vm_bind - Input of &DRM_IOCTL_XE_VM_BIND * * Below is an example of a minimal use of @drm_xe_vm_bind to * asynchronously bind the buffer `data` at address `BIND_ADDRESS` to * illustrate `userptr`. It can be synchronized by using the example * provided for @drm_xe_sync. * * .. code-block:: C * * data = aligned_alloc(ALIGNMENT, BO_SIZE); * struct drm_xe_vm_bind bind = { * .vm_id = vm, * .num_binds = 1, * .bind.obj = 0, * .bind.obj_offset = to_user_pointer(data), * .bind.range = BO_SIZE, * .bind.addr = BIND_ADDRESS, * .bind.op = DRM_XE_VM_BIND_OP_MAP_USERPTR, * .bind.flags = 0, * .num_syncs = 1, * .syncs = &sync, * .exec_queue_id = 0, * }; * ioctl(fd, DRM_IOCTL_XE_VM_BIND, &bind); * */ struct drm_xe_vm_bind { … }; /** * struct drm_xe_exec_queue_create - Input of &DRM_IOCTL_XE_EXEC_QUEUE_CREATE * * The example below shows how to use @drm_xe_exec_queue_create to create * a simple exec_queue (no parallel submission) of class * &DRM_XE_ENGINE_CLASS_RENDER. * * .. code-block:: C * * struct drm_xe_engine_class_instance instance = { * .engine_class = DRM_XE_ENGINE_CLASS_RENDER, * }; * struct drm_xe_exec_queue_create exec_queue_create = { * .extensions = 0, * .vm_id = vm, * .num_bb_per_exec = 1, * .num_eng_per_bb = 1, * .instances = to_user_pointer(&instance), * }; * ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE, &exec_queue_create); * */ struct drm_xe_exec_queue_create { … }; /** * struct drm_xe_exec_queue_destroy - Input of &DRM_IOCTL_XE_EXEC_QUEUE_DESTROY */ struct drm_xe_exec_queue_destroy { … }; /** * struct drm_xe_exec_queue_get_property - Input of &DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY * * The @property can be: * - %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN */ struct drm_xe_exec_queue_get_property { … }; /** * struct drm_xe_sync - sync object * * The @type can be: * - %DRM_XE_SYNC_TYPE_SYNCOBJ * - %DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ * - %DRM_XE_SYNC_TYPE_USER_FENCE * * and the @flags can be: * - %DRM_XE_SYNC_FLAG_SIGNAL * * A minimal use of @drm_xe_sync looks like this: * * .. code-block:: C * * struct drm_xe_sync sync = { * .flags = DRM_XE_SYNC_FLAG_SIGNAL, * .type = DRM_XE_SYNC_TYPE_SYNCOBJ, * }; * struct drm_syncobj_create syncobj_create = { 0 }; * ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create); * sync.handle = syncobj_create.handle; * ... * use of &sync in drm_xe_exec or drm_xe_vm_bind * ... * struct drm_syncobj_wait wait = { * .handles = &sync.handle, * .timeout_nsec = INT64_MAX, * .count_handles = 1, * .flags = 0, * .first_signaled = 0, * .pad = 0, * }; * ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait); */ struct drm_xe_sync { … }; /** * struct drm_xe_exec - Input of &DRM_IOCTL_XE_EXEC * * This is an example to use @drm_xe_exec for execution of the object * at BIND_ADDRESS (see example in @drm_xe_vm_bind) by an exec_queue * (see example in @drm_xe_exec_queue_create). It can be synchronized * by using the example provided for @drm_xe_sync. * * .. code-block:: C * * struct drm_xe_exec exec = { * .exec_queue_id = exec_queue, * .syncs = &sync, * .num_syncs = 1, * .address = BIND_ADDRESS, * .num_batch_buffer = 1, * }; * ioctl(fd, DRM_IOCTL_XE_EXEC, &exec); * */ struct drm_xe_exec { … }; /** * struct drm_xe_wait_user_fence - Input of &DRM_IOCTL_XE_WAIT_USER_FENCE * * Wait on user fence, XE will wake-up on every HW engine interrupt in the * instances list and check if user fence is complete:: * * (*addr & MASK) OP (VALUE & MASK) * * Returns to user on user fence completion or timeout. * * The @op can be: * - %DRM_XE_UFENCE_WAIT_OP_EQ * - %DRM_XE_UFENCE_WAIT_OP_NEQ * - %DRM_XE_UFENCE_WAIT_OP_GT * - %DRM_XE_UFENCE_WAIT_OP_GTE * - %DRM_XE_UFENCE_WAIT_OP_LT * - %DRM_XE_UFENCE_WAIT_OP_LTE * * and the @flags can be: * - %DRM_XE_UFENCE_WAIT_FLAG_ABSTIME * - %DRM_XE_UFENCE_WAIT_FLAG_SOFT_OP * * The @mask values can be for example: * - 0xffu for u8 * - 0xffffu for u16 * - 0xffffffffu for u32 * - 0xffffffffffffffffu for u64 */ struct drm_xe_wait_user_fence { … }; /** * enum drm_xe_observation_type - Observation stream types */ enum drm_xe_observation_type { … }; /** * enum drm_xe_observation_op - Observation stream ops */ enum drm_xe_observation_op { … }; /** * struct drm_xe_observation_param - Input of &DRM_XE_OBSERVATION * * The observation layer enables multiplexing observation streams of * multiple types. The actual params for a particular stream operation are * supplied via the @param pointer (use __copy_from_user to get these * params). */ struct drm_xe_observation_param { … }; /** * enum drm_xe_observation_ioctls - Observation stream fd ioctl's * * Information exchanged between userspace and kernel for observation fd * ioctl's is stream type specific */ enum drm_xe_observation_ioctls { … }; /** * enum drm_xe_oa_unit_type - OA unit types */ enum drm_xe_oa_unit_type { … }; /** * struct drm_xe_oa_unit - describe OA unit */ struct drm_xe_oa_unit { … }; /** * struct drm_xe_query_oa_units - describe OA units * * If a query is made with a struct drm_xe_device_query where .query * is equal to DRM_XE_DEVICE_QUERY_OA_UNITS, then the reply uses struct * drm_xe_query_oa_units in .data. * * OA unit properties for all OA units can be accessed using a code block * such as the one below: * * .. code-block:: C * * struct drm_xe_query_oa_units *qoa; * struct drm_xe_oa_unit *oau; * u8 *poau; * * // malloc qoa and issue DRM_XE_DEVICE_QUERY_OA_UNITS. Then: * poau = (u8 *)&qoa->oa_units[0]; * for (int i = 0; i < qoa->num_oa_units; i++) { * oau = (struct drm_xe_oa_unit *)poau; * // Access 'struct drm_xe_oa_unit' fields here * poau += sizeof(*oau) + oau->num_engines * sizeof(oau->eci[0]); * } */ struct drm_xe_query_oa_units { … }; /** * enum drm_xe_oa_format_type - OA format types as specified in PRM/Bspec * 52198/60942 */ enum drm_xe_oa_format_type { … }; /** * enum drm_xe_oa_property_id - OA stream property id's * * Stream params are specified as a chain of @drm_xe_ext_set_property * struct's, with @property values from enum @drm_xe_oa_property_id and * @drm_xe_user_extension base.name set to @DRM_XE_OA_EXTENSION_SET_PROPERTY. * @param field in struct @drm_xe_observation_param points to the first * @drm_xe_ext_set_property struct. * * Exactly the same mechanism is also used for stream reconfiguration using the * @DRM_XE_OBSERVATION_IOCTL_CONFIG observation stream fd ioctl, though only a * subset of properties below can be specified for stream reconfiguration. */ enum drm_xe_oa_property_id { … }; /** * struct drm_xe_oa_config - OA metric configuration * * Multiple OA configs can be added using @DRM_XE_OBSERVATION_OP_ADD_CONFIG. A * particular config can be specified when opening an OA stream using * @DRM_XE_OA_PROPERTY_OA_METRIC_SET property. */ struct drm_xe_oa_config { … }; /** * struct drm_xe_oa_stream_status - OA stream status returned from * @DRM_XE_OBSERVATION_IOCTL_STATUS observation stream fd ioctl. Userspace can * call the ioctl to query stream status in response to EIO errno from * observation fd read(). */ struct drm_xe_oa_stream_status { … }; /** * struct drm_xe_oa_stream_info - OA stream info returned from * @DRM_XE_OBSERVATION_IOCTL_INFO observation stream fd ioctl */ struct drm_xe_oa_stream_info { … }; #if defined(__cplusplus) } #endif #endif /* _UAPI_XE_DRM_H_ */