Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / i915_gem_tiling.c
index 7fb4191ef934c2b9a9549a36737e075d6ee3fca7..6be3f927c86a78b9a4e85afbfc8abc48a2619d1b 100644 (file)
@@ -96,16 +96,16 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
                 */
                swizzle_x = I915_BIT_6_SWIZZLE_NONE;
                swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-       } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) ||
-                  IS_GM45(dev)) {
+       } else if (IS_MOBILE(dev)) {
                uint32_t dcc;
 
-               /* On 915-945 and GM965, channel interleave by the CPU is
-                * determined by DCC.  The CPU will alternate based on bit 6
-                * in interleaved mode, and the GPU will then also alternate
-                * on bit 6, 9, and 10 for X, but the CPU may also optionally
-                * alternate based on bit 17 (XOR not disabled and XOR
-                * bit == 17).
+               /* On mobile 9xx chipsets, channel interleave by the CPU is
+                * determined by DCC.  For single-channel, neither the CPU
+                * nor the GPU do swizzling.  For dual channel interleaved,
+                * the GPU's interleave is bit 9 and 10 for X tiled, and bit
+                * 9 for Y tiled.  The CPU's interleave is independent, and
+                * can be based on either bit 11 (haven't seen this yet) or
+                * bit 17 (common).
                 */
                dcc = I915_READ(DCC);
                switch (dcc & DCC_ADDRESSING_MODE_MASK) {
@@ -115,19 +115,18 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
                        swizzle_y = I915_BIT_6_SWIZZLE_NONE;
                        break;
                case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
-                       if (IS_I915G(dev) || IS_I915GM(dev) ||
-                           dcc & DCC_CHANNEL_XOR_DISABLE) {
+                       if (dcc & DCC_CHANNEL_XOR_DISABLE) {
+                               /* This is the base swizzling by the GPU for
+                                * tiled buffers.
+                                */
                                swizzle_x = I915_BIT_6_SWIZZLE_9_10;
                                swizzle_y = I915_BIT_6_SWIZZLE_9;
-                       } else if ((IS_I965GM(dev) || IS_GM45(dev)) &&
-                                  (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
-                               /* GM965/GM45 does either bit 11 or bit 17
-                                * swizzling.
-                                */
+                       } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
+                               /* Bit 11 swizzling by the CPU in addition. */
                                swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
                                swizzle_y = I915_BIT_6_SWIZZLE_9_11;
                        } else {
-                               /* Bit 17 or perhaps other swizzling */
+                               /* Bit 17 swizzling by the CPU in addition. */
                                swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
                                swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
                        }
@@ -217,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
        else
                tile_width = 512;
 
+       /* check maximum stride & object size */
+       if (IS_I965G(dev)) {
+               /* i965 stores the end address of the gtt mapping in the fence
+                * reg, so dont bother to check the size */
+               if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
+                       return false;
+       } else if (IS_I9XX(dev)) {
+               if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
+                   size > (I830_FENCE_MAX_SIZE_VAL << 20))
+                       return false;
+       } else {
+               if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
+                   size > (I830_FENCE_MAX_SIZE_VAL << 19))
+                       return false;
+       }
+
        /* 965+ just needs multiples of tile width */
        if (IS_I965G(dev)) {
                if (stride & (tile_width - 1))