1 /*
2 * Copyright © 2023 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23 #include "xe/intel_engine.h"
24
25 #include <stdlib.h>
26
27 #include "common/intel_gem.h"
28 #include "common/xe/intel_device_query.h"
29
30 #include "drm-uapi/xe_drm.h"
31
32 static enum intel_engine_class
xe_engine_class_to_intel(uint16_t xe)33 xe_engine_class_to_intel(uint16_t xe)
34 {
35 switch (xe) {
36 case DRM_XE_ENGINE_CLASS_RENDER:
37 return INTEL_ENGINE_CLASS_RENDER;
38 case DRM_XE_ENGINE_CLASS_COPY:
39 return INTEL_ENGINE_CLASS_COPY;
40 case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
41 return INTEL_ENGINE_CLASS_VIDEO;
42 case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
43 return INTEL_ENGINE_CLASS_VIDEO_ENHANCE;
44 case DRM_XE_ENGINE_CLASS_COMPUTE:
45 return INTEL_ENGINE_CLASS_COMPUTE;
46 default:
47 return INTEL_ENGINE_CLASS_INVALID;
48 }
49 }
50
51 uint16_t
intel_engine_class_to_xe(enum intel_engine_class intel)52 intel_engine_class_to_xe(enum intel_engine_class intel)
53 {
54 switch (intel) {
55 case INTEL_ENGINE_CLASS_RENDER:
56 return DRM_XE_ENGINE_CLASS_RENDER;
57 case INTEL_ENGINE_CLASS_COPY:
58 return DRM_XE_ENGINE_CLASS_COPY;
59 case INTEL_ENGINE_CLASS_VIDEO:
60 return DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
61 case INTEL_ENGINE_CLASS_VIDEO_ENHANCE:
62 return DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
63 case INTEL_ENGINE_CLASS_COMPUTE:
64 return DRM_XE_ENGINE_CLASS_COMPUTE;
65 default:
66 return -1;
67 }
68 }
69
70 struct intel_query_engine_info *
xe_engine_get_info(int fd)71 xe_engine_get_info(int fd)
72 {
73 struct drm_xe_query_engines *xe_engines;
74
75 xe_engines = xe_device_query_alloc_fetch(fd, DRM_XE_DEVICE_QUERY_ENGINES, NULL);
76 if (!xe_engines)
77 return NULL;
78
79 struct intel_query_engine_info *intel_engines_info;
80 intel_engines_info = calloc(1, sizeof(*intel_engines_info) +
81 sizeof(*intel_engines_info->engines) *
82 xe_engines->num_engines);
83 if (!intel_engines_info) {
84 goto error_free_xe_engines;
85 return NULL;
86 }
87
88 for (uint32_t i = 0; i < xe_engines->num_engines; i++) {
89 struct drm_xe_engine_class_instance *xe_engine = &xe_engines->engines[i].instance;
90 struct intel_engine_class_instance *intel_engine = &intel_engines_info->engines[i];
91
92 intel_engine->engine_class = xe_engine_class_to_intel(xe_engine->engine_class);
93 intel_engine->engine_instance = xe_engine->engine_instance;
94 intel_engine->gt_id = xe_engine->gt_id;
95 }
96
97 intel_engines_info->num_engines = xe_engines->num_engines;
98 free(xe_engines);
99 return intel_engines_info;
100
101 error_free_xe_engines:
102 free(xe_engines);
103 return NULL;
104 }
105
106 bool
xe_engines_is_guc_semaphore_functional(int fd,const struct intel_device_info * info)107 xe_engines_is_guc_semaphore_functional(int fd, const struct intel_device_info *info)
108 {
109 struct drm_xe_query_uc_fw_version uc_fw_version = {
110 .uc_type = XE_QUERY_UC_TYPE_GUC_SUBMISSION,
111 };
112 struct drm_xe_device_query query = {
113 .query = DRM_XE_DEVICE_QUERY_UC_FW_VERSION,
114 .data = (uintptr_t)&uc_fw_version,
115 .size = sizeof(uc_fw_version)
116 };
117 uint32_t read_ver, min_ver;
118
119 if (intel_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query))
120 return false;
121
122 /* branch == 0 is mainline branch, any other branch value indicates that
123 * other version numbers cannot be used to infer whether features or fixes
124 * are present in the release.
125 *
126 * major, minor and patch are u8 for GuC, uAPI have it as u32 because of HuC.
127 */
128 if (uc_fw_version.branch_ver == 0) {
129 read_ver = uc_fw_version.major_ver << 16;
130 read_ver |= uc_fw_version.minor_ver << 8;
131 read_ver |= uc_fw_version.patch_ver;
132 } else {
133 read_ver = 0;
134 }
135
136 /* Requires at least GuC submission version 1.1.3 */
137 min_ver = 1ULL << 16 | 1ULL << 8 | 3;
138
139 return read_ver >= min_ver;
140 }
141