@@ -2724,6 +2724,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_GEM_ENGINE_INFO, i915_gem_engine_info_ioctl, DRM_RENDER_ALLOW),
};
static struct drm_driver driver = {
@@ -3598,6 +3598,9 @@ void i915_oa_init_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
uint32_t *reg_state);
+int i915_gem_engine_info_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
+
/* i915_gem_evict.c */
int __must_check i915_gem_evict_something(struct i915_address_space *vm,
u64 min_size, u64 alignment,
@@ -25,6 +25,7 @@
#include "i915_drv.h"
#include "intel_ringbuffer.h"
#include "intel_lrc.h"
+#include <uapi/drm/i915_drm.h>
/* Haswell does have the CXT_SIZE register however it does not appear to be
* valid. Now, docs explain in dwords what is in the context object. The full
@@ -1332,6 +1333,69 @@ void intel_engines_mark_idle(struct drm_i915_private *i915)
}
}
+static u8 user_class_map[I915_ENGINE_CLASS_MAX] = {
+ [I915_ENGINE_CLASS_OTHER] = OTHER_CLASS,
+ [I915_ENGINE_CLASS_RENDER] = RENDER_CLASS,
+ [I915_ENGINE_CLASS_COPY] = COPY_ENGINE_CLASS,
+ [I915_ENGINE_CLASS_VIDEO] = VIDEO_DECODE_CLASS,
+ [I915_ENGINE_CLASS_VIDEO_ENHANCE] = VIDEO_ENHANCEMENT_CLASS,
+};
+
+int i915_gem_engine_info_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_private *i915 = to_i915(dev);
+ struct drm_i915_gem_engine_info *args = data;
+ struct drm_i915_engine_info __user *user_info =
+ u64_to_user_ptr(args->info_ptr);
+ unsigned int info_size = args->num_engines;
+ struct drm_i915_engine_info info;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+ u8 class;
+
+ if (args->rsvd)
+ return -EINVAL;
+
+ switch (args->engine_class) {
+ case I915_ENGINE_CLASS_OTHER:
+ case I915_ENGINE_CLASS_RENDER:
+ case I915_ENGINE_CLASS_COPY:
+ case I915_ENGINE_CLASS_VIDEO:
+ case I915_ENGINE_CLASS_VIDEO_ENHANCE:
+ class = user_class_map[args->engine_class];
+ break;
+ case I915_ENGINE_CLASS_MAX:
+ default:
+ return -EINVAL;
+ };
+
+ args->num_engines = 0;
+
+ for_each_engine(engine, i915, id) {
+ if (class != engine->class)
+ continue;
+
+ if (++args->num_engines > info_size)
+ continue;
+
+ if (args->version != 1)
+ continue;
+
+ memset(&info, 0, sizeof(info));
+ info.instance = engine->instance;
+ if (INTEL_GEN(i915) >= 8 && id == VCS)
+ info.info = I915_VCS_HAS_HEVC;
+
+ if (copy_to_user(user_info++, &info, sizeof(info)))
+ return -EFAULT;
+ }
+
+ args->version = 1;
+
+ return 0;
+}
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/mock_engine.c"
#endif
@@ -260,6 +260,7 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_GEM_ENGINE_INFO 0x37
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -315,6 +316,7 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_GEM_ENGINE_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_ENGINE_INFO, struct drm_i915_gem_engine_info)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -1467,6 +1469,45 @@ enum drm_i915_perf_record_type {
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
+enum drm_i915_gem_engine_class {
+ I915_ENGINE_CLASS_OTHER = 0,
+ I915_ENGINE_CLASS_RENDER = 1,
+ I915_ENGINE_CLASS_COPY = 2,
+ I915_ENGINE_CLASS_VIDEO = 3,
+ I915_ENGINE_CLASS_VIDEO_ENHANCE = 4,
+ I915_ENGINE_CLASS_MAX /* non-ABI */
+};
+
+struct drm_i915_engine_info {
+ /** Engine instance number. */
+ __u8 instance;
+
+ /** Engine specific info. */
+#define I915_VCS_HAS_HEVC BIT(0)
+ __u8 info;
+
+ __u8 rsvd2[6];
+};
+
+struct drm_i915_gem_engine_info {
+ /** in/out: Protocol version requested/supported. */
+ __u32 version;
+
+ /** in: Engine class to probe (enum drm_i915_gem_engine_class). */
+ __u32 engine_class;
+
+ /**
+ * in/out: Number of struct drm_i915_engine_info entries in the provided
+ * @info_ptr array and actual number of supported hardware engines.
+ */
+ __u32 num_engines;
+ __u32 rsvd;
+
+ /** in/out: Pointer to array of struct i915_engine_info elements. */
+ __u64 info_ptr;
+
+};
+
#if defined(__cplusplus)
}
#endif