xref: /dragonfly/sys/dev/drm/i915/i915_gem_tiling.c (revision 2ea2781e)
1 /*
2  * Copyright © 2008 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  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27 
28 #include <linux/string.h>
29 #include <linux/bitops.h>
30 #include <drm/drmP.h>
31 #include <drm/i915_drm.h>
32 #include "i915_drv.h"
33 
34 /**
35  * DOC: buffer object tiling
36  *
37  * i915_gem_set_tiling() and i915_gem_get_tiling() is the userspace interface to
38  * declare fence register requirements.
39  *
40  * In principle GEM doesn't care at all about the internal data layout of an
41  * object, and hence it also doesn't care about tiling or swizzling. There's two
42  * exceptions:
43  *
44  * - For X and Y tiling the hardware provides detilers for CPU access, so called
45  *   fences. Since there's only a limited amount of them the kernel must manage
46  *   these, and therefore userspace must tell the kernel the object tiling if it
47  *   wants to use fences for detiling.
48  * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which
49  *   depends upon the physical page frame number. When swapping such objects the
50  *   page frame number might change and the kernel must be able to fix this up
51  *   and hence now the tiling. Note that on a subset of platforms with
52  *   asymmetric memory channel population the swizzling pattern changes in an
53  *   unknown way, and for those the kernel simply forbids swapping completely.
54  *
55  * Since neither of this applies for new tiling layouts on modern platforms like
56  * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled.
57  * Anything else can be handled in userspace entirely without the kernel's
58  * invovlement.
59  */
60 
61 /* Check pitch constriants for all chips & tiling formats */
62 static bool
63 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
64 {
65 	int tile_width;
66 
67 	/* Linear is always fine */
68 	if (tiling_mode == I915_TILING_NONE)
69 		return true;
70 
71 	if (tiling_mode > I915_TILING_LAST)
72 		return false;
73 
74 	if (IS_GEN2(dev) ||
75 	    (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
76 		tile_width = 128;
77 	else
78 		tile_width = 512;
79 
80 	/* check maximum stride & object size */
81 	/* i965+ stores the end address of the gtt mapping in the fence
82 	 * reg, so dont bother to check the size */
83 	if (INTEL_INFO(dev)->gen >= 7) {
84 		if (stride / 128 > GEN7_FENCE_MAX_PITCH_VAL)
85 			return false;
86 	} else if (INTEL_INFO(dev)->gen >= 4) {
87 		if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
88 			return false;
89 	} else {
90 		if (stride > 8192)
91 			return false;
92 
93 		if (IS_GEN3(dev)) {
94 			if (size > I830_FENCE_MAX_SIZE_VAL << 20)
95 				return false;
96 		} else {
97 			if (size > I830_FENCE_MAX_SIZE_VAL << 19)
98 				return false;
99 		}
100 	}
101 
102 	if (stride < tile_width)
103 		return false;
104 
105 	/* 965+ just needs multiples of tile width */
106 	if (INTEL_INFO(dev)->gen >= 4) {
107 		if (stride & (tile_width - 1))
108 			return false;
109 		return true;
110 	}
111 
112 	/* Pre-965 needs power of two tile widths */
113 	if (stride & (stride - 1))
114 		return false;
115 
116 	return true;
117 }
118 
119 /* Is the current GTT allocation valid for the change in tiling? */
120 static bool
121 i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
122 {
123 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
124 	u32 size;
125 
126 	if (tiling_mode == I915_TILING_NONE)
127 		return true;
128 
129 	if (INTEL_GEN(dev_priv) >= 4)
130 		return true;
131 
132 	if (IS_GEN3(dev_priv)) {
133 		if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
134 			return false;
135 	} else {
136 		if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK)
137 			return false;
138 	}
139 
140 	size = i915_gem_get_ggtt_size(dev_priv, obj->base.size, tiling_mode);
141 	if (i915_gem_obj_ggtt_size(obj) != size)
142 		return false;
143 
144 	if (i915_gem_obj_ggtt_offset(obj) & (size - 1))
145 		return false;
146 
147 	return true;
148 }
149 
150 /**
151  * i915_gem_set_tiling - IOCTL handler to set tiling mode
152  * @dev: DRM device
153  * @data: data pointer for the ioctl
154  * @file: DRM file for the ioctl call
155  *
156  * Sets the tiling mode of an object, returning the required swizzling of
157  * bit 6 of addresses in the object.
158  *
159  * Called by the user via ioctl.
160  *
161  * Returns:
162  * Zero on success, negative errno on failure.
163  */
164 int
165 i915_gem_set_tiling(struct drm_device *dev, void *data,
166 		   struct drm_file *file)
167 {
168 	struct drm_i915_gem_set_tiling *args = data;
169 	struct drm_i915_private *dev_priv = to_i915(dev);
170 	struct drm_i915_gem_object *obj;
171 	int ret = 0;
172 
173 	/* Make sure we don't cross-contaminate obj->tiling_and_stride */
174 	BUILD_BUG_ON(I915_TILING_LAST & STRIDE_MASK);
175 
176 	obj = i915_gem_object_lookup(file, args->handle);
177 	if (!obj)
178 		return -ENOENT;
179 
180 	if (!i915_tiling_ok(dev,
181 			    args->stride, obj->base.size, args->tiling_mode)) {
182 		i915_gem_object_put_unlocked(obj);
183 		return -EINVAL;
184 	}
185 
186 	intel_runtime_pm_get(dev_priv);
187 
188 	mutex_lock(&dev->struct_mutex);
189 	if (obj->pin_display || obj->framebuffer_references) {
190 		ret = -EBUSY;
191 		goto err;
192 	}
193 
194 	if (args->tiling_mode == I915_TILING_NONE) {
195 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
196 		args->stride = 0;
197 	} else {
198 		if (args->tiling_mode == I915_TILING_X)
199 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
200 		else
201 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
202 
203 		/* Hide bit 17 swizzling from the user.  This prevents old Mesa
204 		 * from aborting the application on sw fallbacks to bit 17,
205 		 * and we use the pread/pwrite bit17 paths to swizzle for it.
206 		 * If there was a user that was relying on the swizzle
207 		 * information for drm_intel_bo_map()ed reads/writes this would
208 		 * break it, but we don't have any of those.
209 		 */
210 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
211 			args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
212 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
213 			args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
214 
215 		/* If we can't handle the swizzling, make it untiled. */
216 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
217 			args->tiling_mode = I915_TILING_NONE;
218 			args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
219 			args->stride = 0;
220 		}
221 	}
222 
223 	if (args->tiling_mode != i915_gem_object_get_tiling(obj) ||
224 	    args->stride != i915_gem_object_get_stride(obj)) {
225 		/* We need to rebind the object if its current allocation
226 		 * no longer meets the alignment restrictions for its new
227 		 * tiling mode. Otherwise we can just leave it alone, but
228 		 * need to ensure that any fence register is updated before
229 		 * the next fenced (either through the GTT or by the BLT unit
230 		 * on older GPUs) access.
231 		 *
232 		 * After updating the tiling parameters, we then flag whether
233 		 * we need to update an associated fence register. Note this
234 		 * has to also include the unfenced register the GPU uses
235 		 * whilst executing a fenced command for an untiled object.
236 		 */
237 		if (obj->map_and_fenceable &&
238 		    !i915_gem_object_fence_ok(obj, args->tiling_mode))
239 			ret = i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
240 
241 		if (ret == 0) {
242 			if (obj->pages &&
243 			    obj->madv == I915_MADV_WILLNEED &&
244 			    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
245 				if (args->tiling_mode == I915_TILING_NONE)
246 					i915_gem_object_unpin_pages(obj);
247 				if (!i915_gem_object_is_tiled(obj))
248 					i915_gem_object_pin_pages(obj);
249 			}
250 
251 			obj->fence_dirty =
252 				!i915_gem_active_is_idle(&obj->last_fence,
253 							 &dev->struct_mutex) ||
254 				obj->fence_reg != I915_FENCE_REG_NONE;
255 
256 			obj->tiling_and_stride =
257 				args->stride | args->tiling_mode;
258 
259 			/* Force the fence to be reacquired for GTT access */
260 			i915_gem_release_mmap(obj);
261 		}
262 	}
263 	/* we have to maintain this existing ABI... */
264 	args->stride = i915_gem_object_get_stride(obj);
265 	args->tiling_mode = i915_gem_object_get_tiling(obj);
266 
267 	/* Try to preallocate memory required to save swizzling on put-pages */
268 	if (i915_gem_object_needs_bit17_swizzle(obj)) {
269 		if (obj->bit_17 == NULL) {
270 			obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
271 					      sizeof(long), GFP_KERNEL);
272 		}
273 	} else {
274 		kfree(obj->bit_17);
275 		obj->bit_17 = NULL;
276 	}
277 
278 err:
279 	i915_gem_object_put(obj);
280 	mutex_unlock(&dev->struct_mutex);
281 
282 	intel_runtime_pm_put(dev_priv);
283 
284 	return ret;
285 }
286 
287 /**
288  * i915_gem_get_tiling - IOCTL handler to get tiling mode
289  * @dev: DRM device
290  * @data: data pointer for the ioctl
291  * @file: DRM file for the ioctl call
292  *
293  * Returns the current tiling mode and required bit 6 swizzling for the object.
294  *
295  * Called by the user via ioctl.
296  *
297  * Returns:
298  * Zero on success, negative errno on failure.
299  */
300 int
301 i915_gem_get_tiling(struct drm_device *dev, void *data,
302 		   struct drm_file *file)
303 {
304 	struct drm_i915_gem_get_tiling *args = data;
305 	struct drm_i915_private *dev_priv = to_i915(dev);
306 	struct drm_i915_gem_object *obj;
307 
308 	obj = i915_gem_object_lookup(file, args->handle);
309 	if (!obj)
310 		return -ENOENT;
311 
312 	args->tiling_mode = READ_ONCE(obj->tiling_and_stride) & TILING_MASK;
313 	switch (args->tiling_mode) {
314 	case I915_TILING_X:
315 		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
316 		break;
317 	case I915_TILING_Y:
318 		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
319 		break;
320 	case I915_TILING_NONE:
321 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
322 		break;
323 	default:
324 		DRM_ERROR("unknown tiling mode\n");
325 	}
326 
327 	/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
328 	if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
329 		args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
330 	else
331 		args->phys_swizzle_mode = args->swizzle_mode;
332 	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
333 		args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
334 	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
335 		args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
336 
337 	i915_gem_object_put_unlocked(obj);
338 	return 0;
339 }
340