diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fbc.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_fbc.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a2de57ede276..85723fba6002 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -187,8 +187,30 @@ static bool g4x_fbc_is_active(struct drm_i915_private *dev_priv) return intel_de_read(dev_priv, DPFC_CONTROL) & DPFC_CTL_EN; } +static void i8xx_fbc_recompress(struct drm_i915_private *dev_priv) +{ + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; + enum i9xx_plane_id i9xx_plane = params->crtc.i9xx_plane; + + spin_lock_irq(&dev_priv->uncore.lock); + intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), + intel_de_read_fw(dev_priv, DSPADDR(i9xx_plane))); + spin_unlock_irq(&dev_priv->uncore.lock); +} + +static void i965_fbc_recompress(struct drm_i915_private *dev_priv) +{ + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; + enum i9xx_plane_id i9xx_plane = params->crtc.i9xx_plane; + + spin_lock_irq(&dev_priv->uncore.lock); + intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), + intel_de_read_fw(dev_priv, DSPSURF(i9xx_plane))); + spin_unlock_irq(&dev_priv->uncore.lock); +} + /* This function forces a CFB recompression through the nuke operation. */ -static void intel_fbc_recompress(struct drm_i915_private *dev_priv) +static void snb_fbc_recompress(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; @@ -198,6 +220,16 @@ static void intel_fbc_recompress(struct drm_i915_private *dev_priv) intel_de_posting_read(dev_priv, MSG_FBC_REND_STATE); } +static void intel_fbc_recompress(struct drm_i915_private *dev_priv) +{ + if (INTEL_GEN(dev_priv) >= 6) + snb_fbc_recompress(dev_priv); + else if (INTEL_GEN(dev_priv) >= 4) + i965_fbc_recompress(dev_priv); + else + i8xx_fbc_recompress(dev_priv); +} + static void ilk_fbc_activate(struct drm_i915_private *dev_priv) { struct intel_fbc_reg_params *params = &dev_priv->fbc.params; @@ -315,21 +347,6 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) if (dev_priv->fbc.false_color) dpfc_ctl |= FBC_CTL_FALSE_COLOR; - if (IS_IVYBRIDGE(dev_priv)) { - /* WaFbcAsynchFlipDisableFbcQueue:ivb */ - intel_de_write(dev_priv, ILK_DISPLAY_CHICKEN1, - intel_de_read(dev_priv, ILK_DISPLAY_CHICKEN1) | ILK_FBCQ_DIS); - } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_de_write(dev_priv, CHICKEN_PIPESL_1(params->crtc.pipe), - intel_de_read(dev_priv, CHICKEN_PIPESL_1(params->crtc.pipe)) | HSW_FBCQ_DIS); - } - - if (INTEL_GEN(dev_priv) >= 11) - /* Wa_1409120013:icl,ehl,tgl */ - intel_de_write(dev_priv, ILK_DPFC_CHICKEN, - ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); - intel_de_write(dev_priv, ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); intel_fbc_recompress(dev_priv); @@ -695,9 +712,13 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->plane.pixel_blend_mode = plane_state->hw.pixel_blend_mode; cache->fb.format = fb->format; - cache->fb.stride = fb->pitches[0]; cache->fb.modifier = fb->modifier; + /* FIXME is this correct? */ + cache->fb.stride = plane_state->color_plane[0].stride; + if (drm_rotation_90_or_270(plane_state->hw.rotation)) + cache->fb.stride *= fb->format->cpp[0]; + /* FBC1 compression interval: arbitrary choice of 1 second */ cache->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode); @@ -816,6 +837,11 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } + if (!pixel_format_is_valid(dev_priv, cache->fb.format->format)) { + fbc->no_fbc_reason = "pixel format is invalid"; + return false; + } + if (!rotation_is_valid(dev_priv, cache->fb.format->format, cache->plane.rotation)) { fbc->no_fbc_reason = "rotation unsupported"; @@ -832,11 +858,6 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } - if (!pixel_format_is_valid(dev_priv, cache->fb.format->format)) { - fbc->no_fbc_reason = "pixel format is invalid"; - return false; - } - if (cache->plane.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && cache->fb.format->has_alpha) { fbc->no_fbc_reason = "per-pixel alpha blending is incompatible with FBC"; |