| From b514407547890686572606c9dfa4b7f832db9958 Mon Sep 17 00:00:00 2001 |
| From: Jani Nikula <jani.nikula@intel.com> |
| Date: Thu, 17 Jan 2013 10:24:09 +0200 |
| Subject: drm/i915: fix FORCEWAKE posting reads |
| |
| From: Jani Nikula <jani.nikula@intel.com> |
| |
| commit b514407547890686572606c9dfa4b7f832db9958 upstream. |
| |
| We stopped reading FORCEWAKE for posting reads in |
| |
| commit 8dee3eea3ccd3b6c00a8d3a08dd715d6adf737dd |
| Author: Ben Widawsky <ben@bwidawsk.net> |
| Date: Sat Sep 1 22:59:50 2012 -0700 |
| |
| drm/i915: Never read FORCEWAKE |
| |
| and started using something from the same cacheline instead. On the |
| bug reporter's machine this broke entering rc6 states after a |
| suspend/resume cycle. It turns out reading ECOBUS as posting read |
| worked fine, while GTFIFODBG did not, preventing RC6 states after |
| suspend/resume per the bug report referenced below. It's not entirely |
| clear why, but clearly GTFIFODBG was nowhere near the same cacheline |
| or address range as FORCEWAKE. |
| |
| Trying out various registers for posting reads showed that all tested |
| registers for which NEEDS_FORCE_WAKE() (in i915_drv.c) returns true |
| work. Conversely, most (but not quite all) registers for which |
| NEEDS_FORCE_WAKE() returns false do not work. Details in the referenced |
| bug. |
| |
| Based on the above, add posting reads on ECOBUS where GTFIFODBG was |
| previously relied on. |
| |
| In true cargo cult spirit, add posting reads for FORCEWAKE_VLV writes as |
| well, but instead of ECOBUS, use FORCEWAKE_ACK_VLV which is in the same |
| address range as FORCEWAKE_VLV. |
| |
| v2: Add more details to the commit message. No functional changes. |
| |
| Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=52411 |
| Reported-and-tested-by: Alexander Bersenev <bay@hackerdom.ru> |
| CC: Ben Widawsky <ben@bwidawsk.net> |
| Signed-off-by: Jani Nikula <jani.nikula@intel.com> |
| Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Cc: stable@vger.kernel.org |
| [danvet: add cc: stable and make the commit message a bit clearer that |
| this is a regression fix and what exactly broke.] |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Signed-off-by: CAI Qian <caiqian@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/i915/intel_pm.c | 15 ++++++++++----- |
| 1 file changed, 10 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/intel_pm.c |
| +++ b/drivers/gpu/drm/i915/intel_pm.c |
| @@ -4018,7 +4018,8 @@ static void __gen6_gt_force_wake_get(str |
| DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
| |
| I915_WRITE_NOTRACE(FORCEWAKE, 1); |
| - POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ |
| + /* something from same cacheline, but !FORCEWAKE */ |
| + POSTING_READ(ECOBUS); |
| |
| if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1), |
| FORCEWAKE_ACK_TIMEOUT_MS)) |
| @@ -4041,7 +4042,8 @@ static void __gen6_gt_force_wake_mt_get( |
| DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
| |
| I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); |
| - POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ |
| + /* something from same cacheline, but !FORCEWAKE */ |
| + POSTING_READ(ECOBUS); |
| |
| if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1), |
| FORCEWAKE_ACK_TIMEOUT_MS)) |
| @@ -4078,14 +4080,16 @@ void gen6_gt_check_fifodbg(struct drm_i9 |
| static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
| { |
| I915_WRITE_NOTRACE(FORCEWAKE, 0); |
| - /* gen6_gt_check_fifodbg doubles as the POSTING_READ */ |
| + /* something from same cacheline, but !FORCEWAKE */ |
| + POSTING_READ(ECOBUS); |
| gen6_gt_check_fifodbg(dev_priv); |
| } |
| |
| static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
| { |
| I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); |
| - /* gen6_gt_check_fifodbg doubles as the POSTING_READ */ |
| + /* something from same cacheline, but !FORCEWAKE_MT */ |
| + POSTING_READ(ECOBUS); |
| gen6_gt_check_fifodbg(dev_priv); |
| } |
| |
| @@ -4140,7 +4144,8 @@ static void vlv_force_wake_get(struct dr |
| static void vlv_force_wake_put(struct drm_i915_private *dev_priv) |
| { |
| I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(1)); |
| - /* The below doubles as a POSTING_READ */ |
| + /* something from same cacheline, but !FORCEWAKE_VLV */ |
| + POSTING_READ(FORCEWAKE_ACK_VLV); |
| gen6_gt_check_fifodbg(dev_priv); |
| } |
| |