aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-06 14:01:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-29 12:47:37 -0400
commitce04434c6e596b264f92f39d3228883c60262b69 (patch)
tree9d857d5ff108d8c464203e2f70cde855c255eac7
parent749e7bffd3f71d4fadc0fb54eebce12a28d045e7 (diff)
drm/i915: Invalidate TLBs for the rings after a reset
commit 884020bf3d2a3787a1cc6df902e98e0eec60330b upstream. After any "soft gfx reset" we must manually invalidate the TLBs associated with each ring. Empirically, it seems that a suspend/resume or D3-D0 cycle count as a "soft reset". The symptom is that the hardware would fail to note the new address for its status page, and so it would continue to write the shadow registers and breadcrumbs into the old physical address (now used by something completely different, scary). Whereas the driver would read the new status page and never see any progress, it would appear that the GPU hung immediately upon resume. Based on a patch by naresh kumar kachhi <naresh.kumar.kacchi@intel.com> Reported-by: Thiago Macieira <thiago@kde.org> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64725 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: Thiago Macieira <thiago@kde.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c12
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 80b0a6626a23..01f6c2cf471f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -617,6 +617,8 @@
617 will not assert AGPBUSY# and will only 617 will not assert AGPBUSY# and will only
618 be delivered when out of C3. */ 618 be delivered when out of C3. */
619#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ 619#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */
620#define INSTPM_TLB_INVALIDATE (1<<9)
621#define INSTPM_SYNC_FLUSH (1<<5)
620#define ACTHD 0x020c8 622#define ACTHD 0x020c8
621#define FW_BLC 0x020d8 623#define FW_BLC 0x020d8
622#define FW_BLC2 0x020dc 624#define FW_BLC2 0x020dc
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1424f2042838..48fe23e8d180 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -907,6 +907,18 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
907 907
908 I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); 908 I915_WRITE(mmio, (u32)ring->status_page.gfx_addr);
909 POSTING_READ(mmio); 909 POSTING_READ(mmio);
910
911 /* Flush the TLB for this page */
912 if (INTEL_INFO(dev)->gen >= 6) {
913 u32 reg = RING_INSTPM(ring->mmio_base);
914 I915_WRITE(reg,
915 _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
916 INSTPM_SYNC_FLUSH));
917 if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0,
918 1000))
919 DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
920 ring->name);
921 }
910} 922}
911 923
912static int 924static int