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