xref: /aosp_15_r20/external/mesa3d/src/intel/common/xe/intel_engine.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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