Commit abe959c7 authored by Rodrigo Vivi's avatar Rodrigo Vivi Committed by Daniel Vetter

drm/i915: Add support for FBC on Ivybridge.

This patch introduce Frame Buffer Compression (FBC) support for IVB,
without enabling it by default.
It adds a new function gen7_enable_fbc to avoid getting
ironlake_enable_fbc messed with many IS_IVYBRIDGE checks.

v2: Fixes from Ville.
     	*  Fix Plane. FBC is tied to primary plane A in HSW
    	*  Fix DPFC initial write to avoid let trash on the register.
v3: Checking for bad plane on intel_update_fbc() as Chris suggested.
v4: Ville pointed out that according to BSpec FBC_CTL bits 0:3 must be 0.
v5: Up to v4 this work was entirely focused on Haswell. However Ville
    noticed I could reuse the FBC work done for HSW and get FBC for free
    at Ivybridge. So it makes more sense enable FBC for IVB first.
    FBC for HSW comming on next patches. We are just not enabling it by
    default on IVB.
v6: Fix confused commit name (by Matt Turner).
v7: Remove gtt_offset shift since it is page aligned byte offset (by Ville).

Cc: Matt Turner <mattst88@gmail.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@gmail.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 41aa3448
...@@ -280,6 +280,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { ...@@ -280,6 +280,7 @@ static const struct intel_device_info intel_ivybridge_m_info = {
GEN7_FEATURES, GEN7_FEATURES,
.is_ivybridge = 1, .is_ivybridge = 1,
.is_mobile = 1, .is_mobile = 1,
.has_fbc = 1,
}; };
static const struct intel_device_info intel_ivybridge_q_info = { static const struct intel_device_info intel_ivybridge_q_info = {
......
...@@ -925,7 +925,9 @@ ...@@ -925,7 +925,9 @@
#define DPFC_CTL_EN (1<<31) #define DPFC_CTL_EN (1<<31)
#define DPFC_CTL_PLANEA (0<<30) #define DPFC_CTL_PLANEA (0<<30)
#define DPFC_CTL_PLANEB (1<<30) #define DPFC_CTL_PLANEB (1<<30)
#define IVB_DPFC_CTL_PLANE_SHIFT (29)
#define DPFC_CTL_FENCE_EN (1<<29) #define DPFC_CTL_FENCE_EN (1<<29)
#define IVB_DPFC_CTL_FENCE_EN (1<<28)
#define DPFC_CTL_PERSISTENT_MODE (1<<25) #define DPFC_CTL_PERSISTENT_MODE (1<<25)
#define DPFC_SR_EN (1<<10) #define DPFC_SR_EN (1<<10)
#define DPFC_CTL_LIMIT_1X (0<<6) #define DPFC_CTL_LIMIT_1X (0<<6)
...@@ -958,6 +960,7 @@ ...@@ -958,6 +960,7 @@
#define ILK_DPFC_CHICKEN 0x43224 #define ILK_DPFC_CHICKEN 0x43224
#define ILK_FBC_RT_BASE 0x2128 #define ILK_FBC_RT_BASE 0x2128
#define ILK_FBC_RT_VALID (1<<0) #define ILK_FBC_RT_VALID (1<<0)
#define SNB_FBC_FRONT_BUFFER (1<<1)
#define ILK_DISPLAY_CHICKEN1 0x42000 #define ILK_DISPLAY_CHICKEN1 0x42000
#define ILK_FBCQ_DIS (1<<22) #define ILK_FBCQ_DIS (1<<22)
...@@ -973,6 +976,9 @@ ...@@ -973,6 +976,9 @@
#define SNB_CPU_FENCE_ENABLE (1<<29) #define SNB_CPU_FENCE_ENABLE (1<<29)
#define DPFC_CPU_FENCE_OFFSET 0x100104 #define DPFC_CPU_FENCE_OFFSET 0x100104
/* Framebuffer compression for Ivybridge */
#define IVB_FBC_RT_BASE 0x7020
/* /*
* GPIO regs * GPIO regs
......
...@@ -253,6 +253,30 @@ static bool ironlake_fbc_enabled(struct drm_device *dev) ...@@ -253,6 +253,30 @@ static bool ironlake_fbc_enabled(struct drm_device *dev)
return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
} }
static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID);
I915_WRITE(ILK_DPFC_CONTROL, DPFC_CTL_EN | DPFC_CTL_LIMIT_1X |
IVB_DPFC_CTL_FENCE_EN |
intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT);
I915_WRITE(SNB_DPFC_CTL_SA,
SNB_CPU_FENCE_ENABLE | obj->fence_reg);
I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
sandybridge_blit_fbc_update(dev);
DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
}
bool intel_fbc_enabled(struct drm_device *dev) bool intel_fbc_enabled(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -439,7 +463,7 @@ void intel_update_fbc(struct drm_device *dev) ...@@ -439,7 +463,7 @@ void intel_update_fbc(struct drm_device *dev)
if (enable_fbc < 0) { if (enable_fbc < 0) {
DRM_DEBUG_KMS("fbc set to per-chip default\n"); DRM_DEBUG_KMS("fbc set to per-chip default\n");
enable_fbc = 1; enable_fbc = 1;
if (INTEL_INFO(dev)->gen <= 6) if (INTEL_INFO(dev)->gen <= 7)
enable_fbc = 0; enable_fbc = 0;
} }
if (!enable_fbc) { if (!enable_fbc) {
...@@ -4507,7 +4531,12 @@ void intel_init_pm(struct drm_device *dev) ...@@ -4507,7 +4531,12 @@ void intel_init_pm(struct drm_device *dev)
if (I915_HAS_FBC(dev)) { if (I915_HAS_FBC(dev)) {
if (HAS_PCH_SPLIT(dev)) { if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.fbc_enabled = ironlake_fbc_enabled; dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
dev_priv->display.enable_fbc = ironlake_enable_fbc; if (IS_IVYBRIDGE(dev))
dev_priv->display.enable_fbc =
gen7_enable_fbc;
else
dev_priv->display.enable_fbc =
ironlake_enable_fbc;
dev_priv->display.disable_fbc = ironlake_disable_fbc; dev_priv->display.disable_fbc = ironlake_disable_fbc;
} else if (IS_GM45(dev)) { } else if (IS_GM45(dev)) {
dev_priv->display.fbc_enabled = g4x_fbc_enabled; dev_priv->display.fbc_enabled = g4x_fbc_enabled;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment