xref: /dflybsd-src/sys/dev/drm/i915/i915_gem_tiling.c (revision 303bf2704d314de5be18baeedb8cdc82d3f944de)
1e3adcf8fSFrançois Tigeot /*
2e3adcf8fSFrançois Tigeot  * Copyright © 2008 Intel Corporation
3e3adcf8fSFrançois Tigeot  *
4e3adcf8fSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
5e3adcf8fSFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
6e3adcf8fSFrançois Tigeot  * to deal in the Software without restriction, including without limitation
7e3adcf8fSFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e3adcf8fSFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
9e3adcf8fSFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
10e3adcf8fSFrançois Tigeot  *
11e3adcf8fSFrançois Tigeot  * The above copyright notice and this permission notice (including the next
12e3adcf8fSFrançois Tigeot  * paragraph) shall be included in all copies or substantial portions of the
13e3adcf8fSFrançois Tigeot  * Software.
14e3adcf8fSFrançois Tigeot  *
15e3adcf8fSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16e3adcf8fSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17e3adcf8fSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18e3adcf8fSFrançois Tigeot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19e3adcf8fSFrançois Tigeot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20e3adcf8fSFrançois Tigeot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21e3adcf8fSFrançois Tigeot  * IN THE SOFTWARE.
22e3adcf8fSFrançois Tigeot  *
23e3adcf8fSFrançois Tigeot  * Authors:
24e3adcf8fSFrançois Tigeot  *    Eric Anholt <eric@anholt.net>
25e3adcf8fSFrançois Tigeot  *
26e3adcf8fSFrançois Tigeot  */
27e3adcf8fSFrançois Tigeot 
281487f786SFrançois Tigeot #include <linux/string.h>
29e3440f96SFrançois Tigeot #include <linux/bitops.h>
3018e26a6dSFrançois Tigeot #include <drm/drmP.h>
315c6c6f23SFrançois Tigeot #include <drm/i915_drm.h>
32e3adcf8fSFrançois Tigeot #include "i915_drv.h"
33e3adcf8fSFrançois Tigeot 
34e3adcf8fSFrançois Tigeot /**
35a05eeebfSFrançois Tigeot  * DOC: buffer object tiling
361b13d190SFrançois Tigeot  *
37a05eeebfSFrançois Tigeot  * i915_gem_set_tiling() and i915_gem_get_tiling() is the userspace interface to
38a05eeebfSFrançois Tigeot  * declare fence register requirements.
39e3adcf8fSFrançois Tigeot  *
40a05eeebfSFrançois Tigeot  * In principle GEM doesn't care at all about the internal data layout of an
41a05eeebfSFrançois Tigeot  * object, and hence it also doesn't care about tiling or swizzling. There's two
42a05eeebfSFrançois Tigeot  * exceptions:
43e3adcf8fSFrançois Tigeot  *
44a05eeebfSFrançois Tigeot  * - For X and Y tiling the hardware provides detilers for CPU access, so called
45a05eeebfSFrançois Tigeot  *   fences. Since there's only a limited amount of them the kernel must manage
46a05eeebfSFrançois Tigeot  *   these, and therefore userspace must tell the kernel the object tiling if it
47a05eeebfSFrançois Tigeot  *   wants to use fences for detiling.
48a05eeebfSFrançois Tigeot  * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which
49a05eeebfSFrançois Tigeot  *   depends upon the physical page frame number. When swapping such objects the
50a05eeebfSFrançois Tigeot  *   page frame number might change and the kernel must be able to fix this up
51a05eeebfSFrançois Tigeot  *   and hence now the tiling. Note that on a subset of platforms with
52a05eeebfSFrançois Tigeot  *   asymmetric memory channel population the swizzling pattern changes in an
53a05eeebfSFrançois Tigeot  *   unknown way, and for those the kernel simply forbids swapping completely.
54a05eeebfSFrançois Tigeot  *
55a05eeebfSFrançois Tigeot  * Since neither of this applies for new tiling layouts on modern platforms like
56a05eeebfSFrançois Tigeot  * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled.
57a05eeebfSFrançois Tigeot  * Anything else can be handled in userspace entirely without the kernel's
58a05eeebfSFrançois Tigeot  * invovlement.
59e3adcf8fSFrançois Tigeot  */
60e3adcf8fSFrançois Tigeot 
61e3adcf8fSFrançois Tigeot /* Check pitch constriants for all chips & tiling formats */
62e3adcf8fSFrançois Tigeot static bool
63e3adcf8fSFrançois Tigeot i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
64e3adcf8fSFrançois Tigeot {
65e3adcf8fSFrançois Tigeot 	int tile_width;
66e3adcf8fSFrançois Tigeot 
67e3adcf8fSFrançois Tigeot 	/* Linear is always fine */
68e3adcf8fSFrançois Tigeot 	if (tiling_mode == I915_TILING_NONE)
69e9243325SFrançois Tigeot 		return true;
70e3adcf8fSFrançois Tigeot 
71e3adcf8fSFrançois Tigeot 	if (IS_GEN2(dev) ||
72e3adcf8fSFrançois Tigeot 	    (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
73e3adcf8fSFrançois Tigeot 		tile_width = 128;
74e3adcf8fSFrançois Tigeot 	else
75e3adcf8fSFrançois Tigeot 		tile_width = 512;
76e3adcf8fSFrançois Tigeot 
77e3adcf8fSFrançois Tigeot 	/* check maximum stride & object size */
788e26cdf6SFrançois Tigeot 	/* i965+ stores the end address of the gtt mapping in the fence
79e3adcf8fSFrançois Tigeot 	 * reg, so dont bother to check the size */
808e26cdf6SFrançois Tigeot 	if (INTEL_INFO(dev)->gen >= 7) {
818e26cdf6SFrançois Tigeot 		if (stride / 128 > GEN7_FENCE_MAX_PITCH_VAL)
828e26cdf6SFrançois Tigeot 			return false;
838e26cdf6SFrançois Tigeot 	} else if (INTEL_INFO(dev)->gen >= 4) {
84e3adcf8fSFrançois Tigeot 		if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
85e9243325SFrançois Tigeot 			return false;
86e3adcf8fSFrançois Tigeot 	} else {
87e3adcf8fSFrançois Tigeot 		if (stride > 8192)
88e9243325SFrançois Tigeot 			return false;
89e3adcf8fSFrançois Tigeot 
90e3adcf8fSFrançois Tigeot 		if (IS_GEN3(dev)) {
91e3adcf8fSFrançois Tigeot 			if (size > I830_FENCE_MAX_SIZE_VAL << 20)
92e9243325SFrançois Tigeot 				return false;
93e3adcf8fSFrançois Tigeot 		} else {
94e3adcf8fSFrançois Tigeot 			if (size > I830_FENCE_MAX_SIZE_VAL << 19)
95e9243325SFrançois Tigeot 				return false;
96e3adcf8fSFrançois Tigeot 		}
97e3adcf8fSFrançois Tigeot 	}
98e3adcf8fSFrançois Tigeot 
998e26cdf6SFrançois Tigeot 	if (stride < tile_width)
1008e26cdf6SFrançois Tigeot 		return false;
1018e26cdf6SFrançois Tigeot 
102e3adcf8fSFrançois Tigeot 	/* 965+ just needs multiples of tile width */
103e3adcf8fSFrançois Tigeot 	if (INTEL_INFO(dev)->gen >= 4) {
104e3adcf8fSFrançois Tigeot 		if (stride & (tile_width - 1))
105e9243325SFrançois Tigeot 			return false;
106e9243325SFrançois Tigeot 		return true;
107e3adcf8fSFrançois Tigeot 	}
108e3adcf8fSFrançois Tigeot 
109e3adcf8fSFrançois Tigeot 	/* Pre-965 needs power of two tile widths */
110e3adcf8fSFrançois Tigeot 	if (stride & (stride - 1))
111e9243325SFrançois Tigeot 		return false;
112e3adcf8fSFrançois Tigeot 
113e9243325SFrançois Tigeot 	return true;
114e3adcf8fSFrançois Tigeot }
115e3adcf8fSFrançois Tigeot 
116e3adcf8fSFrançois Tigeot /* Is the current GTT allocation valid for the change in tiling? */
117e3adcf8fSFrançois Tigeot static bool
118e3adcf8fSFrançois Tigeot i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
119e3adcf8fSFrançois Tigeot {
120e3adcf8fSFrançois Tigeot 	u32 size;
121e3adcf8fSFrançois Tigeot 
122e3adcf8fSFrançois Tigeot 	if (tiling_mode == I915_TILING_NONE)
123e9243325SFrançois Tigeot 		return true;
124e3adcf8fSFrançois Tigeot 
125e3adcf8fSFrançois Tigeot 	if (INTEL_INFO(obj->base.dev)->gen >= 4)
126e9243325SFrançois Tigeot 		return true;
127e3adcf8fSFrançois Tigeot 
1281487f786SFrançois Tigeot 	if (IS_GEN3(obj->base.dev)) {
1299edbd4a0SFrançois Tigeot 		if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
130e9243325SFrançois Tigeot 			return false;
131e3adcf8fSFrançois Tigeot 	} else {
1329edbd4a0SFrançois Tigeot 		if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK)
133e9243325SFrançois Tigeot 			return false;
134e3adcf8fSFrançois Tigeot 	}
135e3adcf8fSFrançois Tigeot 
136a2fdbec6SFrançois Tigeot 	size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode);
1379edbd4a0SFrançois Tigeot 	if (i915_gem_obj_ggtt_size(obj) != size)
138e9243325SFrançois Tigeot 		return false;
139e3adcf8fSFrançois Tigeot 
1409edbd4a0SFrançois Tigeot 	if (i915_gem_obj_ggtt_offset(obj) & (size - 1))
141e9243325SFrançois Tigeot 		return false;
142e3adcf8fSFrançois Tigeot 
143e9243325SFrançois Tigeot 	return true;
144e3adcf8fSFrançois Tigeot }
145e3adcf8fSFrançois Tigeot 
146e3adcf8fSFrançois Tigeot /**
147a05eeebfSFrançois Tigeot  * i915_gem_set_tiling - IOCTL handler to set tiling mode
148a05eeebfSFrançois Tigeot  * @dev: DRM device
149a05eeebfSFrançois Tigeot  * @data: data pointer for the ioctl
150a05eeebfSFrançois Tigeot  * @file: DRM file for the ioctl call
151a05eeebfSFrançois Tigeot  *
152e3adcf8fSFrançois Tigeot  * Sets the tiling mode of an object, returning the required swizzling of
153e3adcf8fSFrançois Tigeot  * bit 6 of addresses in the object.
154a05eeebfSFrançois Tigeot  *
155a05eeebfSFrançois Tigeot  * Called by the user via ioctl.
156a05eeebfSFrançois Tigeot  *
157a05eeebfSFrançois Tigeot  * Returns:
158a05eeebfSFrançois Tigeot  * Zero on success, negative errno on failure.
159e3adcf8fSFrançois Tigeot  */
160e3adcf8fSFrançois Tigeot int
161e3adcf8fSFrançois Tigeot i915_gem_set_tiling(struct drm_device *dev, void *data,
162e3adcf8fSFrançois Tigeot 		   struct drm_file *file)
163e3adcf8fSFrançois Tigeot {
164e3adcf8fSFrançois Tigeot 	struct drm_i915_gem_set_tiling *args = data;
165*303bf270SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
166e3adcf8fSFrançois Tigeot 	struct drm_i915_gem_object *obj;
167e9243325SFrançois Tigeot 	int ret = 0;
168e3adcf8fSFrançois Tigeot 
1698621f407SFrançois Tigeot 	obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
170e3adcf8fSFrançois Tigeot 	if (&obj->base == NULL)
171e3adcf8fSFrançois Tigeot 		return -ENOENT;
172e3adcf8fSFrançois Tigeot 
173e3adcf8fSFrançois Tigeot 	if (!i915_tiling_ok(dev,
174e3adcf8fSFrançois Tigeot 			    args->stride, obj->base.size, args->tiling_mode)) {
175f192107fSFrançois Tigeot 		drm_gem_object_unreference_unlocked(&obj->base);
176e3adcf8fSFrançois Tigeot 		return -EINVAL;
177e3adcf8fSFrançois Tigeot 	}
178e3adcf8fSFrançois Tigeot 
179aee94f86SFrançois Tigeot 	intel_runtime_pm_get(dev_priv);
180aee94f86SFrançois Tigeot 
1812c9916cdSFrançois Tigeot 	mutex_lock(&dev->struct_mutex);
18219c468b4SFrançois Tigeot 	if (obj->pin_display || obj->framebuffer_references) {
1832c9916cdSFrançois Tigeot 		ret = -EBUSY;
1842c9916cdSFrançois Tigeot 		goto err;
185e3adcf8fSFrançois Tigeot 	}
186e3adcf8fSFrançois Tigeot 
187e3adcf8fSFrançois Tigeot 	if (args->tiling_mode == I915_TILING_NONE) {
188e3adcf8fSFrançois Tigeot 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
189e3adcf8fSFrançois Tigeot 		args->stride = 0;
190e3adcf8fSFrançois Tigeot 	} else {
191e3adcf8fSFrançois Tigeot 		if (args->tiling_mode == I915_TILING_X)
192e3adcf8fSFrançois Tigeot 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
193e3adcf8fSFrançois Tigeot 		else
194e3adcf8fSFrançois Tigeot 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
195e3adcf8fSFrançois Tigeot 
196e3adcf8fSFrançois Tigeot 		/* Hide bit 17 swizzling from the user.  This prevents old Mesa
197e3adcf8fSFrançois Tigeot 		 * from aborting the application on sw fallbacks to bit 17,
198e3adcf8fSFrançois Tigeot 		 * and we use the pread/pwrite bit17 paths to swizzle for it.
199e3adcf8fSFrançois Tigeot 		 * If there was a user that was relying on the swizzle
200e3adcf8fSFrançois Tigeot 		 * information for drm_intel_bo_map()ed reads/writes this would
201e3adcf8fSFrançois Tigeot 		 * break it, but we don't have any of those.
202e3adcf8fSFrançois Tigeot 		 */
203e3adcf8fSFrançois Tigeot 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
204e3adcf8fSFrançois Tigeot 			args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
205e3adcf8fSFrançois Tigeot 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
206e3adcf8fSFrançois Tigeot 			args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
207e3adcf8fSFrançois Tigeot 
208e3adcf8fSFrançois Tigeot 		/* If we can't handle the swizzling, make it untiled. */
209e3adcf8fSFrançois Tigeot 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
210e3adcf8fSFrançois Tigeot 			args->tiling_mode = I915_TILING_NONE;
211e3adcf8fSFrançois Tigeot 			args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
212e3adcf8fSFrançois Tigeot 			args->stride = 0;
213e3adcf8fSFrançois Tigeot 		}
214e3adcf8fSFrançois Tigeot 	}
215e3adcf8fSFrançois Tigeot 
216e3adcf8fSFrançois Tigeot 	if (args->tiling_mode != obj->tiling_mode ||
217e3adcf8fSFrançois Tigeot 	    args->stride != obj->stride) {
218e3adcf8fSFrançois Tigeot 		/* We need to rebind the object if its current allocation
219e3adcf8fSFrançois Tigeot 		 * no longer meets the alignment restrictions for its new
220e3adcf8fSFrançois Tigeot 		 * tiling mode. Otherwise we can just leave it alone, but
221e3440f96SFrançois Tigeot 		 * need to ensure that any fence register is updated before
222e3440f96SFrançois Tigeot 		 * the next fenced (either through the GTT or by the BLT unit
223e3440f96SFrançois Tigeot 		 * on older GPUs) access.
224e9243325SFrançois Tigeot 		 *
225e9243325SFrançois Tigeot 		 * After updating the tiling parameters, we then flag whether
226e9243325SFrançois Tigeot 		 * we need to update an associated fence register. Note this
227e9243325SFrançois Tigeot 		 * has to also include the unfenced register the GPU uses
228e9243325SFrançois Tigeot 		 * whilst executing a fenced command for an untiled object.
229e3adcf8fSFrançois Tigeot 		 */
2301b13d190SFrançois Tigeot 		if (obj->map_and_fenceable &&
2311b13d190SFrançois Tigeot 		    !i915_gem_object_fence_ok(obj, args->tiling_mode))
2321487f786SFrançois Tigeot 			ret = i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
233f192107fSFrançois Tigeot 
234e3adcf8fSFrançois Tigeot 		if (ret == 0) {
2352c9916cdSFrançois Tigeot 			if (obj->pages &&
2362c9916cdSFrançois Tigeot 			    obj->madv == I915_MADV_WILLNEED &&
2372c9916cdSFrançois Tigeot 			    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
2382c9916cdSFrançois Tigeot 				if (args->tiling_mode == I915_TILING_NONE)
2392c9916cdSFrançois Tigeot 					i915_gem_object_unpin_pages(obj);
2402c9916cdSFrançois Tigeot 				if (obj->tiling_mode == I915_TILING_NONE)
2412c9916cdSFrançois Tigeot 					i915_gem_object_pin_pages(obj);
2422c9916cdSFrançois Tigeot 			}
2432c9916cdSFrançois Tigeot 
244f192107fSFrançois Tigeot 			obj->fence_dirty =
2452c9916cdSFrançois Tigeot 				obj->last_fenced_req ||
246f192107fSFrançois Tigeot 				obj->fence_reg != I915_FENCE_REG_NONE;
247f192107fSFrançois Tigeot 
248e3adcf8fSFrançois Tigeot 			obj->tiling_mode = args->tiling_mode;
249e3adcf8fSFrançois Tigeot 			obj->stride = args->stride;
250e3440f96SFrançois Tigeot 
251e3440f96SFrançois Tigeot 			/* Force the fence to be reacquired for GTT access */
252e3440f96SFrançois Tigeot 			i915_gem_release_mmap(obj);
253e3adcf8fSFrançois Tigeot 		}
254e3adcf8fSFrançois Tigeot 	}
255e3adcf8fSFrançois Tigeot 	/* we have to maintain this existing ABI... */
256e3adcf8fSFrançois Tigeot 	args->stride = obj->stride;
257e3adcf8fSFrançois Tigeot 	args->tiling_mode = obj->tiling_mode;
258a2fdbec6SFrançois Tigeot 
259a2fdbec6SFrançois Tigeot 	/* Try to preallocate memory required to save swizzling on put-pages */
260a2fdbec6SFrançois Tigeot 	if (i915_gem_object_needs_bit17_swizzle(obj)) {
261a2fdbec6SFrançois Tigeot 		if (obj->bit_17 == NULL) {
26222ee5efbSFrançois Tigeot 			obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
26322ee5efbSFrançois Tigeot 					      sizeof(long), GFP_KERNEL);
264a2fdbec6SFrançois Tigeot 		}
265a2fdbec6SFrançois Tigeot 	} else {
2669edbd4a0SFrançois Tigeot 		kfree(obj->bit_17);
267a2fdbec6SFrançois Tigeot 		obj->bit_17 = NULL;
268a2fdbec6SFrançois Tigeot 	}
269a2fdbec6SFrançois Tigeot 
2702c9916cdSFrançois Tigeot err:
271e3adcf8fSFrançois Tigeot 	drm_gem_object_unreference(&obj->base);
272a2fdbec6SFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
273e3adcf8fSFrançois Tigeot 
274aee94f86SFrançois Tigeot 	intel_runtime_pm_put(dev_priv);
275aee94f86SFrançois Tigeot 
276e9243325SFrançois Tigeot 	return ret;
277e3adcf8fSFrançois Tigeot }
278e3adcf8fSFrançois Tigeot 
279e3adcf8fSFrançois Tigeot /**
280a05eeebfSFrançois Tigeot  * i915_gem_get_tiling - IOCTL handler to get tiling mode
281a05eeebfSFrançois Tigeot  * @dev: DRM device
282a05eeebfSFrançois Tigeot  * @data: data pointer for the ioctl
283a05eeebfSFrançois Tigeot  * @file: DRM file for the ioctl call
284a05eeebfSFrançois Tigeot  *
285e3adcf8fSFrançois Tigeot  * Returns the current tiling mode and required bit 6 swizzling for the object.
286a05eeebfSFrançois Tigeot  *
287a05eeebfSFrançois Tigeot  * Called by the user via ioctl.
288a05eeebfSFrançois Tigeot  *
289a05eeebfSFrançois Tigeot  * Returns:
290a05eeebfSFrançois Tigeot  * Zero on success, negative errno on failure.
291e3adcf8fSFrançois Tigeot  */
292e3adcf8fSFrançois Tigeot int
293e3adcf8fSFrançois Tigeot i915_gem_get_tiling(struct drm_device *dev, void *data,
294e3adcf8fSFrançois Tigeot 		   struct drm_file *file)
295e3adcf8fSFrançois Tigeot {
296e3adcf8fSFrançois Tigeot 	struct drm_i915_gem_get_tiling *args = data;
297*303bf270SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
298e3adcf8fSFrançois Tigeot 	struct drm_i915_gem_object *obj;
299e3adcf8fSFrançois Tigeot 
3008621f407SFrançois Tigeot 	obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
301e3adcf8fSFrançois Tigeot 	if (&obj->base == NULL)
302e3adcf8fSFrançois Tigeot 		return -ENOENT;
303e3adcf8fSFrançois Tigeot 
304a2fdbec6SFrançois Tigeot 	mutex_lock(&dev->struct_mutex);
305283d6aceSFrançois Tigeot 
306e3adcf8fSFrançois Tigeot 	args->tiling_mode = obj->tiling_mode;
307e3adcf8fSFrançois Tigeot 	switch (obj->tiling_mode) {
308e3adcf8fSFrançois Tigeot 	case I915_TILING_X:
309e3adcf8fSFrançois Tigeot 		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
310e3adcf8fSFrançois Tigeot 		break;
311e3adcf8fSFrançois Tigeot 	case I915_TILING_Y:
312e3adcf8fSFrançois Tigeot 		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
313e3adcf8fSFrançois Tigeot 		break;
314e3adcf8fSFrançois Tigeot 	case I915_TILING_NONE:
315e3adcf8fSFrançois Tigeot 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
316e3adcf8fSFrançois Tigeot 		break;
317e3adcf8fSFrançois Tigeot 	default:
318e3adcf8fSFrançois Tigeot 		DRM_ERROR("unknown tiling mode\n");
319e3adcf8fSFrançois Tigeot 	}
320e3adcf8fSFrançois Tigeot 
321e3adcf8fSFrançois Tigeot 	/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
32219c468b4SFrançois Tigeot 	if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
32319c468b4SFrançois Tigeot 		args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
32419c468b4SFrançois Tigeot 	else
3252c9916cdSFrançois Tigeot 		args->phys_swizzle_mode = args->swizzle_mode;
326e3adcf8fSFrançois Tigeot 	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
327e3adcf8fSFrançois Tigeot 		args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
328e3adcf8fSFrançois Tigeot 	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
329e3adcf8fSFrançois Tigeot 		args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
330e3adcf8fSFrançois Tigeot 
331e3adcf8fSFrançois Tigeot 	drm_gem_object_unreference(&obj->base);
332a2fdbec6SFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
333e3adcf8fSFrançois Tigeot 
334e3adcf8fSFrançois Tigeot 	return 0;
335e3adcf8fSFrançois Tigeot }
336