2014-05-22 11:48 GMT-03:00 <ville.syrj...@linux.intel.com>: > From: Ville Syrjälä <ville.syrj...@linux.intel.com> > > After we've disabled the planes, it seems like a good idea wait for > the vblank driven watermark updates to finish before we turn off the > vblank interrupts and eventually the entire pipe.
Can you please elaborate more on why it is a "good idea"? Is is a real requirement? A bugfix? What happens if we don't do this? The answer should be on the commit message. The only potential problem I could find is that we'll wake up the waitqueue after ilk_refresh_pending_watermarks() but still before ilk_program_watermarks(). This doesn't seem to be a problem with the current code, but is the kid of thing that could lead to future bugs due to the constant code rewrite/refactor we do. Maybe a comment on top of the ilk_wm_synchronize() definition - explaining that the function may return while the register values are still not "synchronized" - would help a little bit. Or maybe we could just call wake_up_all() after the registers are written. With at least the commit message amended: Reviewed-by: Paulo Zanoni <paulo.r.zan...@intel.com> > > v2: Rebase and s/intel_crtc/crtc/ > > Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/intel_display.c | 2 ++ > drivers/gpu/drm/i915/intel_drv.h | 1 + > drivers/gpu/drm/i915/intel_pm.c | 32 ++++++++++++++++++++++++++++++++ > 4 files changed, 36 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 5b1404e..1fe0cac 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1554,6 +1554,7 @@ struct drm_i915_private { > struct mutex mutex; > > struct work_struct work; > + wait_queue_head_t wait; > } wm; > > struct i915_runtime_pm pm; > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 5bf1633..ca362db 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3960,6 +3960,8 @@ static void intel_crtc_disable_planes(struct drm_crtc > *crtc) > intel_disable_planes(crtc); > intel_disable_primary_hw_plane(dev_priv, plane, pipe); > > + ilk_wm_synchronize(intel_crtc); > + > drm_vblank_off(dev, pipe); > } > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index 1ec4379..5ad7ad5 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1021,6 +1021,7 @@ void intel_program_watermarks_pre(struct intel_crtc > *crtc, > const struct intel_crtc_wm_config *config); > void intel_program_watermarks_post(struct intel_crtc *crtc, > const struct intel_crtc_wm_config *config); > +void ilk_wm_synchronize(struct intel_crtc *crtc); > > > /* intel_sdvo.c */ > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index 13366b7..1c072cd 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -2812,6 +2812,7 @@ static bool ilk_pending_watermarks_ready(struct > intel_crtc *crtc) > > static bool ilk_refresh_pending_watermarks(struct drm_device *dev) > { > + struct drm_i915_private *dev_priv = dev->dev_private; > struct intel_crtc *crtc; > bool changed = false; > > @@ -2833,6 +2834,9 @@ static bool ilk_refresh_pending_watermarks(struct > drm_device *dev) > changed = true; > } > > + if (changed) > + wake_up_all(&dev_priv->wm.wait); > + > return changed; > } > > @@ -3029,6 +3033,33 @@ static void ilk_wm_cancel(struct intel_crtc *crtc) > } > } > > +void ilk_wm_synchronize(struct intel_crtc *crtc) > +{ > + struct drm_device *dev = crtc->base.dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + enum pipe pipe = crtc->pipe; > + unsigned long timeout = msecs_to_jiffies(100); > + > + wait_event_timeout(dev_priv->wm.wait, !crtc->wm.dirty, timeout); > + > + mutex_lock(&dev_priv->wm.mutex); > + > + spin_lock_irq(&crtc->wm.lock); > + > + WARN(crtc->wm.dirty, "pipe %c watermark updates failed to complete\n", > + pipe_name(pipe)); > + > + /* clean up if something is left behind */ > + ilk_wm_cancel(crtc); > + > + spin_unlock_irq(&crtc->wm.lock); > + > + /* pending update (if any) got cancelled */ > + crtc->wm.pending = crtc->wm.active; > + > + mutex_unlock(&dev_priv->wm.mutex); > +} > + > static int ilk_update_primary_wm(struct intel_crtc *crtc, > struct intel_crtc_wm_config *config) > { > @@ -6736,6 +6767,7 @@ void intel_init_pm(struct drm_device *dev) > struct drm_i915_private *dev_priv = dev->dev_private; > > mutex_init(&dev_priv->wm.mutex); > + init_waitqueue_head(&dev_priv->wm.wait); > INIT_WORK(&dev_priv->wm.work, ilk_watermark_work); > > if (HAS_FBC(dev)) { > -- > 1.8.5.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Paulo Zanoni _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx