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

Currently ilk_disable_lp_wm() just disabled LP1+ watermarks directly.
However there's nothing preventing someone else from re-enabling them
immediately. To make sure sure LP1+ watermarks stay disabled for the
intended period, keep track which pipes require the LP1+ watermarks
to be disabled.

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  6 ++++++
 drivers/gpu/drm/i915/intel_display.c |  2 +-
 drivers/gpu/drm/i915/intel_drv.h     |  2 +-
 drivers/gpu/drm/i915/intel_pm.c      | 22 ++++++++++++++++++----
 4 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 39bcf3b..5e69ca7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1612,6 +1612,12 @@ typedef struct drm_i915_private {
                struct ilk_wm_values hw;
 
                /*
+                * bitmask of pipes that have requested
+                * LP1+ watermarks to be disabled.
+                */
+               unsigned int lp_disabled;
+
+               /*
                 * protects some dev_priv->wm and intel_crtc->wm
                 * state as well as the actual hardware registers
                 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9c43751..6673de02 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3659,7 +3659,7 @@ static void ilk_prepare_for_num_pipes_change(struct 
intel_crtc *crtc)
 
        ilk_wm_synchronize(&other_active_crtc->base);
 
-       if (ilk_disable_lp_wm(dev))
+       if (ilk_disable_lp_wm(&crtc->base))
                intel_wait_for_vblank(dev, other_active_crtc->pipe);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 94e90ad..9c84d21 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -953,7 +953,7 @@ void ilk_wm_get_hw_state(struct drm_device *dev);
 void ilk_update_pipe_wm(struct drm_device *dev, enum pipe pipe);
 void ilk_wm_synchronize(struct drm_crtc *crtc);
 void ilk_wm_pipe_post_disable(struct drm_crtc *crtc);
-bool ilk_disable_lp_wm(struct drm_device *dev);
+bool ilk_disable_lp_wm(struct drm_crtc *crtc);
 
 
 /* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7230748..6e07686 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2377,6 +2377,7 @@ static void ilk_compute_wm_results(struct drm_device *dev,
                                   enum intel_ddb_partitioning partitioning,
                                   struct ilk_wm_values *results)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc;
        int level, wm_lp;
 
@@ -2400,7 +2401,7 @@ static void ilk_compute_wm_results(struct drm_device *dev,
                        (r->pri_val << WM1_LP_SR_SHIFT) |
                        r->cur_val;
 
-               if (r->enable)
+               if (r->enable && !dev_priv->wm.lp_disabled)
                        results->wm_lp[wm_lp - 1] |= WM1_LP_SR_EN;
 
                if (INTEL_INFO(dev)->gen >= 8)
@@ -2714,13 +2715,18 @@ static void ilk_write_wm_values(struct drm_i915_private 
*dev_priv,
        }
 }
 
-bool ilk_disable_lp_wm(struct drm_device *dev)
+bool ilk_disable_lp_wm(struct drm_crtc *crtc)
 {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        bool changed;
 
        mutex_lock(&dev_priv->wm.mutex);
+
+       dev_priv->wm.lp_disabled |= 1 << to_intel_crtc(crtc)->pipe;
+
        changed = _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
+
        mutex_unlock(&dev_priv->wm.mutex);
 
        return changed;
@@ -2838,15 +2844,20 @@ static void ilk_setup_pending_watermarks(struct 
intel_crtc *intel_crtc,
                                         u32 vbl_count)
 {
        struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe = intel_crtc->pipe;
 
        WARN(!intel_crtc->active, "pipe %c should be enabled\n",
             pipe_name(pipe));
 
        /* do the watermarks actually need changing? */
-       if (!memcmp(&intel_crtc->wm.pending, pipe_wm, sizeof(*pipe_wm)))
+       if (!(dev_priv->wm.lp_disabled & (1 << intel_crtc->pipe)) &&
+           !memcmp(&intel_crtc->wm.pending, pipe_wm, sizeof(*pipe_wm)))
                return;
 
+       /* allow LP1+ watermarks again */
+       dev_priv->wm.lp_disabled &= ~(1 << intel_crtc->pipe);
+
        intel_crtc->wm.pending = *pipe_wm;
 
        spin_lock_irq(&intel_crtc->wm.lock);
@@ -3044,6 +3055,9 @@ void ilk_wm_pipe_post_disable(struct drm_crtc *crtc)
        /* pending update (if any) got cancelled */
        intel_crtc->wm.pending = intel_crtc->wm.active;
 
+       /* allow LP1+ watermarks again */
+       dev_priv->wm.lp_disabled &= ~(1 << intel_crtc->pipe);
+
        ilk_update_watermarks(dev, true);
 
        mutex_unlock(&dev_priv->wm.mutex);
@@ -3097,7 +3111,7 @@ static int ilk_update_sprite_wm(struct drm_plane *plane,
         *
         * WaCxSRDisabledForSpriteScaling:ivb
         */
-       if (IS_IVYBRIDGE(dev) && config->spr.scaled && ilk_disable_lp_wm(dev))
+       if (IS_IVYBRIDGE(dev) && config->spr.scaled && ilk_disable_lp_wm(crtc))
                intel_wait_for_vblank(dev, to_intel_plane(plane)->pipe);
 
        params.pri = config->pri;
-- 
1.8.3.2

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

Reply via email to