Merge branch 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6] / drivers / gpu / drm / i915 / i915_gem_tiling.c
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/acpi.h>
29 #include <linux/pnp.h>
30 #include "linux/string.h"
31 #include "linux/bitops.h"
32 #include "drmP.h"
33 #include "drm.h"
34 #include "i915_drm.h"
35 #include "i915_drv.h"
36
37 /** @file i915_gem_tiling.c
38  *
39  * Support for managing tiling state of buffer objects.
40  *
41  * The idea behind tiling is to increase cache hit rates by rearranging
42  * pixel data so that a group of pixel accesses are in the same cacheline.
43  * Performance improvement from doing this on the back/depth buffer are on
44  * the order of 30%.
45  *
46  * Intel architectures make this somewhat more complicated, though, by
47  * adjustments made to addressing of data when the memory is in interleaved
48  * mode (matched pairs of DIMMS) to improve memory bandwidth.
49  * For interleaved memory, the CPU sends every sequential 64 bytes
50  * to an alternate memory channel so it can get the bandwidth from both.
51  *
52  * The GPU also rearranges its accesses for increased bandwidth to interleaved
53  * memory, and it matches what the CPU does for non-tiled.  However, when tiled
54  * it does it a little differently, since one walks addresses not just in the
55  * X direction but also Y.  So, along with alternating channels when bit
56  * 6 of the address flips, it also alternates when other bits flip --  Bits 9
57  * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
58  * are common to both the 915 and 965-class hardware.
59  *
60  * The CPU also sometimes XORs in higher bits as well, to improve
61  * bandwidth doing strided access like we do so frequently in graphics.  This
62  * is called "Channel XOR Randomization" in the MCH documentation.  The result
63  * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
64  * decode.
65  *
66  * All of this bit 6 XORing has an effect on our memory management,
67  * as we need to make sure that the 3d driver can correctly address object
68  * contents.
69  *
70  * If we don't have interleaved memory, all tiling is safe and no swizzling is
71  * required.
72  *
73  * When bit 17 is XORed in, we simply refuse to tile at all.  Bit
74  * 17 is not just a page offset, so as we page an objet out and back in,
75  * individual pages in it will have different bit 17 addresses, resulting in
76  * each 64 bytes being swapped with its neighbor!
77  *
78  * Otherwise, if interleaved, we have to tell the 3d driver what the address
79  * swizzling it needs to do is, since it's writing with the CPU to the pages
80  * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
81  * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
82  * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
83  * to match what the GPU expects.
84  */
85
86 #define MCHBAR_I915 0x44
87 #define MCHBAR_I965 0x48
88 #define MCHBAR_SIZE (4*4096)
89
90 #define DEVEN_REG 0x54
91 #define   DEVEN_MCHBAR_EN (1 << 28)
92
93 /* Allocate space for the MCH regs if needed, return nonzero on error */
94 static int
95 intel_alloc_mchbar_resource(struct drm_device *dev)
96 {
97         struct pci_dev *bridge_dev;
98         drm_i915_private_t *dev_priv = dev->dev_private;
99         int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
100         u32 temp_lo, temp_hi = 0;
101         u64 mchbar_addr;
102         int ret = 0;
103
104         bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
105         if (!bridge_dev) {
106                 DRM_DEBUG("no bridge dev?!\n");
107                 ret = -ENODEV;
108                 goto out;
109         }
110
111         if (IS_I965G(dev))
112                 pci_read_config_dword(bridge_dev, reg + 4, &temp_hi);
113         pci_read_config_dword(bridge_dev, reg, &temp_lo);
114         mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
115
116         /* If ACPI doesn't have it, assume we need to allocate it ourselves */
117 #ifdef CONFIG_PNP
118         if (mchbar_addr &&
119             pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
120                 ret = 0;
121                 goto out_put;
122         }
123 #endif
124
125         /* Get some space for it */
126         ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res,
127                                      MCHBAR_SIZE, MCHBAR_SIZE,
128                                      PCIBIOS_MIN_MEM,
129                                      0,   pcibios_align_resource,
130                                      bridge_dev);
131         if (ret) {
132                 DRM_DEBUG("failed bus alloc: %d\n", ret);
133                 dev_priv->mch_res.start = 0;
134                 goto out_put;
135         }
136
137         if (IS_I965G(dev))
138                 pci_write_config_dword(bridge_dev, reg + 4,
139                                        upper_32_bits(dev_priv->mch_res.start));
140
141         pci_write_config_dword(bridge_dev, reg,
142                                lower_32_bits(dev_priv->mch_res.start));
143 out_put:
144         pci_dev_put(bridge_dev);
145 out:
146         return ret;
147 }
148
149 /* Setup MCHBAR if possible, return true if we should disable it again */
150 static bool
151 intel_setup_mchbar(struct drm_device *dev)
152 {
153         struct pci_dev *bridge_dev;
154         int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
155         u32 temp;
156         bool need_disable = false, enabled;
157
158         bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
159         if (!bridge_dev) {
160                 DRM_DEBUG("no bridge dev?!\n");
161                 goto out;
162         }
163
164         if (IS_I915G(dev) || IS_I915GM(dev)) {
165                 pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
166                 enabled = !!(temp & DEVEN_MCHBAR_EN);
167         } else {
168                 pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
169                 enabled = temp & 1;
170         }
171
172         /* If it's already enabled, don't have to do anything */
173         if (enabled)
174                 goto out_put;
175
176         if (intel_alloc_mchbar_resource(dev))
177                 goto out_put;
178
179         need_disable = true;
180
181         /* Space is allocated or reserved, so enable it. */
182         if (IS_I915G(dev) || IS_I915GM(dev)) {
183                 pci_write_config_dword(bridge_dev, DEVEN_REG,
184                                        temp | DEVEN_MCHBAR_EN);
185         } else {
186                 pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
187                 pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1);
188         }
189 out_put:
190         pci_dev_put(bridge_dev);
191 out:
192         return need_disable;
193 }
194
195 static void
196 intel_teardown_mchbar(struct drm_device *dev, bool disable)
197 {
198         drm_i915_private_t *dev_priv = dev->dev_private;
199         struct pci_dev *bridge_dev;
200         int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
201         u32 temp;
202
203         bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
204         if (!bridge_dev) {
205                 DRM_DEBUG("no bridge dev?!\n");
206                 return;
207         }
208
209         if (disable) {
210                 if (IS_I915G(dev) || IS_I915GM(dev)) {
211                         pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
212                         temp &= ~DEVEN_MCHBAR_EN;
213                         pci_write_config_dword(bridge_dev, DEVEN_REG, temp);
214                 } else {
215                         pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
216                         temp &= ~1;
217                         pci_write_config_dword(bridge_dev, mchbar_reg, temp);
218                 }
219         }
220
221         if (dev_priv->mch_res.start)
222                 release_resource(&dev_priv->mch_res);
223 }
224
225 /**
226  * Detects bit 6 swizzling of address lookup between IGD access and CPU
227  * access through main memory.
228  */
229 void
230 i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
231 {
232         drm_i915_private_t *dev_priv = dev->dev_private;
233         uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
234         uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
235         bool need_disable;
236
237         if (!IS_I9XX(dev)) {
238                 /* As far as we know, the 865 doesn't have these bit 6
239                  * swizzling issues.
240                  */
241                 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
242                 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
243         } else if (IS_MOBILE(dev)) {
244                 uint32_t dcc;
245
246                 /* Try to make sure MCHBAR is enabled before poking at it */
247                 need_disable = intel_setup_mchbar(dev);
248
249                 /* On mobile 9xx chipsets, channel interleave by the CPU is
250                  * determined by DCC.  For single-channel, neither the CPU
251                  * nor the GPU do swizzling.  For dual channel interleaved,
252                  * the GPU's interleave is bit 9 and 10 for X tiled, and bit
253                  * 9 for Y tiled.  The CPU's interleave is independent, and
254                  * can be based on either bit 11 (haven't seen this yet) or
255                  * bit 17 (common).
256                  */
257                 dcc = I915_READ(DCC);
258                 switch (dcc & DCC_ADDRESSING_MODE_MASK) {
259                 case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
260                 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
261                         swizzle_x = I915_BIT_6_SWIZZLE_NONE;
262                         swizzle_y = I915_BIT_6_SWIZZLE_NONE;
263                         break;
264                 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
265                         if (dcc & DCC_CHANNEL_XOR_DISABLE) {
266                                 /* This is the base swizzling by the GPU for
267                                  * tiled buffers.
268                                  */
269                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
270                                 swizzle_y = I915_BIT_6_SWIZZLE_9;
271                         } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
272                                 /* Bit 11 swizzling by the CPU in addition. */
273                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
274                                 swizzle_y = I915_BIT_6_SWIZZLE_9_11;
275                         } else {
276                                 /* Bit 17 swizzling by the CPU in addition. */
277                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
278                                 swizzle_y = I915_BIT_6_SWIZZLE_9_17;
279                         }
280                         break;
281                 }
282                 if (dcc == 0xffffffff) {
283                         DRM_ERROR("Couldn't read from MCHBAR.  "
284                                   "Disabling tiling.\n");
285                         swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
286                         swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
287                 }
288
289                 intel_teardown_mchbar(dev, need_disable);
290         } else {
291                 /* The 965, G33, and newer, have a very flexible memory
292                  * configuration.  It will enable dual-channel mode
293                  * (interleaving) on as much memory as it can, and the GPU
294                  * will additionally sometimes enable different bit 6
295                  * swizzling for tiled objects from the CPU.
296                  *
297                  * Here's what I found on the G965:
298                  *    slot fill         memory size  swizzling
299                  * 0A   0B   1A   1B    1-ch   2-ch
300                  * 512  0    0    0     512    0     O
301                  * 512  0    512  0     16     1008  X
302                  * 512  0    0    512   16     1008  X
303                  * 0    512  0    512   16     1008  X
304                  * 1024 1024 1024 0     2048   1024  O
305                  *
306                  * We could probably detect this based on either the DRB
307                  * matching, which was the case for the swizzling required in
308                  * the table above, or from the 1-ch value being less than
309                  * the minimum size of a rank.
310                  */
311                 if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
312                         swizzle_x = I915_BIT_6_SWIZZLE_NONE;
313                         swizzle_y = I915_BIT_6_SWIZZLE_NONE;
314                 } else {
315                         swizzle_x = I915_BIT_6_SWIZZLE_9_10;
316                         swizzle_y = I915_BIT_6_SWIZZLE_9;
317                 }
318         }
319
320         /* FIXME: check with memory config on IGDNG */
321         if (IS_IGDNG(dev)) {
322                 DRM_ERROR("disable tiling on IGDNG...\n");
323                 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
324                 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
325         }
326
327         dev_priv->mm.bit_6_swizzle_x = swizzle_x;
328         dev_priv->mm.bit_6_swizzle_y = swizzle_y;
329 }
330
331
332 /**
333  * Returns the size of the fence for a tiled object of the given size.
334  */
335 static int
336 i915_get_fence_size(struct drm_device *dev, int size)
337 {
338         int i;
339         int start;
340
341         if (IS_I965G(dev)) {
342                 /* The 965 can have fences at any page boundary. */
343                 return ALIGN(size, 4096);
344         } else {
345                 /* Align the size to a power of two greater than the smallest
346                  * fence size.
347                  */
348                 if (IS_I9XX(dev))
349                         start = 1024 * 1024;
350                 else
351                         start = 512 * 1024;
352
353                 for (i = start; i < size; i <<= 1)
354                         ;
355
356                 return i;
357         }
358 }
359
360 /* Check pitch constriants for all chips & tiling formats */
361 static bool
362 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
363 {
364         int tile_width;
365
366         /* Linear is always fine */
367         if (tiling_mode == I915_TILING_NONE)
368                 return true;
369
370         if (!IS_I9XX(dev) ||
371             (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
372                 tile_width = 128;
373         else
374                 tile_width = 512;
375
376         /* check maximum stride & object size */
377         if (IS_I965G(dev)) {
378                 /* i965 stores the end address of the gtt mapping in the fence
379                  * reg, so dont bother to check the size */
380                 if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
381                         return false;
382         } else if (IS_I9XX(dev)) {
383                 uint32_t pitch_val = ffs(stride / tile_width) - 1;
384
385                 /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
386                  * instead of 4 (2KB) on 945s.
387                  */
388                 if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
389                     size > (I830_FENCE_MAX_SIZE_VAL << 20))
390                         return false;
391         } else {
392                 uint32_t pitch_val = ffs(stride / tile_width) - 1;
393
394                 if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
395                     size > (I830_FENCE_MAX_SIZE_VAL << 19))
396                         return false;
397         }
398
399         /* 965+ just needs multiples of tile width */
400         if (IS_I965G(dev)) {
401                 if (stride & (tile_width - 1))
402                         return false;
403                 return true;
404         }
405
406         /* Pre-965 needs power of two tile widths */
407         if (stride < tile_width)
408                 return false;
409
410         if (stride & (stride - 1))
411                 return false;
412
413         /* We don't 0handle the aperture area covered by the fence being bigger
414          * than the object size.
415          */
416         if (i915_get_fence_size(dev, size) != size)
417                 return false;
418
419         return true;
420 }
421
422 static bool
423 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
424 {
425         struct drm_device *dev = obj->dev;
426         struct drm_i915_gem_object *obj_priv = obj->driver_private;
427
428         if (obj_priv->gtt_space == NULL)
429                 return true;
430
431         if (tiling_mode == I915_TILING_NONE)
432                 return true;
433
434         if (!IS_I965G(dev)) {
435                 if (obj_priv->gtt_offset & (obj->size - 1))
436                         return false;
437                 if (IS_I9XX(dev)) {
438                         if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK)
439                                 return false;
440                 } else {
441                         if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK)
442                                 return false;
443                 }
444         }
445
446         return true;
447 }
448
449 /**
450  * Sets the tiling mode of an object, returning the required swizzling of
451  * bit 6 of addresses in the object.
452  */
453 int
454 i915_gem_set_tiling(struct drm_device *dev, void *data,
455                    struct drm_file *file_priv)
456 {
457         struct drm_i915_gem_set_tiling *args = data;
458         drm_i915_private_t *dev_priv = dev->dev_private;
459         struct drm_gem_object *obj;
460         struct drm_i915_gem_object *obj_priv;
461         int ret = 0;
462
463         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
464         if (obj == NULL)
465                 return -EINVAL;
466         obj_priv = obj->driver_private;
467
468         if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
469                 mutex_lock(&dev->struct_mutex);
470                 drm_gem_object_unreference(obj);
471                 mutex_unlock(&dev->struct_mutex);
472                 return -EINVAL;
473         }
474
475         if (args->tiling_mode == I915_TILING_NONE) {
476                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
477                 args->stride = 0;
478         } else {
479                 if (args->tiling_mode == I915_TILING_X)
480                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
481                 else
482                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
483
484                 /* Hide bit 17 swizzling from the user.  This prevents old Mesa
485                  * from aborting the application on sw fallbacks to bit 17,
486                  * and we use the pread/pwrite bit17 paths to swizzle for it.
487                  * If there was a user that was relying on the swizzle
488                  * information for drm_intel_bo_map()ed reads/writes this would
489                  * break it, but we don't have any of those.
490                  */
491                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
492                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
493                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
494                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
495
496                 /* If we can't handle the swizzling, make it untiled. */
497                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
498                         args->tiling_mode = I915_TILING_NONE;
499                         args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
500                         args->stride = 0;
501                 }
502         }
503
504         mutex_lock(&dev->struct_mutex);
505         if (args->tiling_mode != obj_priv->tiling_mode ||
506             args->stride != obj_priv->stride) {
507                 /* We need to rebind the object if its current allocation
508                  * no longer meets the alignment restrictions for its new
509                  * tiling mode. Otherwise we can just leave it alone, but
510                  * need to ensure that any fence register is cleared.
511                  */
512                 if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
513                     ret = i915_gem_object_unbind(obj);
514                 else
515                     ret = i915_gem_object_put_fence_reg(obj);
516                 if (ret != 0) {
517                         WARN(ret != -ERESTARTSYS,
518                              "failed to reset object for tiling switch");
519                         args->tiling_mode = obj_priv->tiling_mode;
520                         args->stride = obj_priv->stride;
521                         goto err;
522                 }
523
524                 obj_priv->tiling_mode = args->tiling_mode;
525                 obj_priv->stride = args->stride;
526         }
527 err:
528         drm_gem_object_unreference(obj);
529         mutex_unlock(&dev->struct_mutex);
530
531         return ret;
532 }
533
534 /**
535  * Returns the current tiling mode and required bit 6 swizzling for the object.
536  */
537 int
538 i915_gem_get_tiling(struct drm_device *dev, void *data,
539                    struct drm_file *file_priv)
540 {
541         struct drm_i915_gem_get_tiling *args = data;
542         drm_i915_private_t *dev_priv = dev->dev_private;
543         struct drm_gem_object *obj;
544         struct drm_i915_gem_object *obj_priv;
545
546         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
547         if (obj == NULL)
548                 return -EINVAL;
549         obj_priv = obj->driver_private;
550
551         mutex_lock(&dev->struct_mutex);
552
553         args->tiling_mode = obj_priv->tiling_mode;
554         switch (obj_priv->tiling_mode) {
555         case I915_TILING_X:
556                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
557                 break;
558         case I915_TILING_Y:
559                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
560                 break;
561         case I915_TILING_NONE:
562                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
563                 break;
564         default:
565                 DRM_ERROR("unknown tiling mode\n");
566         }
567
568         /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
569         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
570                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
571         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
572                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
573
574         drm_gem_object_unreference(obj);
575         mutex_unlock(&dev->struct_mutex);
576
577         return 0;
578 }
579
580 /**
581  * Swap every 64 bytes of this page around, to account for it having a new
582  * bit 17 of its physical address and therefore being interpreted differently
583  * by the GPU.
584  */
585 static int
586 i915_gem_swizzle_page(struct page *page)
587 {
588         char *vaddr;
589         int i;
590         char temp[64];
591
592         vaddr = kmap(page);
593         if (vaddr == NULL)
594                 return -ENOMEM;
595
596         for (i = 0; i < PAGE_SIZE; i += 128) {
597                 memcpy(temp, &vaddr[i], 64);
598                 memcpy(&vaddr[i], &vaddr[i + 64], 64);
599                 memcpy(&vaddr[i + 64], temp, 64);
600         }
601
602         kunmap(page);
603
604         return 0;
605 }
606
607 void
608 i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
609 {
610         struct drm_device *dev = obj->dev;
611         drm_i915_private_t *dev_priv = dev->dev_private;
612         struct drm_i915_gem_object *obj_priv = obj->driver_private;
613         int page_count = obj->size >> PAGE_SHIFT;
614         int i;
615
616         if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
617                 return;
618
619         if (obj_priv->bit_17 == NULL)
620                 return;
621
622         for (i = 0; i < page_count; i++) {
623                 char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17;
624                 if ((new_bit_17 & 0x1) !=
625                     (test_bit(i, obj_priv->bit_17) != 0)) {
626                         int ret = i915_gem_swizzle_page(obj_priv->pages[i]);
627                         if (ret != 0) {
628                                 DRM_ERROR("Failed to swizzle page\n");
629                                 return;
630                         }
631                         set_page_dirty(obj_priv->pages[i]);
632                 }
633         }
634 }
635
636 void
637 i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
638 {
639         struct drm_device *dev = obj->dev;
640         drm_i915_private_t *dev_priv = dev->dev_private;
641         struct drm_i915_gem_object *obj_priv = obj->driver_private;
642         int page_count = obj->size >> PAGE_SHIFT;
643         int i;
644
645         if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
646                 return;
647
648         if (obj_priv->bit_17 == NULL) {
649                 obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
650                                            sizeof(long), GFP_KERNEL);
651                 if (obj_priv->bit_17 == NULL) {
652                         DRM_ERROR("Failed to allocate memory for bit 17 "
653                                   "record\n");
654                         return;
655                 }
656         }
657
658         for (i = 0; i < page_count; i++) {
659                 if (page_to_phys(obj_priv->pages[i]) & (1 << 17))
660                         __set_bit(i, obj_priv->bit_17);
661                 else
662                         __clear_bit(i, obj_priv->bit_17);
663         }
664 }