From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> 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.syrjala@xxxxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx