Commit 54b4f68f authored by Chris Wilson's avatar Chris Wilson

Revert "drm/i915: Enable RC6 immediately"

This reverts commit b12e0ee2 ("drm/i915: Enable RC6 immediately"),
as it was never meant to be sent anywhere other than the bug report for
experimentation.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1469132179-4052-1-git-send-email-chris@chris-wilson.co.ukAcked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 843759a5
...@@ -1630,6 +1630,7 @@ static int i915_drm_resume(struct drm_device *dev) ...@@ -1630,6 +1630,7 @@ static int i915_drm_resume(struct drm_device *dev)
intel_opregion_notify_adapter(dev_priv, PCI_D0); intel_opregion_notify_adapter(dev_priv, PCI_D0);
intel_autoenable_gt_powersave(dev_priv);
drm_kms_helper_poll_enable(dev); drm_kms_helper_poll_enable(dev);
enable_rpm_wakeref_asserts(dev_priv); enable_rpm_wakeref_asserts(dev_priv);
...@@ -1811,8 +1812,7 @@ int i915_reset(struct drm_i915_private *dev_priv) ...@@ -1811,8 +1812,7 @@ int i915_reset(struct drm_i915_private *dev_priv)
* previous concerns that it doesn't respond well to some forms * previous concerns that it doesn't respond well to some forms
* of re-init after reset. * of re-init after reset.
*/ */
if (INTEL_GEN(dev_priv) > 5) intel_autoenable_gt_powersave(dev_priv);
intel_enable_gt_powersave(dev_priv);
return 0; return 0;
...@@ -2440,7 +2440,6 @@ static int intel_runtime_resume(struct device *device) ...@@ -2440,7 +2440,6 @@ static int intel_runtime_resume(struct device *device)
i915_gem_init_swizzling(dev); i915_gem_init_swizzling(dev);
intel_runtime_pm_enable_interrupts(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv);
intel_enable_gt_powersave(dev_priv);
/* /*
* On VLV/CHV display interrupts are part of the display * On VLV/CHV display interrupts are part of the display
......
...@@ -1192,6 +1192,7 @@ struct intel_gen6_power_mgmt { ...@@ -1192,6 +1192,7 @@ struct intel_gen6_power_mgmt {
bool client_boost; bool client_boost;
bool enabled; bool enabled;
struct delayed_work autoenable_work;
unsigned boosts; unsigned boosts;
/* manual wa residency calculations */ /* manual wa residency calculations */
......
...@@ -4355,6 +4355,8 @@ i915_gem_suspend(struct drm_device *dev) ...@@ -4355,6 +4355,8 @@ i915_gem_suspend(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
int ret = 0; int ret = 0;
intel_suspend_gt_powersave(dev_priv);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/* We have to flush all the executing contexts to main memory so /* We have to flush all the executing contexts to main memory so
......
...@@ -405,6 +405,7 @@ static void i915_gem_mark_busy(const struct intel_engine_cs *engine) ...@@ -405,6 +405,7 @@ static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
intel_runtime_pm_get_noresume(dev_priv); intel_runtime_pm_get_noresume(dev_priv);
dev_priv->gt.awake = true; dev_priv->gt.awake = true;
intel_enable_gt_powersave(dev_priv);
i915_update_gfx_val(dev_priv); i915_update_gfx_val(dev_priv);
if (INTEL_GEN(dev_priv) >= 6) if (INTEL_GEN(dev_priv) >= 6)
gen6_rps_busy(dev_priv); gen6_rps_busy(dev_priv);
......
...@@ -15502,7 +15502,6 @@ void intel_modeset_init_hw(struct drm_device *dev) ...@@ -15502,7 +15502,6 @@ void intel_modeset_init_hw(struct drm_device *dev)
dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
intel_init_clock_gating(dev); intel_init_clock_gating(dev);
intel_enable_gt_powersave(dev_priv);
} }
/* /*
......
...@@ -1691,9 +1691,12 @@ void intel_pm_setup(struct drm_device *dev); ...@@ -1691,9 +1691,12 @@ void intel_pm_setup(struct drm_device *dev);
void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
void intel_gpu_ips_teardown(void); void intel_gpu_ips_teardown(void);
void intel_init_gt_powersave(struct drm_i915_private *dev_priv); void intel_init_gt_powersave(struct drm_i915_private *dev_priv);
void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv);
void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv);
void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); void intel_enable_gt_powersave(struct drm_i915_private *dev_priv);
void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv);
void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); void intel_disable_gt_powersave(struct drm_i915_private *dev_priv);
void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
void gen6_rps_busy(struct drm_i915_private *dev_priv); void gen6_rps_busy(struct drm_i915_private *dev_priv);
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv); void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_idle(struct drm_i915_private *dev_priv);
......
...@@ -6526,6 +6526,8 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -6526,6 +6526,8 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
dev_priv->rps.boost_freq = dev_priv->rps.max_freq; dev_priv->rps.boost_freq = dev_priv->rps.max_freq;
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
intel_autoenable_gt_powersave(dev_priv);
} }
void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
...@@ -6539,10 +6541,31 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -6539,10 +6541,31 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
} }
/**
* intel_suspend_gt_powersave - suspend PM work and helper threads
* @dev_priv: i915 device
*
* We don't want to disable RC6 or other features here, we just want
* to make sure any work we've queued has finished and won't bother
* us while we're suspended.
*/
void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
{
if (INTEL_GEN(dev_priv) < 6)
return;
if (cancel_delayed_work_sync(&dev_priv->rps.autoenable_work))
intel_runtime_pm_put(dev_priv);
/* gen6_rps_idle() will be called later to disable interrupts */
}
void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
{ {
dev_priv->rps.enabled = true; /* force disabling */ dev_priv->rps.enabled = true; /* force disabling */
intel_disable_gt_powersave(dev_priv); intel_disable_gt_powersave(dev_priv);
gen6_reset_rps_interrupts(dev_priv);
} }
void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
...@@ -6567,12 +6590,13 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -6567,12 +6590,13 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
dev_priv->rps.enabled = false; dev_priv->rps.enabled = false;
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
gen6_reset_rps_interrupts(dev_priv);
} }
void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
{ {
/* We shouldn't be disabling as we submit, so this should be less
* racy than it appears!
*/
if (READ_ONCE(dev_priv->rps.enabled)) if (READ_ONCE(dev_priv->rps.enabled))
return; return;
...@@ -6608,9 +6632,75 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -6608,9 +6632,75 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq); WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq);
WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq);
dev_priv->rps.enabled = true;
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
} }
static void __intel_autoenable_gt_powersave(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), rps.autoenable_work.work);
struct intel_engine_cs *rcs;
struct drm_i915_gem_request *req;
if (READ_ONCE(dev_priv->rps.enabled))
goto out;
rcs = &dev_priv->engine[RCS];
if (rcs->last_context)
goto out;
if (!rcs->init_context)
goto out;
mutex_lock(&dev_priv->drm.struct_mutex);
req = i915_gem_request_alloc(rcs, dev_priv->kernel_context);
if (IS_ERR(req))
goto unlock;
if (!i915.enable_execlists && i915_switch_context(req) == 0)
rcs->init_context(req);
/* Mark the device busy, calling intel_enable_gt_powersave() */
i915_add_request_no_flush(req);
unlock:
mutex_unlock(&dev_priv->drm.struct_mutex);
out:
intel_runtime_pm_put(dev_priv);
}
void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
{
if (READ_ONCE(dev_priv->rps.enabled))
return;
if (IS_IRONLAKE_M(dev_priv)) {
ironlake_enable_drps(dev_priv);
mutex_lock(&dev_priv->drm.struct_mutex);
intel_init_emon(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
} else if (INTEL_INFO(dev_priv)->gen >= 6) {
/*
* 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).
*/
if (queue_delayed_work(dev_priv->wq,
&dev_priv->rps.autoenable_work,
round_jiffies_up_relative(HZ)))
intel_runtime_pm_get_noresume(dev_priv);
}
}
static void ibx_init_clock_gating(struct drm_device *dev) static void ibx_init_clock_gating(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
...@@ -7716,6 +7806,8 @@ void intel_pm_setup(struct drm_device *dev) ...@@ -7716,6 +7806,8 @@ void intel_pm_setup(struct drm_device *dev)
mutex_init(&dev_priv->rps.hw_lock); mutex_init(&dev_priv->rps.hw_lock);
spin_lock_init(&dev_priv->rps.client_lock); spin_lock_init(&dev_priv->rps.client_lock);
INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work,
__intel_autoenable_gt_powersave);
INIT_LIST_HEAD(&dev_priv->rps.clients); INIT_LIST_HEAD(&dev_priv->rps.clients);
dev_priv->pm.suspended = false; dev_priv->pm.suspended = false;
......
...@@ -435,7 +435,7 @@ void intel_uncore_sanitize(struct drm_i915_private *dev_priv) ...@@ -435,7 +435,7 @@ void intel_uncore_sanitize(struct drm_i915_private *dev_priv)
i915.enable_rc6 = sanitize_rc6_option(dev_priv, i915.enable_rc6); i915.enable_rc6 = sanitize_rc6_option(dev_priv, i915.enable_rc6);
/* BIOS often leaves RC6 enabled, but disable it for hw init */ /* BIOS often leaves RC6 enabled, but disable it for hw init */
intel_disable_gt_powersave(dev_priv); intel_sanitize_gt_powersave(dev_priv);
} }
static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv, static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment