From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  10 +--
 drivers/gpu/drm/i915/intel_display.c |   3 +-
 drivers/gpu/drm/i915/intel_drv.h     |   1 +
 drivers/gpu/drm/i915/intel_pm.c      | 130 +++++++++++++++++++----------------
 drivers/gpu/drm/i915/intel_sprite.c  |   2 +-
 5 files changed, 81 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c92292a..e88baee 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -410,7 +410,7 @@ struct dpll;
 
 struct drm_i915_display_funcs {
        bool (*fbc_enabled)(struct drm_device *dev);
-       void (*enable_fbc)(struct drm_crtc *crtc);
+       void (*enable_fbc)(struct drm_device *dev);
        void (*disable_fbc)(struct drm_device *dev);
        int (*get_display_clock_speed)(struct drm_device *dev);
        int (*get_fifo_size)(struct drm_device *dev, int plane);
@@ -600,14 +600,16 @@ struct intel_context {
 };
 
 struct i915_fbc {
+       struct intel_crtc *crtc;
        unsigned long size;
-       unsigned int fb_id;
-       enum plane plane;
-       int y;
+       uint32_t pixel_format;
+       int fence_reg, pitch, y;
 
        struct drm_mm_node *compressed_fb;
        struct drm_mm_node *compressed_llb;
 
+       struct drm_i915_gem_object *obj;
+
        struct intel_fbc_work {
                struct delayed_work work;
                struct drm_crtc *crtc;
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 53ed4a9..beead24 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4010,7 +4010,7 @@ static void intel_crtc_disable_planes(struct drm_crtc 
*crtc)
 
        intel_crtc_wait_for_pending_flips(crtc);
 
-       if (dev_priv->fbc.plane == plane)
+       if (dev_priv->fbc.crtc == intel_crtc)
                intel_disable_fbc(dev);
 
        hsw_disable_ips(intel_crtc);
@@ -12320,6 +12320,7 @@ void intel_modeset_init(struct drm_device *dev)
                      INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
 
        intel_ips_init(dev);
+       intel_fbc_init(dev);
 
        for_each_pipe(pipe) {
                intel_crtc_init(dev, pipe);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7a48eda..1da1f7b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -961,6 +961,7 @@ void intel_pm_setup(struct drm_device *dev);
 bool intel_fbc_enabled(struct drm_device *dev);
 void intel_disable_fbc(struct drm_device *dev);
 void intel_update_fbc(struct drm_device *dev);
+void intel_fbc_init(struct drm_device *dev);
 void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
 void intel_gpu_ips_teardown(void);
 int intel_power_domains_init(struct drm_i915_private *);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 777167e..6b22e40 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -88,21 +88,17 @@ static void i8xx_disable_fbc(struct drm_device *dev)
        DRM_DEBUG_KMS("disabled FBC\n");
 }
 
-static void i8xx_enable_fbc(struct drm_crtc *crtc)
+static void i8xx_enable_fbc(struct drm_device *dev)
 {
-       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_framebuffer *fb = crtc->primary->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);
+       struct intel_crtc *crtc = dev_priv->fbc.crtc;
        int cfb_pitch;
        int i;
        u32 fbc_ctl;
 
        cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE;
-       if (fb->pitches[0] < cfb_pitch)
-               cfb_pitch = fb->pitches[0];
+       if (dev_priv->fbc.pitch < cfb_pitch)
+               cfb_pitch = dev_priv->fbc.pitch;
 
        /* FBC_CTL wants 32B or 64B units */
        if (IS_GEN2(dev))
@@ -119,9 +115,9 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc)
 
                /* Set it up... */
                fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | 
FBC_CTL_CPU_FENCE;
-               fbc_ctl2 |= FBC_CTL_PLANE(intel_crtc->plane);
+               fbc_ctl2 |= FBC_CTL_PLANE(crtc->plane);
                I915_WRITE(FBC_CONTROL2, fbc_ctl2);
-               I915_WRITE(FBC_FENCE_OFF, crtc->y);
+               I915_WRITE(FBC_FENCE_OFF, dev_priv->fbc.y);
        }
 
        /* enable it... */
@@ -131,11 +127,11 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc)
        if (IS_I945GM(dev))
                fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
        fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
-       fbc_ctl |= obj->fence_reg;
+       fbc_ctl |= dev_priv->fbc.fence_reg;
        I915_WRITE(FBC_CONTROL, fbc_ctl);
 
        DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n",
-                     cfb_pitch, crtc->y, plane_name(intel_crtc->plane));
+                     cfb_pitch, dev_priv->fbc.y, plane_name(crtc->plane));
 }
 
 static bool i8xx_fbc_enabled(struct drm_device *dev)
@@ -145,29 +141,25 @@ static bool i8xx_fbc_enabled(struct drm_device *dev)
        return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
 }
 
-static void g4x_enable_fbc(struct drm_crtc *crtc)
+static void g4x_enable_fbc(struct drm_device *dev)
 {
-       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_framebuffer *fb = crtc->primary->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);
+       struct intel_crtc *crtc = dev_priv->fbc.crtc;
        u32 dpfc_ctl;
 
-       dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN;
-       if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+       dpfc_ctl = DPFC_CTL_PLANE(crtc->plane) | DPFC_SR_EN;
+       if (drm_format_plane_cpp(dev_priv->fbc.pixel_format, 0) == 2)
                dpfc_ctl |= DPFC_CTL_LIMIT_2X;
        else
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;
-       dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg;
+       dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->fbc.fence_reg;
 
-       I915_WRITE(DPFC_FENCE_YOFF, crtc->y);
+       I915_WRITE(DPFC_FENCE_YOFF, dev_priv->fbc.y);
 
        /* enable it... */
        I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
 
-       DRM_DEBUG_KMS("enabled fbc on plane %c\n", 
plane_name(intel_crtc->plane));
+       DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
 }
 
 static void g4x_disable_fbc(struct drm_device *dev)
@@ -217,38 +209,35 @@ static void sandybridge_blit_fbc_update(struct drm_device 
*dev)
        gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
 }
 
-static void ironlake_enable_fbc(struct drm_crtc *crtc)
+static void ironlake_enable_fbc(struct drm_device *dev)
 {
-       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_framebuffer *fb = crtc->primary->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);
+       struct intel_crtc *crtc = dev_priv->fbc.crtc;
        u32 dpfc_ctl;
 
-       dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);
-       if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+       dpfc_ctl = DPFC_CTL_PLANE(crtc->plane);
+       if (drm_format_plane_cpp(dev_priv->fbc.pixel_format, 0) == 2)
                dpfc_ctl |= DPFC_CTL_LIMIT_2X;
        else
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;
        dpfc_ctl |= DPFC_CTL_FENCE_EN;
        if (IS_GEN5(dev))
-               dpfc_ctl |= obj->fence_reg;
+               dpfc_ctl |= dev_priv->fbc.fence_reg;
 
-       I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y);
-       I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | 
ILK_FBC_RT_VALID);
+       I915_WRITE(ILK_DPFC_FENCE_YOFF, dev_priv->fbc.y);
+       I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(dev_priv->fbc.obj) 
|
+                  ILK_FBC_RT_VALID);
        /* enable it... */
        I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
 
        if (IS_GEN6(dev)) {
                I915_WRITE(SNB_DPFC_CTL_SA,
-                          SNB_CPU_FENCE_ENABLE | obj->fence_reg);
-               I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+                          SNB_CPU_FENCE_ENABLE | dev_priv->fbc.fence_reg);
+               I915_WRITE(DPFC_CPU_FENCE_OFFSET, dev_priv->fbc.y);
                sandybridge_blit_fbc_update(dev);
        }
 
-       DRM_DEBUG_KMS("enabled fbc on plane %c\n", 
plane_name(intel_crtc->plane));
+       DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
 }
 
 static void ironlake_disable_fbc(struct drm_device *dev)
@@ -273,18 +262,14 @@ static bool ironlake_fbc_enabled(struct drm_device *dev)
        return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
 }
 
-static void gen7_enable_fbc(struct drm_crtc *crtc)
+static void gen7_enable_fbc(struct drm_device *dev)
 {
-       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_framebuffer *fb = crtc->primary->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);
+       struct intel_crtc *crtc = dev_priv->fbc.crtc;
        u32 dpfc_ctl;
 
-       dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);
-       if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+       dpfc_ctl = IVB_DPFC_CTL_PLANE(crtc->plane);
+       if (drm_format_plane_cpp(dev_priv->fbc.pixel_format, 0) == 2)
                dpfc_ctl |= DPFC_CTL_LIMIT_2X;
        else
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;
@@ -299,18 +284,18 @@ static void gen7_enable_fbc(struct drm_crtc *crtc)
                           ILK_FBCQ_DIS);
        } else {
                /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
-               I915_WRITE(CHICKEN_PIPESL_1(intel_crtc->pipe),
-                          I915_READ(CHICKEN_PIPESL_1(intel_crtc->pipe)) |
+               I915_WRITE(CHICKEN_PIPESL_1(crtc->pipe),
+                          I915_READ(CHICKEN_PIPESL_1(crtc->pipe)) |
                           HSW_FBCQ_DIS);
        }
 
        I915_WRITE(SNB_DPFC_CTL_SA,
-                  SNB_CPU_FENCE_ENABLE | obj->fence_reg);
-       I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+                  SNB_CPU_FENCE_ENABLE | dev_priv->fbc.fence_reg);
+       I915_WRITE(DPFC_CPU_FENCE_OFFSET, dev_priv->fbc.y);
 
        sandybridge_blit_fbc_update(dev);
 
-       DRM_DEBUG_KMS("enabled fbc on plane %c\n", 
plane_name(intel_crtc->plane));
+       DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
 }
 
 bool intel_fbc_enabled(struct drm_device *dev)
@@ -323,6 +308,21 @@ bool intel_fbc_enabled(struct drm_device *dev)
        return dev_priv->display.fbc_enabled(dev);
 }
 
+static void intel_fbc_update_params(struct intel_crtc *crtc)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_framebuffer *fb = crtc->base.primary->fb;
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
+
+       dev_priv->fbc.crtc = crtc;
+       dev_priv->fbc.pixel_format = fb->pixel_format;
+       dev_priv->fbc.pitch = fb->pitches[0];
+       dev_priv->fbc.obj = obj;
+       dev_priv->fbc.fence_reg = obj->fence_reg;
+       dev_priv->fbc.y = crtc->base.y;
+}
+
 static void intel_fbc_work_fn(struct work_struct *__work)
 {
        struct intel_fbc_work *work =
@@ -337,11 +337,8 @@ static void intel_fbc_work_fn(struct work_struct *__work)
                 * the prior work.
                 */
                if (work->crtc->primary->fb == work->fb) {
-                       dev_priv->display.enable_fbc(work->crtc);
-
-                       dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane;
-                       dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id;
-                       dev_priv->fbc.y = work->crtc->y;
+                       intel_fbc_update_params(to_intel_crtc(work->crtc));
+                       dev_priv->display.enable_fbc(dev);
                }
 
                dev_priv->fbc.fbc_work = NULL;
@@ -388,7 +385,8 @@ static void intel_enable_fbc(struct drm_crtc *crtc)
        work = kzalloc(sizeof(*work), GFP_KERNEL);
        if (work == NULL) {
                DRM_ERROR("Failed to allocate FBC work structure\n");
-               dev_priv->display.enable_fbc(crtc);
+               intel_fbc_update_params(to_intel_crtc(crtc));
+               dev_priv->display.enable_fbc(dev);
                return;
        }
 
@@ -424,7 +422,11 @@ void intel_disable_fbc(struct drm_device *dev)
                return;
 
        dev_priv->display.disable_fbc(dev);
-       dev_priv->fbc.plane = -1;
+       dev_priv->fbc.crtc = NULL;
+       dev_priv->fbc.pixel_format = 0;
+       dev_priv->fbc.pitch = 0;
+       dev_priv->fbc.fence_reg = I915_FENCE_REG_NONE;
+       dev_priv->fbc.y = 0;
 }
 
 static bool set_no_fbc_reason(struct drm_i915_private *dev_priv,
@@ -812,8 +814,11 @@ void intel_update_fbc(struct drm_device *dev)
         * cannot be unpinned (and have its GTT offset and fence revoked)
         * without first being decoupled from the scanout and FBC disabled.
         */
-       if (dev_priv->fbc.plane == crtc->plane &&
-           dev_priv->fbc.fb_id == fb->base.id &&
+       if (dev_priv->fbc.crtc == crtc &&
+           dev_priv->fbc.obj == obj &&
+           dev_priv->fbc.pixel_format == fb->pixel_format &&
+           dev_priv->fbc.pitch == fb->pitches[0] &&
+           dev_priv->fbc.fence_reg == obj->fence_reg &&
            dev_priv->fbc.y == crtc->base.y)
                return;
 
@@ -858,6 +863,13 @@ out_disable:
        i915_gem_stolen_cleanup_compression(dev);
 }
 
+void intel_fbc_init(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       dev_priv->fbc.fence_reg = I915_FENCE_REG_NONE;
+}
+
 static void i915_pineview_get_mem_freq(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 404335d..e04ca5d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -711,7 +711,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
        mutex_lock(&dev->struct_mutex);
-       if (dev_priv->fbc.plane == intel_crtc->plane)
+       if (dev_priv->fbc.crtc == intel_crtc)
                intel_disable_fbc(dev);
        mutex_unlock(&dev->struct_mutex);
 
-- 
1.8.5.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to