drm/i915/hsw: Fix GPU hang during resume from S3-devices state
Currently resuming on HSW from S3 pm_test/devices state leads to an unrecoverable GPU hang. Resetting the GPU during suspend fixes this. For a full S3 cycle this change only means the reset happens earlier (before reaching S3). For S4 the reset will happen now both during the freeze and quiesce phases, which is a benefit since it will guarantee that the GPU is idle before creating and loading the hibernation image. Cc: Mika Kuoppala <mika.kuoppala@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Suggested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1476283597-580-1-git-send-email-imre.deak@intel.com
This commit is contained in:
parent
45353ce59b
commit
1c777c5d1d
@ -532,32 +532,6 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
|
|||||||
|
|
||||||
static void i915_gem_fini(struct drm_device *dev)
|
static void i915_gem_fini(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Neither the BIOS, ourselves or any other kernel
|
|
||||||
* expects the system to be in execlists mode on startup,
|
|
||||||
* so we need to reset the GPU back to legacy mode. And the only
|
|
||||||
* known way to disable logical contexts is through a GPU reset.
|
|
||||||
*
|
|
||||||
* So in order to leave the system in a known default configuration,
|
|
||||||
* always reset the GPU upon unload. Afterwards we then clean up the
|
|
||||||
* GEM state tracking, flushing off the requests and leaving the
|
|
||||||
* system in a known idle state.
|
|
||||||
*
|
|
||||||
* Note that is of the upmost importance that the GPU is idle and
|
|
||||||
* all stray writes are flushed *before* we dismantle the backing
|
|
||||||
* storage for the pinned objects.
|
|
||||||
*
|
|
||||||
* However, since we are uncertain that reseting the GPU on older
|
|
||||||
* machines is a good idea, we don't - just in case it leaves the
|
|
||||||
* machine in an unusable condition.
|
|
||||||
*/
|
|
||||||
if (HAS_HW_CONTEXTS(dev)) {
|
|
||||||
int reset = intel_gpu_reset(dev_priv, ALL_ENGINES);
|
|
||||||
WARN_ON(reset && reset != -ENODEV);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
i915_gem_cleanup_engines(dev);
|
i915_gem_cleanup_engines(dev);
|
||||||
i915_gem_context_fini(dev);
|
i915_gem_context_fini(dev);
|
||||||
@ -636,6 +610,8 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup_gem:
|
cleanup_gem:
|
||||||
|
if (i915_gem_suspend(dev))
|
||||||
|
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
|
||||||
i915_gem_fini(dev);
|
i915_gem_fini(dev);
|
||||||
cleanup_irq:
|
cleanup_irq:
|
||||||
intel_guc_fini(dev);
|
intel_guc_fini(dev);
|
||||||
|
@ -4273,6 +4273,30 @@ int i915_gem_suspend(struct drm_device *dev)
|
|||||||
*/
|
*/
|
||||||
WARN_ON(dev_priv->gt.awake);
|
WARN_ON(dev_priv->gt.awake);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Neither the BIOS, ourselves or any other kernel
|
||||||
|
* expects the system to be in execlists mode on startup,
|
||||||
|
* so we need to reset the GPU back to legacy mode. And the only
|
||||||
|
* known way to disable logical contexts is through a GPU reset.
|
||||||
|
*
|
||||||
|
* So in order to leave the system in a known default configuration,
|
||||||
|
* always reset the GPU upon unload and suspend. Afterwards we then
|
||||||
|
* clean up the GEM state tracking, flushing off the requests and
|
||||||
|
* leaving the system in a known idle state.
|
||||||
|
*
|
||||||
|
* Note that is of the upmost importance that the GPU is idle and
|
||||||
|
* all stray writes are flushed *before* we dismantle the backing
|
||||||
|
* storage for the pinned objects.
|
||||||
|
*
|
||||||
|
* However, since we are uncertain that resetting the GPU on older
|
||||||
|
* machines is a good idea, we don't - just in case it leaves the
|
||||||
|
* machine in an unusable condition.
|
||||||
|
*/
|
||||||
|
if (HAS_HW_CONTEXTS(dev)) {
|
||||||
|
int reset = intel_gpu_reset(dev_priv, ALL_ENGINES);
|
||||||
|
WARN_ON(reset && reset != -ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
Loading…
Reference in New Issue
Block a user