Reviewed and tested on My SNB fixing bug: https://bugs.freedesktop.org/show_bug.cgi?id=54089 Reviewed-by: Rodrigo Vivi <rodrigo.vivi at gmail.com> Tested-by: Rodrigo Vivi <rodrigo.vivi at gmail.com> On Fri, Oct 26, 2012 at 3:08 PM, Jesse Barnes <jbarnes at virtuousgeek.org> wrote: > Communicating via the mailbox registers with the PCU can take quite > awhile. And updating the ring frequency or enabling turbo is not > something that needs to happen synchronously, so take it out of our init > and resume paths to speed things up (~200ms on my T420). > > v2: add comment about why we use a work queue (Daniel) > make sure work queue is idle on suspend (Daniel) > use a delayed work queue since there's no hurry (Daniel) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=54089 > > Signed-of-by: Jesse Barnes <jbarnes at virtuougseek.org> > --- > drivers/gpu/drm/i915/i915_dma.c | 1 + > drivers/gpu/drm/i915/i915_drv.c | 2 ++ > drivers/gpu/drm/i915/i915_drv.h | 3 +++ > drivers/gpu/drm/i915/intel_pm.c | 32 ++++++++++++++++++++++++++++++-- > 4 files changed, 36 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c > index 14526dc..b5977b4 100644 > --- a/drivers/gpu/drm/i915/i915_dma.c > +++ b/drivers/gpu/drm/i915/i915_dma.c > @@ -1725,6 +1725,7 @@ int i915_driver_unload(struct drm_device *dev) > if (drm_core_check_feature(dev, DRIVER_MODESET)) { > intel_fbdev_fini(dev); > intel_modeset_cleanup(dev); > + intel_gt_cleanup(dev); > cancel_work_sync(&dev_priv->console_resume_work); > > /* > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 6d1fb51..4d858a9 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -470,6 +470,8 @@ static int i915_drm_freeze(struct drm_device *dev) > return error; > } > > + intel_gt_cleanup(dev); > + > intel_modeset_disable(dev); > > drm_irq_uninstall(dev); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index a5b0456..1e84a59 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -871,6 +871,8 @@ typedef struct drm_i915_private { > int r_t; > } ips; > > + struct delayed_work gen6_power_work; > + > enum no_fbc_reason no_fbc_reason; > > struct drm_mm_node *compressed_fb; > @@ -1268,6 +1270,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged); > extern void intel_irq_init(struct drm_device *dev); > extern void intel_gt_init(struct drm_device *dev); > extern void intel_gt_reset(struct drm_device *dev); > +extern void intel_gt_cleanup(struct drm_device *dev); > > void i915_error_state_free(struct kref *error_ref); > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index 59068be..025abbf 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -3312,15 +3312,34 @@ void intel_disable_gt_powersave(struct drm_device *dev) > } > } > > +static void intel_gen6_powersave_work(struct work_struct *work) > +{ > + struct drm_i915_private *dev_priv = > + container_of(work, struct drm_i915_private, > + gen6_power_work.work); > + struct drm_device *dev = dev_priv->dev; > + > + mutex_lock(&dev->struct_mutex); > + gen6_enable_rps(dev); > + gen6_update_ring_freq(dev); > + mutex_unlock(&dev->struct_mutex); > +} > + > void intel_enable_gt_powersave(struct drm_device *dev) > { > + struct drm_i915_private *dev_priv = dev->dev_private; > + > if (IS_IRONLAKE_M(dev)) { > ironlake_enable_drps(dev); > ironlake_enable_rc6(dev); > intel_init_emon(dev); > } else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { > - gen6_enable_rps(dev); > - gen6_update_ring_freq(dev); > + /* > + * PCU communication is slow and this doesn't need to be > + * done at any specific time, so do this out of our fast path > + * to make resume and init faster. > + */ > + schedule_delayed_work(&dev_priv->gen6_power_work, HZ); > } > } > > @@ -4175,6 +4194,15 @@ void intel_gt_init(struct drm_device *dev) > dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; > dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; > } > + INIT_DELAYED_WORK(&dev_priv->gen6_power_work, > + intel_gen6_powersave_work); > +} > + > +void intel_gt_cleanup(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + > + cancel_delayed_work_sync(&dev_priv->gen6_power_work); > } > > int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Rodrigo Vivi Blog: http://blog.vivi.eng.br