From 99106bc17e667989b4c0af0a6afcbd6ddbada8fb Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Thu, 5 Nov 2015 13:11:38 +0200 Subject: [PATCH] drm/i915: Do graphics device reset under forcewake We have a timed release of a forcewake when using I915_READ/WRITE macros. wait_for() macro will go to quite long sleep if the first read doesn't satisfy the condition for successful exit. With these two interacting, it is possible that we lose the forcewake during the wait_for() and the subsequent read will reaquire forcewake. Further experiments with skl shows that when we lose forcewake, we lose the reset request we submitted. So reset request register is not power context saved. Grab forcewakes for all engines before starting the reset/request dance so that all requests stay valid for the duration of reset requisition across all the engines. v2: Add comment on power well sleeps. Wrap the reset handling under forcewake instead of just reset requests (Chris) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92774 Cc: Chris Wilson Reviewed-by: Chris Wilson Tested-by: Tomi Sarvela (v1, v2) Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1446721898-1450-1-git-send-email-mika.kuoppala@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_uncore.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 1663ea55e37c..43cba129a0c0 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1531,13 +1531,22 @@ static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *) int intel_gpu_reset(struct drm_device *dev) { + struct drm_i915_private *dev_priv = to_i915(dev); int (*reset)(struct drm_device *); + int ret; reset = intel_get_gpu_reset(dev); if (reset == NULL) return -ENODEV; - return reset(dev); + /* If the power well sleeps during the reset, the reset + * request may be dropped and never completes (causing -EIO). + */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + ret = reset(dev); + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); + + return ret; } bool intel_has_gpu_reset(struct drm_device *dev) -- 2.39.5