Commit 6f745ba6 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/fbc: Precompute gen9 cfb stride w/a

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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191127201222.16669-6-ville.syrjala@linux.intel.comReviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
parent 64439858
...@@ -283,8 +283,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) ...@@ -283,8 +283,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK); val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK);
if (i915_gem_object_get_tiling(params->vma->obj) != if (params->gen9_wa_cfb_stride)
I915_TILING_X)
val |= FBC_STRIDE_OVERRIDE | params->gen9_wa_cfb_stride; val |= FBC_STRIDE_OVERRIDE | params->gen9_wa_cfb_stride;
I915_WRITE(CHICKEN_MISC_4, val); I915_WRITE(CHICKEN_MISC_4, val);
...@@ -414,8 +413,8 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv, ...@@ -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, static int find_compression_threshold(struct drm_i915_private *dev_priv,
struct drm_mm_node *node, struct drm_mm_node *node,
int size, unsigned int size,
int fb_cpp) unsigned int fb_cpp)
{ {
int compression_threshold = 1; int compression_threshold = 1;
int ret; int ret;
...@@ -461,18 +460,15 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv, ...@@ -461,18 +460,15 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv,
} }
} }
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 intel_fbc *fbc = &dev_priv->fbc;
struct drm_mm_node *uninitialized_var(compressed_llb); struct drm_mm_node *uninitialized_var(compressed_llb);
int size, fb_cpp, ret; int ret;
WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb)); 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, ret = find_compression_threshold(dev_priv, &fbc->compressed_fb,
size, fb_cpp); size, fb_cpp);
if (!ret) if (!ret)
...@@ -823,9 +819,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, ...@@ -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); 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 = cache->gen9_wa_cfb_stride;
params->gen9_wa_cfb_stride = DIV_ROUND_UP(cache->plane.src_w,
32 * fbc->threshold) * 8;
} }
void intel_fbc_pre_update(struct intel_crtc *crtc, void intel_fbc_pre_update(struct intel_crtc *crtc,
...@@ -1054,6 +1048,8 @@ void intel_fbc_enable(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 drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc; 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)) if (!fbc_supported(dev_priv))
return; return;
...@@ -1076,11 +1072,25 @@ void intel_fbc_enable(struct intel_crtc *crtc, ...@@ -1076,11 +1072,25 @@ void intel_fbc_enable(struct intel_crtc *crtc,
WARN_ON(fbc->crtc != NULL); WARN_ON(fbc->crtc != NULL);
intel_fbc_update_state_cache(crtc, crtc_state, plane_state); 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"; fbc->no_fbc_reason = "not enough stolen memory";
goto out; 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)); DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
fbc->no_fbc_reason = "FBC enabled but not active yet\n"; fbc->no_fbc_reason = "FBC enabled but not active yet\n";
......
...@@ -417,6 +417,7 @@ struct intel_fbc { ...@@ -417,6 +417,7 @@ struct intel_fbc {
const struct drm_format_info *format; const struct drm_format_info *format;
unsigned int stride; unsigned int stride;
} fb; } fb;
u16 gen9_wa_cfb_stride;
} state_cache; } state_cache;
/* /*
...@@ -442,7 +443,7 @@ struct intel_fbc { ...@@ -442,7 +443,7 @@ struct intel_fbc {
} fb; } fb;
int cfb_size; int cfb_size;
unsigned int gen9_wa_cfb_stride; u16 gen9_wa_cfb_stride;
} params; } params;
const char *no_fbc_reason; const char *no_fbc_reason;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment