summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_fbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fbc.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c65
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";