Merge branch 'core' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile...
[safe/jmp/linux-2.6] / drivers / gpu / drm / i915 / i915_gem_tiling.c
index ba247d1..4bdccef 100644 (file)
@@ -92,7 +92,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
        uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
        uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 
-       if (IS_IRONLAKE(dev)) {
+       if (IS_IRONLAKE(dev) || IS_GEN6(dev)) {
                /* On Ironlake whatever DRAM config, GPU always do
                 * same swizzling setup.
                 */
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
                 * reg, so dont bother to check the size */
                if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
                        return false;
-       } else if (IS_I9XX(dev)) {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
-
-               /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
-                * instead of 4 (2KB) on 945s.
-                */
-               if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 20))
+       } else if (IS_GEN3(dev) || IS_GEN2(dev)) {
+               if (stride > 8192)
                        return false;
-       } else {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
 
-               if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 19))
-                       return false;
+               if (IS_GEN3(dev)) {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+                               return false;
+               } else {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+                               return false;
+               }
        }
 
        /* 965+ just needs multiples of tile width */
@@ -240,7 +236,7 @@ bool
 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->gtt_space == NULL)
                return true;
@@ -280,12 +276,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
-               mutex_lock(&dev->struct_mutex);
-               drm_gem_object_unreference(obj);
-               mutex_unlock(&dev->struct_mutex);
+               drm_gem_object_unreference_unlocked(obj);
                return -EINVAL;
        }
 
@@ -327,9 +321,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
                 * need to ensure that any fence register is cleared.
                 */
                if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
-                   ret = i915_gem_object_unbind(obj);
+                       ret = i915_gem_object_unbind(obj);
+               else if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+                       ret = i915_gem_object_put_fence_reg(obj);
                else
-                   ret = i915_gem_object_put_fence_reg(obj);
+                       i915_gem_release_mmap(obj);
+
                if (ret != 0) {
                        WARN(ret != -ERESTARTSYS,
                             "failed to reset object for tiling switch");
@@ -363,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -426,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
@@ -455,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;