From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [PATCH 3/3] drm/i915: Boost GPU frequency if we detect outstanding pageflips Date: Tue, 10 Jun 2014 15:32:08 +0300 Message-ID: <20140610123208.GB27580@intel.com> References: <1402394642-6263-1-git-send-email-chris@chris-wilson.co.uk> <1402394642-6263-3-git-send-email-chris@chris-wilson.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 2C1AB6E688 for ; Tue, 10 Jun 2014 05:32:12 -0700 (PDT) Content-Disposition: inline In-Reply-To: <1402394642-6263-3-git-send-email-chris@chris-wilson.co.uk> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Chris Wilson Cc: Daniel Vetter , intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org On Tue, Jun 10, 2014 at 11:04:02AM +0100, Chris Wilson wrote: > If we hit a vblank and see that have a pageflip queue but not yet > processed, ensure that the GPU is running at maximum in order to clear > the backlog. Pageflips are only queued for the following vblank, if we > miss it, there will be a visible stutter. Boosting the GPU frequency > doesn't prevent us from missing the target vblank, but it should help > the subsequent frames hitting theirs. > = > v2: Reorder vblank vs flip-complete so that we only check for a missed > flip after processing the completion events, and avoid spurious boosts. > = > v3: Rename missed_vblank > = > Signed-off-by: Chris Wilson > Cc: Daniel Vetter > Cc: Ville Syrj=E4l=E4 > --- > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/intel_display.c | 6 ++++++ > drivers/gpu/drm/i915/intel_drv.h | 1 + > drivers/gpu/drm/i915/intel_pm.c | 15 +++++++++++++++ > 4 files changed, 23 insertions(+) > = > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_= drv.h > index 10dd80a..33ed0c6 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -910,6 +910,7 @@ struct intel_gen6_power_mgmt { > = > bool enabled; > struct delayed_work delayed_resume_work; > + struct work_struct boost_work; > = > /* > * Protects RPS/RC6 register access and PCU communication. > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/= intel_display.c > index 9ecc6bf..aeb58fa 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -9339,6 +9339,7 @@ void intel_check_page_flip(struct drm_device *dev, = int pipe) > struct drm_crtc *crtc =3D dev_priv->pipe_to_crtc_mapping[pipe]; > struct intel_crtc *intel_crtc =3D to_intel_crtc(crtc); > unsigned long flags; > + bool missed_vblank; > = > if (crtc =3D=3D NULL) > return; > @@ -9349,7 +9350,12 @@ void intel_check_page_flip(struct drm_device *dev,= int pipe) > intel_crtc->unpin_work->sbc, crtc_sbc(intel_crtc)); > page_flip_completed(intel_crtc); > } > + missed_vblank =3D (intel_crtc->unpin_work !=3D NULL && > + crtc_sbc(intel_crtc) - intel_crtc->unpin_work->sbc > 1); > spin_unlock_irqrestore(&dev->event_lock, flags); > + > + if (missed_vblank) > + intel_queue_rps_boost(dev); > } > = > static int intel_crtc_page_flip(struct drm_crtc *crtc, > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/inte= l_drv.h > index ac902ad..75fba0d 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -966,6 +966,7 @@ void ironlake_teardown_rc6(struct drm_device *dev); > void gen6_update_ring_freq(struct drm_device *dev); > void gen6_rps_idle(struct drm_i915_private *dev_priv); > void gen6_rps_boost(struct drm_i915_private *dev_priv); > +void intel_queue_rps_boost(struct drm_device *dev); > void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv); > void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv); > void intel_runtime_pm_get(struct drm_i915_private *dev_priv); > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel= _pm.c > index b06f896..ab760e5 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -6722,6 +6722,19 @@ int vlv_freq_opcode(struct drm_i915_private *dev_p= riv, int val) > return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6; > } > = > +static void __intel_rps_boost_work(struct work_struct *work) > +{ > + gen6_rps_boost(container_of(work, struct drm_i915_private, rps.boost_wo= rk)); gen6_rps_boost() checks for rps.enabled so it doesn't matter when this gets scheduled wrt. rps enable/disable. Check. And we have a flush_workqueue() in unload path after the modeset cleanup, so the work should be done by the time the workqueue gets torn down. Check. Reviewed-by: Ville Syrj=E4l=E4 > +} > + > +void intel_queue_rps_boost(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv =3D to_i915(dev); > + > + if (INTEL_INFO(dev)->gen >=3D 6) > + queue_work(dev_priv->wq, &dev_priv->rps.boost_work); > +} > + > void intel_pm_setup(struct drm_device *dev) > { > struct drm_i915_private *dev_priv =3D dev->dev_private; > @@ -6730,6 +6743,8 @@ void intel_pm_setup(struct drm_device *dev) > = > INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, > intel_gen6_powersave_work); > + INIT_WORK(&dev_priv->rps.boost_work, > + __intel_rps_boost_work); > = > dev_priv->pm.suspended =3D false; > dev_priv->pm.irqs_disabled =3D false; > -- = > 1.7.9.5 -- = Ville Syrj=E4l=E4 Intel OTC