drm/i915: preserve swizzle settings if necessary v4
authorJesse Barnes <jbarnes@virtuousgeek.org>
Thu, 9 Oct 2014 19:57:43 +0000 (12:57 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 24 Oct 2014 14:34:09 +0000 (16:34 +0200)
Some machines (like MBAs) might use a tiled framebuffer but not enable
display swizzling at boot time.  We want to preserve that configuration
if possible to prevent a boot time mode set.  On IVB+ it shouldn't
affect performance anyway since the memory controller does internal
swizzling anyway.

For most other configs we'll be able to enable swizzling at boot time,
since the initial framebuffer won't be tiled, thus we won't see any
corruption when we enable it.

v2: preserve swizzling if BIOS had it set (Daniel)
v3: preserve swizzling only if we inherited a tiled framebuffer (Daniel)
    check display swizzle setting in detect_bit_6_swizzle (Daniel)
    use gen6 as cutoff point (Daniel)
v4: fixup swizzle preserve again, had wrong init order (Daniel)

Reported-by: Kristian Høgsberg <hoegsberg@gmail.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/intel_display.c

index d1905b38fc953327fcd54982e89c6e65bc41b852..3212d62c3c64c130f2ae08724e6d72759618eef8 100644 (file)
@@ -1541,6 +1541,8 @@ struct drm_i915_private {
        struct intel_opregion opregion;
        struct intel_vbt_data vbt;
 
+       bool preserve_bios_swizzle;
+
        /* overlay */
        struct intel_overlay *overlay;
 
index 2cefb597df6dc92d446557442073d5c998843a30..d1e7a3e088aae58922a1162f3ebf2cb8739fe78a 100644 (file)
@@ -102,22 +102,33 @@ 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 (INTEL_INFO(dev)->gen >= 6) {
-               uint32_t dimm_c0, dimm_c1;
-               dimm_c0 = I915_READ(MAD_DIMM_C0);
-               dimm_c1 = I915_READ(MAD_DIMM_C1);
-               dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
-               dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
-               /* Enable swizzling when the channels are populated with
-                * identically sized dimms. We don't need to check the 3rd
-                * channel because no cpu with gpu attached ships in that
-                * configuration. Also, swizzling only makes sense for 2
-                * channels anyway. */
-               if (dimm_c0 == dimm_c1) {
-                       swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-                       swizzle_y = I915_BIT_6_SWIZZLE_9;
+               if (dev_priv->preserve_bios_swizzle) {
+                       if (I915_READ(DISP_ARB_CTL) &
+                           DISP_TILE_SURFACE_SWIZZLING) {
+                               swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+                               swizzle_y = I915_BIT_6_SWIZZLE_9;
+                       } else {
+                               swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+                               swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+                       }
                } else {
-                       swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-                       swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+                       uint32_t dimm_c0, dimm_c1;
+                       dimm_c0 = I915_READ(MAD_DIMM_C0);
+                       dimm_c1 = I915_READ(MAD_DIMM_C1);
+                       dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+                       dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+                       /* Enable swizzling when the channels are populated
+                        * with identically sized dimms. We don't need to check
+                        * the 3rd channel because no cpu with gpu attached
+                        * ships in that configuration. Also, swizzling only
+                        * makes sense for 2 channels anyway. */
+                       if (dimm_c0 == dimm_c1) {
+                               swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+                               swizzle_y = I915_BIT_6_SWIZZLE_9;
+                       } else {
+                               swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+                               swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+                       }
                }
        } else if (IS_GEN5(dev)) {
                /* On Ironlake whatever DRAM config, GPU always do
index 103972c131b614ed6309bc0ee49191220e7c934b..fb9a4348068082f8fb21a7409696339402e347d4 100644 (file)
@@ -2359,6 +2359,7 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
                                 struct intel_plane_config *plane_config)
 {
        struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *c;
        struct intel_crtc *i;
        struct drm_i915_gem_object *obj;
@@ -2390,6 +2391,9 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
                        continue;
 
                if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
+                       if (obj->tiling_mode != I915_TILING_NONE)
+                               dev_priv->preserve_bios_swizzle = true;
+
                        drm_framebuffer_reference(c->primary->fb);
                        intel_crtc->base.primary->fb = c->primary->fb;
                        obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);