>From f49cbb9fd7131e49414a15c9041195d089411973 Mon Sep 17 00:00:00 2001 Message-Id: <f49cbb9fd7131e49414a15c9041195d089411973.1387201899.git.ian.lister@xxxxxxxxx> In-Reply-To: <cover.1387201899.git.ian.lister@xxxxxxxxx> References: <cover.1387201899.git.ian.lister@xxxxxxxxx> From: ian-lister <ian.lister@xxxxxxxxx> Date: Tue, 10 Dec 2013 16:37:12 +0000 Subject: [RFC 09/13] drm/i915: Watchdog timer support functions This is part of a series of patches to enable watchdog support. This patch adds the i915_ring_start_watchdog/i915_ring_stop_watchdog functions. These functions can be used to insert the timer start/stop commands onto the ring to surround a section of commands that need to be protected by watchdog timeout. The i915_ring_watchdog_supported function can be used to query which rings have the required hardware for watchdog support. Signed-off-by: ian-lister <ian.lister@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_ringbuffer.c | 84 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +++ 3 files changed, 92 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e896bca..a0bbf82 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -735,6 +735,8 @@ #define RING_SYNC_2(base) ((base)+0x48) #define RING_MI_MODE(base) ((base)+0x9c) #define RING_UHPTR(base) ((base)+0x134) +#define RING_CNTR(base) ((base)+0x178) +#define RING_THRESH(base) ((base)+0x17c) #define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE)) #define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE)) #define GEN6_RVESYNC (RING_SYNC_2(RENDER_RING_BASE)) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 42e9ee6..2a0091d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2597,3 +2597,87 @@ intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring) ring->gpu_caches_dirty = false; return 0; } + +int +intel_ring_watchdog_supported(struct intel_ring_buffer *ring) +{ + /* Return 1 if the ring supports watchdog reset, otherwise 0 */ + if (ring) { + switch (ring->id) { + case RCS: + case VCS: + return 1; + default: + return 0; + } + } + + return 0; +} + +int +intel_ring_start_watchdog(struct intel_ring_buffer *ring) +{ + int ret; + + ret = intel_ring_begin(ring, 10); + if (ret) + return ret; + + /* i915_reg.h includes a warning to place a MI_NOOP + * before an MI_LOAD_REGISTER_IMM */ + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_NOOP); + + /* Set counter period */ + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, RING_THRESH(ring->mmio_base)); + intel_ring_emit(ring, ring->hangcheck.watchdog_threshold); + intel_ring_emit(ring, MI_NOOP); + + /* Start counter */ + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, RING_CNTR(ring->mmio_base)); + intel_ring_emit(ring, WATCHDOG_ENABLE); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + + +int +intel_ring_stop_watchdog(struct intel_ring_buffer *ring) +{ + int ret; + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + /* i915_reg.h includes a warning to place a MI_NOOP + * before an MI_LOAD_REGISTER_IMM*/ + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_NOOP); + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, RING_CNTR(ring->mmio_base)); + + switch (ring->id) { + default: + case RCS: + intel_ring_emit(ring, RCS_WATCHDOG_DISABLE); + break; + case VCS: + intel_ring_emit(ring, VCS_WATCHDOG_DISABLE); + break; + } + + intel_ring_emit(ring, MI_NOOP); + + intel_ring_advance(ring); + + return 0; +} + + diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c3d6cbb..91c10b7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -18,6 +18,9 @@ struct intel_hw_status_page { struct drm_i915_gem_object *obj; }; +#define WATCHDOG_ENABLE 0 +#define RCS_WATCHDOG_DISABLE 1 +#define VCS_WATCHDOG_DISABLE 0xFFFFFFFF /* These values must match the requirements of the ring save/restore functions * which will vary for each chip*/ @@ -322,5 +325,8 @@ int intel_ring_save(struct intel_ring_buffer *ring, u32 flags); int intel_ring_restore(struct intel_ring_buffer *ring); +int intel_ring_watchdog_supported(struct intel_ring_buffer *ring); +int intel_ring_start_watchdog(struct intel_ring_buffer *ring); +int intel_ring_stop_watchdog(struct intel_ring_buffer *ring); #endif /* _INTEL_RINGBUFFER_H_ */ -- 1.8.5.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx