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 "i915/iris_bufmgr.h"
24
25 #include "common/intel_gem.h"
26 #include "intel/dev/intel_debug.h"
27 #include "iris/iris_bufmgr.h"
28
29 #include "drm-uapi/i915_drm.h"
30
31 #define FILE_DEBUG_FLAG DEBUG_BUFMGR
32
iris_i915_bo_busy_gem(struct iris_bo * bo)33 bool iris_i915_bo_busy_gem(struct iris_bo *bo)
34 {
35 assert(iris_bo_is_real(bo));
36
37 struct iris_bufmgr *bufmgr = bo->bufmgr;
38 struct drm_i915_gem_busy busy = { .handle = bo->gem_handle };
39
40 if (intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_I915_GEM_BUSY, &busy))
41 return false;
42
43 return busy.busy;
44 }
45
iris_i915_bo_wait_gem(struct iris_bo * bo,int64_t timeout_ns)46 int iris_i915_bo_wait_gem(struct iris_bo *bo, int64_t timeout_ns)
47 {
48 assert(iris_bo_is_real(bo));
49
50 struct iris_bufmgr *bufmgr = bo->bufmgr;
51 struct drm_i915_gem_wait wait = {
52 .bo_handle = bo->gem_handle,
53 .timeout_ns = timeout_ns,
54 };
55
56 if (intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_I915_GEM_WAIT, &wait))
57 return -errno;
58
59 return 0;
60 }
61
iris_i915_init_global_vm(struct iris_bufmgr * bufmgr,uint32_t * vm_id)62 bool iris_i915_init_global_vm(struct iris_bufmgr *bufmgr, uint32_t *vm_id)
63 {
64 uint64_t value;
65 bool ret = intel_gem_get_context_param(iris_bufmgr_get_fd(bufmgr), 0,
66 I915_CONTEXT_PARAM_VM, &value);
67 if (ret)
68 *vm_id = value;
69 return ret;
70 }
71
iris_i915_bo_get_tiling(struct iris_bo * bo,uint32_t * tiling)72 int iris_i915_bo_get_tiling(struct iris_bo *bo, uint32_t *tiling)
73 {
74 struct iris_bufmgr *bufmgr = bo->bufmgr;
75 struct drm_i915_gem_get_tiling ti = { .handle = bo->gem_handle };
76 int ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_I915_GEM_GET_TILING, &ti);
77
78 if (ret) {
79 DBG("gem_get_tiling failed for BO %u: %s\n",
80 bo->gem_handle, strerror(errno));
81 }
82
83 *tiling = ti.tiling_mode;
84
85 return ret;
86 }
87
iris_i915_bo_set_tiling(struct iris_bo * bo,const struct isl_surf * surf)88 int iris_i915_bo_set_tiling(struct iris_bo *bo, const struct isl_surf *surf)
89 {
90 struct iris_bufmgr *bufmgr = bo->bufmgr;
91 uint32_t tiling_mode = isl_tiling_to_i915_tiling(surf->tiling);
92 int ret;
93
94 /* GEM_SET_TILING is slightly broken and overwrites the input on the
95 * error path, so we have to open code intel_ioctl().
96 */
97 struct drm_i915_gem_set_tiling set_tiling = {
98 .handle = bo->gem_handle,
99 .tiling_mode = tiling_mode,
100 .stride = surf->row_pitch_B,
101 };
102
103 ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
104 if (ret) {
105 DBG("gem_set_tiling failed for BO %u: %s\n",
106 bo->gem_handle, strerror(errno));
107 }
108
109 return ret;
110 }
111
112 uint64_t
iris_i915_tiling_to_modifier(uint32_t tiling)113 iris_i915_tiling_to_modifier(uint32_t tiling)
114 {
115 static const uint64_t map[] = {
116 [I915_TILING_NONE] = DRM_FORMAT_MOD_LINEAR,
117 [I915_TILING_X] = I915_FORMAT_MOD_X_TILED,
118 [I915_TILING_Y] = I915_FORMAT_MOD_Y_TILED,
119 };
120
121 assert(tiling < ARRAY_SIZE(map));
122
123 return map[tiling];
124 }
125