aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-02 10:51:03 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-07-03 16:09:21 -0400
commitc4de7b0ffda2bb4843fd7f1052d0a2bb90bd08a5 (patch)
treeb6806b54c43e44dd15e1bf7bf3480a4f47b8edcd /drivers/gpu
parent990bbdadabaa51828e475eda86ee5720a4910cc3 (diff)
drm/i915: Implement w/a for sporadic read failures on waking from rc6
As a w/a to prevent reads sporadically returning 0, we need to wait for the GT thread to return to TC0 before proceeding to read the registers. v2: adapt for Haswell changes (Eugeni). v3: use wait_for_atomic_us for thread status polling. v3: *really* use wait_for_atomic for polling. References: https://bugs.freedesktop.org/show_bug.cgi?id=50243 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Acked-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c22
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
2 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 928b6677759d..a4ea4a9fc425 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -433,6 +433,22 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
433 return 1; 433 return 1;
434} 434}
435 435
436static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
437{
438 u32 gt_thread_status_mask;
439
440 if (IS_HASWELL(dev_priv->dev))
441 gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW;
442 else
443 gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK;
444
445 /* w/a for a sporadic read returning 0 by waiting for the GT
446 * thread to wake up.
447 */
448 if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500))
449 DRM_ERROR("GT thread status wait timed out\n");
450}
451
436static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) 452static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
437{ 453{
438 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500)) 454 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500))
@@ -442,6 +458,8 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
442 458
443 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500)) 459 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500))
444 DRM_ERROR("Force wake wait timed out\n"); 460 DRM_ERROR("Force wake wait timed out\n");
461
462 __gen6_gt_wait_for_thread_c0(dev_priv);
445} 463}
446 464
447static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) 465static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
@@ -453,6 +471,8 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
453 471
454 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500)) 472 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500))
455 DRM_ERROR("Force wake wait timed out\n"); 473 DRM_ERROR("Force wake wait timed out\n");
474
475 __gen6_gt_wait_for_thread_c0(dev_priv);
456} 476}
457 477
458/* 478/*
@@ -538,6 +558,8 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
538 558
539 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) 559 if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500))
540 DRM_ERROR("Force wake wait timed out\n"); 560 DRM_ERROR("Force wake wait timed out\n");
561
562 __gen6_gt_wait_for_thread_c0(dev_priv);
541} 563}
542 564
543static void vlv_force_wake_put(struct drm_i915_private *dev_priv) 565static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ac65e96ea98e..8b400e96de10 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1458,6 +1458,10 @@
1458#define DDRMPLL1 0X12c20 1458#define DDRMPLL1 0X12c20
1459#define PEG_BAND_GAP_DATA 0x14d68 1459#define PEG_BAND_GAP_DATA 0x14d68
1460 1460
1461#define GEN6_GT_THREAD_STATUS_REG 0x13805c
1462#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7
1463#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16))
1464
1461#define GEN6_GT_PERF_STATUS 0x145948 1465#define GEN6_GT_PERF_STATUS 0x145948
1462#define GEN6_RP_STATE_LIMITS 0x145994 1466#define GEN6_RP_STATE_LIMITS 0x145994
1463#define GEN6_RP_STATE_CAP 0x145998 1467#define GEN6_RP_STATE_CAP 0x145998