From a9b9185e0b125e0fd6f2182d75c4e9b369e2640e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 2 Nov 2012 11:14:00 -0700 Subject: [PATCH] --- yaml --- r: 345282 b: refs/heads/master c: 1a01ab3b2dc4394c46c4c3230805748f632f6f74 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 2 ++ trunk/drivers/gpu/drm/i915/i915_drv.h | 2 ++ trunk/drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index c0a65c9f6bd3..47759522bf33 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 073f34d9d49bdbadbea8198ddc3fbb7e736a94dd +refs/heads/master: 1a01ab3b2dc4394c46c4c3230805748f632f6f74 diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index cfd8920537c5..577858bd0809 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -474,6 +474,8 @@ static int i915_drm_freeze(struct drm_device *dev) return error; } + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); + intel_modeset_disable(dev); drm_irq_uninstall(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index f8fa63deb92c..8db7bb9899b9 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -562,6 +562,8 @@ struct intel_gen6_power_mgmt { u8 cur_delay; u8 min_delay; u8 max_delay; + + struct delayed_work delayed_resume_work; }; struct intel_ilk_power_mgmt { diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index b6d980b0ac4c..169b416430db 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -3304,23 +3304,46 @@ static void intel_init_emon(struct drm_device *dev) void intel_disable_gt_powersave(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + if (IS_IRONLAKE_M(dev)) { ironlake_disable_drps(dev); ironlake_disable_rc6(dev); } else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) { + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); gen6_disable_rps(dev); } } +static void intel_gen6_powersave_work(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, struct drm_i915_private, + rps.delayed_resume_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->rps.delayed_resume_work, + round_jiffies_up_relative(HZ)); } } @@ -4216,6 +4239,8 @@ 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->rps.delayed_resume_work, + intel_gen6_powersave_work); } int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)