drm/i915: fix tiling on IGDNG
[safe/jmp/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_IGDNG(dev)) {
238                 /* On IGDNG whatever DRAM config, GPU always do
239                  * same swizzling setup.
240                  */
241                 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
242                 swizzle_y = I915_BIT_6_SWIZZLE_9;
243         } else if (!IS_I9XX(dev)) {
244                 /* As far as we know, the 865 doesn't have these bit 6
245                  * swizzling issues.
246                  */
247                 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
248                 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
249         } else if (IS_MOBILE(dev)) {
250                 uint32_t dcc;
251
252                 /* Try to make sure MCHBAR is enabled before poking at it */
253                 need_disable = intel_setup_mchbar(dev);
254
255                 /* On mobile 9xx chipsets, channel interleave by the CPU is
256                  * determined by DCC.  For single-channel, neither the CPU
257                  * nor the GPU do swizzling.  For dual channel interleaved,
258                  * the GPU's interleave is bit 9 and 10 for X tiled, and bit
259                  * 9 for Y tiled.  The CPU's interleave is independent, and
260                  * can be based on either bit 11 (haven't seen this yet) or
261                  * bit 17 (common).
262                  */
263                 dcc = I915_READ(DCC);
264                 switch (dcc & DCC_ADDRESSING_MODE_MASK) {
265                 case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
266                 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
267                         swizzle_x = I915_BIT_6_SWIZZLE_NONE;
268                         swizzle_y = I915_BIT_6_SWIZZLE_NONE;
269                         break;
270                 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
271                         if (dcc & DCC_CHANNEL_XOR_DISABLE) {
272                                 /* This is the base swizzling by the GPU for
273                                  * tiled buffers.
274                                  */
275                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
276                                 swizzle_y = I915_BIT_6_SWIZZLE_9;
277                         } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
278                                 /* Bit 11 swizzling by the CPU in addition. */
279                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
280                                 swizzle_y = I915_BIT_6_SWIZZLE_9_11;
281                         } else {
282                                 /* Bit 17 swizzling by the CPU in addition. */
283                                 swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
284                                 swizzle_y = I915_BIT_6_SWIZZLE_9_17;
285                         }
286                         break;
287                 }
288                 if (dcc == 0xffffffff) {
289                         DRM_ERROR("Couldn't read from MCHBAR.  "
290                                   "Disabling tiling.\n");
291                         swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
292                         swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
293                 }
294
295                 intel_teardown_mchbar(dev, need_disable);
296         } else {
297                 /* The 965, G33, and newer, have a very flexible memory
298                  * configuration.  It will enable dual-channel mode
299                  * (interleaving) on as much memory as it can, and the GPU
300                  * will additionally sometimes enable different bit 6
301                  * swizzling for tiled objects from the CPU.
302                  *
303                  * Here's what I found on the G965:
304                  *    slot fill         memory size  swizzling
305                  * 0A   0B   1A   1B    1-ch   2-ch
306                  * 512  0    0    0     512    0     O
307                  * 512  0    512  0     16     1008  X
308                  * 512  0    0    512   16     1008  X
309                  * 0    512  0    512   16     1008  X
310                  * 1024 1024 1024 0     2048   1024  O
311                  *
312                  * We could probably detect this based on either the DRB
313                  * matching, which was the case for the swizzling required in
314                  * the table above, or from the 1-ch value being less than
315                  * the minimum size of a rank.
316                  */
317                 if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
318                         swizzle_x = I915_BIT_6_SWIZZLE_NONE;
319                         swizzle_y = I915_BIT_6_SWIZZLE_NONE;
320                 } else {
321                         swizzle_x = I915_BIT_6_SWIZZLE_9_10;
322                         swizzle_y = I915_BIT_6_SWIZZLE_9;
323                 }
324         }
325
326         dev_priv->mm.bit_6_swizzle_x = swizzle_x;
327         dev_priv->mm.bit_6_swizzle_y = swizzle_y;
328 }
329
330
331 /**
332  * Returns the size of the fence for a tiled object of the given size.
333  */
334 static int
335 i915_get_fence_size(struct drm_device *dev, int size)
336 {
337         int i;
338         int start;
339
340         if (IS_I965G(dev)) {
341                 /* The 965 can have fences at any page boundary. */
342                 return ALIGN(size, 4096);
343         } else {
344                 /* Align the size to a power of two greater than the smallest
345                  * fence size.
346                  */
347                 if (IS_I9XX(dev))
348                         start = 1024 * 1024;
349                 else
350                         start = 512 * 1024;
351
352                 for (i = start; i < size; i <<= 1)
353                         ;
354
355                 return i;
356         }
357 }
358
359 /* Check pitch constriants for all chips & tiling formats */
360 static bool
361 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
362 {
363         int tile_width;
364
365         /* Linear is always fine */
366         if (tiling_mode == I915_TILING_NONE)
367                 return true;
368
369         if (!IS_I9XX(dev) ||
370             (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
371                 tile_width = 128;
372         else
373                 tile_width = 512;
374
375         /* check maximum stride & object size */
376         if (IS_I965G(dev)) {
377                 /* i965 stores the end address of the gtt mapping in the fence
378                  * reg, so dont bother to check the size */
379                 if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
380                         return false;
381         } else if (IS_I9XX(dev)) {
382                 uint32_t pitch_val = ffs(stride / tile_width) - 1;
383
384                 /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
385                  * instead of 4 (2KB) on 945s.
386                  */
387                 if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
388                     size > (I830_FENCE_MAX_SIZE_VAL << 20))
389                         return false;
390         } else {
391                 uint32_t pitch_val = ffs(stride / tile_width) - 1;
392
393                 if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
394                     size > (I830_FENCE_MAX_SIZE_VAL << 19))
395                         return false;
396         }
397
398         /* 965+ just needs multiples of tile width */
399         if (IS_I965G(dev)) {
400                 if (stride & (tile_width - 1))
401                         return false;
402                 return true;
403         }
404
405         /* Pre-965 needs power of two tile widths */
406         if (stride < tile_width)
407                 return false;
408
409         if (stride & (stride - 1))
410                 return false;
411
412         /* We don't 0handle the aperture area covered by the fence being bigger
413          * than the object size.
414          */
415         if (i915_get_fence_size(dev, size) != size)
416                 return false;
417
418         return true;
419 }
420
421 static bool
422 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
423 {
424         struct drm_device *dev = obj->dev;
425         struct drm_i915_gem_object *obj_priv = obj->driver_private;
426
427         if (obj_priv->gtt_space == NULL)
428                 return true;
429
430         if (tiling_mode == I915_TILING_NONE)
431                 return true;
432
433         if (!IS_I965G(dev)) {
434                 if (obj_priv->gtt_offset & (obj->size - 1))
435                         return false;
436                 if (IS_I9XX(dev)) {
437                         if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK)
438                                 return false;
439                 } else {
440                         if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK)
441                                 return false;
442                 }
443         }
444
445         return true;
446 }
447
448 /**
449  * Sets the tiling mode of an object, returning the required swizzling of
450  * bit 6 of addresses in the object.
451  */
452 int
453 i915_gem_set_tiling(struct drm_device *dev, void *data,
454                    struct drm_file *file_priv)
455 {
456         struct drm_i915_gem_set_tiling *args = data;
457         drm_i915_private_t *dev_priv = dev->dev_private;
458         struct drm_gem_object *obj;
459         struct drm_i915_gem_object *obj_priv;
460         int ret = 0;
461
462         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
463         if (obj == NULL)
464                 return -EINVAL;
465         obj_priv = obj->driver_private;
466
467         if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
468                 mutex_lock(&dev->struct_mutex);
469                 drm_gem_object_unreference(obj);
470                 mutex_unlock(&dev->struct_mutex);
471                 return -EINVAL;
472         }
473
474         if (args->tiling_mode == I915_TILING_NONE) {
475                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
476                 args->stride = 0;
477         } else {
478                 if (args->tiling_mode == I915_TILING_X)
479                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
480                 else
481                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
482
483                 /* Hide bit 17 swizzling from the user.  This prevents old Mesa
484                  * from aborting the application on sw fallbacks to bit 17,
485                  * and we use the pread/pwrite bit17 paths to swizzle for it.
486                  * If there was a user that was relying on the swizzle
487                  * information for drm_intel_bo_map()ed reads/writes this would
488                  * break it, but we don't have any of those.
489                  */
490                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
491                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
492                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
493                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
494
495                 /* If we can't handle the swizzling, make it untiled. */
496                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
497                         args->tiling_mode = I915_TILING_NONE;
498                         args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
499                         args->stride = 0;
500                 }
501         }
502
503         mutex_lock(&dev->struct_mutex);
504         if (args->tiling_mode != obj_priv->tiling_mode ||
505             args->stride != obj_priv->stride) {
506                 /* We need to rebind the object if its current allocation
507                  * no longer meets the alignment restrictions for its new
508                  * tiling mode. Otherwise we can just leave it alone, but
509                  * need to ensure that any fence register is cleared.
510                  */
511                 if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
512                     ret = i915_gem_object_unbind(obj);
513                 else
514                     ret = i915_gem_object_put_fence_reg(obj);
515                 if (ret != 0) {
516                         WARN(ret != -ERESTARTSYS,
517                              "failed to reset object for tiling switch");
518                         args->tiling_mode = obj_priv->tiling_mode;
519                         args->stride = obj_priv->stride;
520                         goto err;
521                 }
522
523                 /* If we've changed tiling, GTT-mappings of the object
524                  * need to re-fault to ensure that the correct fence register
525                  * setup is in place.
526                  */
527                 i915_gem_release_mmap(obj);
528
529                 obj_priv->tiling_mode = args->tiling_mode;
530                 obj_priv->stride = args->stride;
531         }
532 err:
533         drm_gem_object_unreference(obj);
534         mutex_unlock(&dev->struct_mutex);
535
536         return ret;
537 }
538
539 /**
540  * Returns the current tiling mode and required bit 6 swizzling for the object.
541  */
542 int
543 i915_gem_get_tiling(struct drm_device *dev, void *data,
544                    struct drm_file *file_priv)
545 {
546         struct drm_i915_gem_get_tiling *args = data;
547         drm_i915_private_t *dev_priv = dev->dev_private;
548         struct drm_gem_object *obj;
549         struct drm_i915_gem_object *obj_priv;
550
551         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
552         if (obj == NULL)
553                 return -EINVAL;
554         obj_priv = obj->driver_private;
555
556         mutex_lock(&dev->struct_mutex);
557
558         args->tiling_mode = obj_priv->tiling_mode;
559         switch (obj_priv->tiling_mode) {
560         case I915_TILING_X:
561                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
562                 break;
563         case I915_TILING_Y:
564                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
565                 break;
566         case I915_TILING_NONE:
567                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
568                 break;
569         default:
570                 DRM_ERROR("unknown tiling mode\n");
571         }
572
573         /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
574         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
575                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
576         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
577                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
578
579         drm_gem_object_unreference(obj);
580         mutex_unlock(&dev->struct_mutex);
581
582         return 0;
583 }
584
585 /**
586  * Swap every 64 bytes of this page around, to account for it having a new
587  * bit 17 of its physical address and therefore being interpreted differently
588  * by the GPU.
589  */
590 static int
591 i915_gem_swizzle_page(struct page *page)
592 {
593         char *vaddr;
594         int i;
595         char temp[64];
596
597         vaddr = kmap(page);
598         if (vaddr == NULL)
599                 return -ENOMEM;
600
601         for (i = 0; i < PAGE_SIZE; i += 128) {
602                 memcpy(temp, &vaddr[i], 64);
603                 memcpy(&vaddr[i], &vaddr[i + 64], 64);
604                 memcpy(&vaddr[i + 64], temp, 64);
605         }
606
607         kunmap(page);
608
609         return 0;
610 }
611
612 void
613 i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
614 {
615         struct drm_device *dev = obj->dev;
616         drm_i915_private_t *dev_priv = dev->dev_private;
617         struct drm_i915_gem_object *obj_priv = obj->driver_private;
618         int page_count = obj->size >> PAGE_SHIFT;
619         int i;
620
621         if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
622                 return;
623
624         if (obj_priv->bit_17 == NULL)
625                 return;
626
627         for (i = 0; i < page_count; i++) {
628                 char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17;
629                 if ((new_bit_17 & 0x1) !=
630                     (test_bit(i, obj_priv->bit_17) != 0)) {
631                         int ret = i915_gem_swizzle_page(obj_priv->pages[i]);
632                         if (ret != 0) {
633                                 DRM_ERROR("Failed to swizzle page\n");
634                                 return;
635                         }
636                         set_page_dirty(obj_priv->pages[i]);
637                 }
638         }
639 }
640
641 void
642 i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
643 {
644         struct drm_device *dev = obj->dev;
645         drm_i915_private_t *dev_priv = dev->dev_private;
646         struct drm_i915_gem_object *obj_priv = obj->driver_private;
647         int page_count = obj->size >> PAGE_SHIFT;
648         int i;
649
650         if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
651                 return;
652
653         if (obj_priv->bit_17 == NULL) {
654                 obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
655                                            sizeof(long), GFP_KERNEL);
656                 if (obj_priv->bit_17 == NULL) {
657                         DRM_ERROR("Failed to allocate memory for bit 17 "
658                                   "record\n");
659                         return;
660                 }
661         }
662
663         for (i = 0; i < page_count; i++) {
664                 if (page_to_phys(obj_priv->pages[i]) & (1 << 17))
665                         __set_bit(i, obj_priv->bit_17);
666                 else
667                         __clear_bit(i, obj_priv->bit_17);
668         }
669 }