Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c777c5d authored by Imre Deak's avatar Imre Deak
Browse files

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1476283597-580-1-git-send-email-imre.deak@intel.com
parent 45353ce5
Loading
Loading
Loading
Loading
+2 −26
Original line number Original line Diff line number Diff line
@@ -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);
+24 −0
Original line number Original line Diff line number Diff line
@@ -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: