From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 21 Feb 2018 19:31:01 +0200 Subject: drm/i915: Clean up fbc vs. plane checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git-commit: cf1805e65802cf77243e2cdcf1b265240f70eda2 Patch-mainline: v4.17-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 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 v3: Move inte_fbc_init() back since we depend on it happening even with i915.disable_display, and populate fbc->possible_framebuffer_bits directly from the plane init code instead v4: Add note about plane A being tied to pipe A on HSW+ Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180221173101.19385-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180221160235.11134-5-ville.syrjala@linux.intel.com Acked-by: Petr Tesarik --- drivers/gpu/drm/i915/intel_display.c | 41 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 drivers/gpu/drm/i915/intel_fbc.c | 26 +--------------------- 3 files changed, 44 insertions(+), 24 deletions(-) --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13223,6 +13223,32 @@ static const struct drm_plane_funcs inte .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; /* tied to pipe 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) { @@ -13265,6 +13291,21 @@ intel_primary_plane_create(struct drm_i9 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); + + if (primary->has_fbc) { + struct intel_fbc *fbc = &dev_priv->fbc; + + fbc->possible_framebuffer_bits |= primary->frontbuffer_bit; + } + primary->check_plane = intel_check_primary_plane; if (INTEL_GEN(dev_priv) >= 9) { --- 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; --- 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 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_i9 struct intel_crtc_state *crtc_state; struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc); - if (!plane_state->base.visible) + if (!plane->has_fbc) continue; - if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) - 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,6 @@ static bool need_fbc_vtd_wa(struct drm_i void intel_fbc_init(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - enum pipe pipe; INIT_WORK(&fbc->work.work, intel_fbc_work_fn); INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); @@ -1378,14 +1364,6 @@ void intel_fbc_init(struct drm_i915_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; - } - /* This value was pulled out of someone's hat */ if (INTEL_GEN(dev_priv) <= 4 && !IS_GM45(dev_priv)) I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);