]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/fbc: Precompute gen9 cfb stride w/a
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 27 Nov 2019 20:12:13 +0000 (22:12 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 9 Dec 2019 14:10:58 +0000 (16:10 +0200)
Precompute the override cfb stride value so that we can check
it when determining if flip nuke can be used or not.

The hardware has 13 bits for this, so we can shrink the storage
to u16 while at it.

v2: Don't explode when crtc_state->enable_fbc lies to us

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191127201222.16669-6-ville.syrjala@linux.intel.com
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/i915_drv.h

index 20e753749bf8e30f3430253f89941c644dc9364b..e579f78e4453e26947d69224b8491add983f66c0 100644 (file)
@@ -283,8 +283,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
 
                val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK);
 
-               if (i915_gem_object_get_tiling(params->vma->obj) !=
-                   I915_TILING_X)
+               if (params->gen9_wa_cfb_stride)
                        val |= FBC_STRIDE_OVERRIDE | params->gen9_wa_cfb_stride;
 
                I915_WRITE(CHICKEN_MISC_4, val);
@@ -414,8 +413,8 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv,
 
 static int find_compression_threshold(struct drm_i915_private *dev_priv,
                                      struct drm_mm_node *node,
-                                     int size,
-                                     int fb_cpp)
+                                     unsigned int size,
+                                     unsigned int fb_cpp)
 {
        int compression_threshold = 1;
        int ret;
@@ -461,18 +460,15 @@ again:
        }
 }
 
-static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
+static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
+                              unsigned int size, unsigned int fb_cpp)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_fbc *fbc = &dev_priv->fbc;
        struct drm_mm_node *uninitialized_var(compressed_llb);
-       int size, fb_cpp, ret;
+       int ret;
 
        WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb));
 
-       size = intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache);
-       fb_cpp = fbc->state_cache.fb.format->cpp[0];
-
        ret = find_compression_threshold(dev_priv, &fbc->compressed_fb,
                                         size, fb_cpp);
        if (!ret)
@@ -823,9 +819,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
 
        params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache);
 
-       if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv))
-               params->gen9_wa_cfb_stride = DIV_ROUND_UP(cache->plane.src_w,
-                                               32 * fbc->threshold) * 8;
+       params->gen9_wa_cfb_stride = cache->gen9_wa_cfb_stride;
 }
 
 void intel_fbc_pre_update(struct intel_crtc *crtc,
@@ -1054,6 +1048,8 @@ void intel_fbc_enable(struct intel_crtc *crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_fbc *fbc = &dev_priv->fbc;
+       struct intel_fbc_state_cache *cache = &fbc->state_cache;
+       const struct drm_framebuffer *fb = plane_state->hw.fb;
 
        if (!fbc_supported(dev_priv))
                return;
@@ -1076,11 +1072,25 @@ void intel_fbc_enable(struct intel_crtc *crtc,
        WARN_ON(fbc->crtc != NULL);
 
        intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
-       if (intel_fbc_alloc_cfb(crtc)) {
+
+       /* FIXME crtc_state->enable_fbc lies :( */
+       if (!cache->plane.visible)
+               goto out;
+
+       if (intel_fbc_alloc_cfb(dev_priv,
+                               intel_fbc_calculate_cfb_size(dev_priv, cache),
+                               fb->format->cpp[0])) {
                fbc->no_fbc_reason = "not enough stolen memory";
                goto out;
        }
 
+       if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) &&
+           fb->modifier != I915_FORMAT_MOD_X_TILED)
+               cache->gen9_wa_cfb_stride =
+                       DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
+       else
+               cache->gen9_wa_cfb_stride = 0;
+
        DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
        fbc->no_fbc_reason = "FBC enabled but not active yet\n";
 
index d515a9d39e2e7f10694d40c28e8fb59d734eedf6..2e99f5d48396ef4c112ec48a1321416144c64194 100644 (file)
@@ -417,6 +417,7 @@ struct intel_fbc {
                        const struct drm_format_info *format;
                        unsigned int stride;
                } fb;
+               u16 gen9_wa_cfb_stride;
        } state_cache;
 
        /*
@@ -442,7 +443,7 @@ struct intel_fbc {
                } fb;
 
                int cfb_size;
-               unsigned int gen9_wa_cfb_stride;
+               u16 gen9_wa_cfb_stride;
        } params;
 
        const char *no_fbc_reason;