Skip to content

Commit 0428ab0

Browse files
committed
drm/i915: Recalculate FBC w/a stride when needed
Currently we're failing to recalculate the gen9 FBC w/a stride unless something more drastic than just the modifier itself has changed. This often leaves us with FBC enabled with the linear fbdev framebuffer without the w/a stride enabled. That will cause an immediate underrun and FBC will get promptly disabled. Fix the problem by checking if the w/a stride is about to change, and go through the full dance if so. This part of the FBC code is still pretty much a disaster and will need lots more work. But this should at least fix the immediate issue. v2: Deactivate FBC when the modifier changes since that will likely require resetting the w/a CFB stride Cc: [email protected] Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: José Roberto de Souza <[email protected]>
1 parent a581483 commit 0428ab0

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

drivers/gpu/drm/i915/display/intel_fbc.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,25 @@ static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv)
742742
fbc->compressed_fb.size * fbc->threshold;
743743
}
744744

745+
static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv)
746+
{
747+
struct intel_fbc *fbc = &dev_priv->fbc;
748+
struct intel_fbc_state_cache *cache = &fbc->state_cache;
749+
750+
if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) &&
751+
cache->fb.modifier != I915_FORMAT_MOD_X_TILED)
752+
return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
753+
else
754+
return 0;
755+
}
756+
757+
static bool intel_fbc_gen9_wa_cfb_stride_changed(struct drm_i915_private *dev_priv)
758+
{
759+
struct intel_fbc *fbc = &dev_priv->fbc;
760+
761+
return fbc->params.gen9_wa_cfb_stride != intel_fbc_gen9_wa_cfb_stride(dev_priv);
762+
}
763+
745764
static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv)
746765
{
747766
struct intel_fbc *fbc = &dev_priv->fbc;
@@ -902,6 +921,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
902921
params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane;
903922

904923
params->fb.format = cache->fb.format;
924+
params->fb.modifier = cache->fb.modifier;
905925
params->fb.stride = cache->fb.stride;
906926

907927
params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache);
@@ -931,6 +951,9 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state)
931951
if (params->fb.format != cache->fb.format)
932952
return false;
933953

954+
if (params->fb.modifier != cache->fb.modifier)
955+
return false;
956+
934957
if (params->fb.stride != cache->fb.stride)
935958
return false;
936959

@@ -1218,7 +1241,8 @@ void intel_fbc_enable(struct intel_atomic_state *state,
12181241

12191242
if (fbc->crtc) {
12201243
if (fbc->crtc != crtc ||
1221-
!intel_fbc_cfb_size_changed(dev_priv))
1244+
(!intel_fbc_cfb_size_changed(dev_priv) &&
1245+
!intel_fbc_gen9_wa_cfb_stride_changed(dev_priv)))
12221246
goto out;
12231247

12241248
__intel_fbc_disable(dev_priv);
@@ -1240,12 +1264,7 @@ void intel_fbc_enable(struct intel_atomic_state *state,
12401264
goto out;
12411265
}
12421266

1243-
if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) &&
1244-
plane_state->hw.fb->modifier != I915_FORMAT_MOD_X_TILED)
1245-
cache->gen9_wa_cfb_stride =
1246-
DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
1247-
else
1248-
cache->gen9_wa_cfb_stride = 0;
1267+
cache->gen9_wa_cfb_stride = intel_fbc_gen9_wa_cfb_stride(dev_priv);
12491268

12501269
drm_dbg_kms(&dev_priv->drm, "Enabling FBC on pipe %c\n",
12511270
pipe_name(crtc->pipe));

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ struct intel_fbc {
442442
struct {
443443
const struct drm_format_info *format;
444444
unsigned int stride;
445+
u64 modifier;
445446
} fb;
446447

447448
int cfb_size;

0 commit comments

Comments
 (0)