From c6df39b5ea6342323a42edfbeeca0a28c643d7ae Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 14 Apr 2014 20:24:29 +0300 Subject: drm/i915: get a runtime PM ref for the deferred GT powersave enabling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At least on VLV but probably on other platforms too we depend on RC6 being enabled for RPM, so disable RPM until the delayed RC6 enabling completes. v2: - explain the reason for the _noresume version of RPM get (Daniel) - use the simpler 'if (schedule_work()) rpm_get();' instead of 'if (!cancel_work_sync()) rpm_get(); schedule_work();' Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e5b9f08d1098..0e8b263965f2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4549,6 +4549,8 @@ static void intel_gen6_powersave_work(struct work_struct *work) } dev_priv->rps.enabled = true; mutex_unlock(&dev_priv->rps.hw_lock); + + intel_runtime_pm_put(dev_priv); } void intel_enable_gt_powersave(struct drm_device *dev) @@ -4566,12 +4568,28 @@ void intel_enable_gt_powersave(struct drm_device *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. + * + * We depend on the HW RC6 power context save/restore + * mechanism when entering D3 through runtime PM suspend. So + * disable RPM until RPS/RC6 is properly setup. We can only + * get here via the driver load/system resume/runtime resume + * paths, so the _noresume version is enough (and in case of + * runtime resume it's necessary). */ - schedule_delayed_work(&dev_priv->rps.delayed_resume_work, - round_jiffies_up_relative(HZ)); + if (schedule_delayed_work(&dev_priv->rps.delayed_resume_work, + round_jiffies_up_relative(HZ))) + intel_runtime_pm_get_noresume(dev_priv); } } +void intel_reset_gt_powersave(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->rps.enabled = false; + intel_enable_gt_powersave(dev); +} + static void ibx_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6025,6 +6043,18 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) WARN(dev_priv->pm.suspended, "Device still suspended.\n"); } +void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + WARN(dev_priv->pm.suspended, "Getting nosync-ref while suspended.\n"); + pm_runtime_get_noresume(device); +} + void intel_runtime_pm_put(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; -- cgit v1.2.3