From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Let's record the information whether a plane can do fbc or not under struct inte_plane. v2: Rebase due to i9xx_plane_id Handle BDW/HSW correctly Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_fbc.c | 28 +++++++-------------------- drivers/gpu/drm/i915/intel_pm.c | 2 -- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d2a66704e6f5..8aeb6b686bac 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13238,6 +13238,32 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = { .format_mod_supported = intel_cursor_plane_format_mod_supported, }; +static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv, + enum i9xx_plane_id i9xx_plane) +{ + if (!HAS_FBC(dev_priv)) + return false; + + if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + return i9xx_plane == PLANE_A; + else if (IS_IVYBRIDGE(dev_priv)) + return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B || + i9xx_plane == PLANE_C; + else if (INTEL_GEN(dev_priv) >= 4) + return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B; + else + return i9xx_plane == PLANE_A; +} + +static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, + enum pipe pipe, enum plane_id plane_id) +{ + if (!HAS_FBC(dev_priv)) + return false; + + return pipe == PIPE_A && plane_id == PLANE_PRIMARY; +} + static struct intel_plane * intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -13280,6 +13306,15 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->i9xx_plane = (enum i9xx_plane_id) pipe; primary->id = PLANE_PRIMARY; primary->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, primary->id); + + if (INTEL_GEN(dev_priv) >= 9) + primary->has_fbc = skl_plane_has_fbc(dev_priv, + primary->pipe, + primary->id); + else + primary->has_fbc = i9xx_plane_has_fbc(dev_priv, + primary->i9xx_plane); + primary->check_plane = intel_check_primary_plane; if (INTEL_GEN(dev_priv) >= 9) { @@ -14683,6 +14718,8 @@ int intel_modeset_init(struct drm_device *dev) } } + intel_fbc_init(dev_priv); + intel_shared_dpll_init(dev); intel_update_fdi_pll_freq(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e3f78fdae859..af82feb4a3cd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -935,6 +935,7 @@ struct intel_plane { enum plane_id id; enum pipe pipe; bool can_scale; + bool has_fbc; int max_downscale; uint32_t frontbuffer_bit; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index f66f6fb5743d..97d088058d1d 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -46,16 +46,6 @@ static inline bool fbc_supported(struct drm_i915_private *dev_priv) return HAS_FBC(dev_priv); } -static inline bool fbc_on_pipe_a_only(struct drm_i915_private *dev_priv) -{ - return IS_HASWELL(dev_priv) || INTEL_GEN(dev_priv) >= 8; -} - -static inline bool fbc_on_plane_a_only(struct drm_i915_private *dev_priv) -{ - return INTEL_GEN(dev_priv) < 4; -} - static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) { return INTEL_GEN(dev_priv) <= 3; @@ -1094,13 +1084,10 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, struct intel_crtc_state *crtc_state; struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc); - if (!plane_state->base.visible) - continue; - - if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) + if (!plane->has_fbc) continue; - if (fbc_on_plane_a_only(dev_priv) && plane->i9xx_plane != PLANE_A) + if (!plane_state->base.visible) continue; crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -1357,7 +1344,7 @@ static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv) void intel_fbc_init(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - enum pipe pipe; + struct intel_plane *plane; INIT_WORK(&fbc->work.work, intel_fbc_work_fn); INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); @@ -1378,12 +1365,11 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) return; } - for_each_pipe(dev_priv, pipe) { - fbc->possible_framebuffer_bits |= - INTEL_FRONTBUFFER(pipe, PLANE_PRIMARY); - if (fbc_on_pipe_a_only(dev_priv)) - break; + for_each_intel_plane(&dev_priv->drm, plane) { + if (plane->has_fbc) + fbc->possible_framebuffer_bits |= + INTEL_FRONTBUFFER(plane->pipe, plane->id); } /* This value was pulled out of someone's hat */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index abf80e462833..e8180ff66f43 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -9049,8 +9049,6 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_i915_private *dev_priv) { - intel_fbc_init(dev_priv); - /* For cxsr */ if (IS_PINEVIEW(dev_priv)) i915_pineview_get_mem_freq(dev_priv); -- 2.13.6 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx