From cefd7d64ee5bc0abb3925b93eb98ecb891739cc8 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 31 Aug 2011 11:09:48 -0700 Subject: temp --- drivers/gpu/drm/i915/i915_debugfs.c | 22 ++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 175 ++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 8 ++ 3 files changed, 199 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3c395a59da35..b04b8fece112 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1274,6 +1274,27 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) return 0; } +static int i915_dump_ring_timestamps(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!i915_timestamp_batch) + return 0; + + i915_dump_object(m, dev_priv->mm.gtt_mapping, + dev_priv->ring[RCS].timestamp_obj); + if (dev_priv->ring[VCS].timestamp_obj) + i915_dump_object(m, dev_priv->mm.gtt_mapping, + dev_priv->ring[VCS].timestamp_obj); + if (dev_priv->ring[BCS].timestamp_obj) + i915_dump_object(m, dev_priv->mm.gtt_mapping, + dev_priv->ring[BCS].timestamp_obj); + + return 0; +} + static int i915_wedged_open(struct inode *inode, struct file *filp) @@ -1655,6 +1676,7 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_context_status", i915_context_status, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, + {"i915_dump_ring_timestamps", i915_dump_ring_timestamps, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4b9f325a6b72..e3db5855967d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -27,6 +27,7 @@ * */ +#include #include "drmP.h" #include "drm.h" #include "i915_drv.h" @@ -203,6 +204,14 @@ static int init_ring_common(struct intel_ring_buffer *ring) ring->space = ring_space(ring); } + if (i915_timestamp_batch) { + /* We'd like to use the generic ringbuffer interface... */ + ring->timestamp_obj = i915_gem_alloc_object(ring->dev, 4096); + if (WARN_ON(i915_gem_object_pin(ring->timestamp_obj, 4096, + true))) { + i915_gem_free_object(&ring->timestamp_obj->base); + } + } return 0; } @@ -696,12 +705,166 @@ bsd_ring_put_irq(struct intel_ring_buffer *ring) spin_unlock(&ring->irq_lock); } +static void +increment_timestamp_offset(struct intel_ring_buffer *ring, + struct intel_timestamp_data **ptr) +{ + u64 size; + if (!ring->timestamp_obj->gtt_space) + return; + + size = ring->timestamp_obj->gtt_space->size; + (*ptr)++; + if (((u64)ring->timestamp_head + sizeof(*ring->timestamp_head)) > size) + (*ptr) = 0; +} + +static inline uint32_t +get_timestamp_before(struct intel_ring_buffer *ring) +{ + return ((ring->timestamp_obj->gtt_offset)) + + ((uint32_t)((off_t)(&ring->timestamp_head->before))); +} + +static inline uint32_t +get_timestamp_after(struct intel_ring_buffer *ring) +{ + return ((ring->timestamp_obj->gtt_offset)) + + ((uint32_t)((off_t)(&ring->timestamp_head->after))); +} + +static inline uint32_t +get_timestamp_pid(struct intel_ring_buffer *ring) +{ + return ((ring->timestamp_obj->gtt_offset)) + + ((uint32_t)((off_t)(&ring->timestamp_head->pid))); +} + +static void +pc_insert_timestamp(struct intel_ring_buffer *ring, + bool before) +{ + struct drm_device *dev = ring->dev; + int ret; + u32 offset, pid_offset, dwords; + + if (WARN_ON_ONCE(ring->timestamp_obj == NULL)) + return; + + pid_offset = get_timestamp_pid(ring); + + if (before) { + dwords = 10; + offset = get_timestamp_before(ring); + } else { + dwords = 4; + offset = get_timestamp_after(ring); + } + + if (WARN_ON((offset % 8) || (pid_offset % 8))) + return; + + if (INTEL_INFO(dev)->gen >= 6) { + ret = intel_ring_begin(ring, dwords); + if (ret) + return; + + if (before) { + intel_ring_emit(ring, GFX_OP_PIPE_CONTROLn(3)); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); + intel_ring_emit(ring, (pid_offset) | + PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, current->pid); + intel_ring_emit(ring, 0); + } + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROLn(2)); + intel_ring_emit(ring, PIPE_CONTROL_TSC_WRITE); + intel_ring_emit(ring, offset | + PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, 0); + + if (before) + intel_ring_emit(ring, MI_NOOP); + else + increment_timestamp_offset(ring, &ring->timestamp_head); + } else if (INTEL_INFO(dev)->gen >= 4) { + ret = intel_ring_begin(ring, dwords); + if (ret) + return; + if (before) { + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | + PIPE_CONTROL_QW_WRITE | 2); + intel_ring_emit(ring, (pid_offset) | + PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, current->pid); + intel_ring_emit(ring, 0); + } + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | + PIPE_CONTROL_TSC_WRITE | 2); + intel_ring_emit(ring, offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + if (before) + intel_ring_emit(ring, MI_NOOP); + else + increment_timestamp_offset(ring, &ring->timestamp_head); + } else { + WARN_ONCE(1, "Gen3 GPUs are not supported"); + return; + } + + intel_ring_advance(ring); +} + static int -timestamp_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) +render_ring_timestamp_execbuffer(struct intel_ring_buffer *ring, + u32 offset, + u32 length) { - return ring->dispatch_execbuffer(ring, offset, length); + int ret; + pc_insert_timestamp(ring, true); + ret = ring->dispatch_execbuffer(ring, offset, length); + pc_insert_timestamp(ring, false); + return ret; } +static int +blt_timestamp_execbuffer(struct intel_ring_buffer *ring, + u32 offset, + u32 length) +{ + int ret; + + if (!intel_ring_begin(ring, 8)) { + intel_ring_emit(ring, MI_STORE_DWORD_IMM(3) | MI_MEM_VIRTUAL | +MI_STORE_DWORD_QWORD); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, get_timestamp_pid(ring)); + intel_ring_emit(ring, current->pid); + intel_ring_emit(ring, ring->name[0]); + intel_ring_emit(ring, MI_STORE_REGISTER_MEM); + intel_ring_emit(ring, 0x2358); + intel_ring_emit(ring, get_timestamp_before(ring)); + intel_ring_advance(ring); + } + + ret = ring->dispatch_execbuffer(ring, offset, length); + if (ret) + return ret; + + if (!intel_ring_begin(ring, 4)) { + intel_ring_emit(ring, MI_STORE_REGISTER_MEM); + intel_ring_emit(ring, 0x2358); + intel_ring_emit(ring, get_timestamp_after(ring)); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } + + increment_timestamp_offset(ring, &ring->timestamp_head); + + return ret; +} static int ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) { @@ -1032,7 +1195,7 @@ static const struct intel_ring_buffer render_ring = { .irq_get = render_ring_get_irq, .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, - .timestamp_execbuffer = timestamp_execbuffer, + .timestamp_execbuffer = render_ring_timestamp_execbuffer, .cleanup = render_ring_cleanup, }; @@ -1051,7 +1214,7 @@ static const struct intel_ring_buffer bsd_ring = { .irq_get = bsd_ring_get_irq, .irq_put = bsd_ring_put_irq, .dispatch_execbuffer = ring_dispatch_execbuffer, - .timestamp_execbuffer = timestamp_execbuffer, + .timestamp_execbuffer = NULL, }; @@ -1162,7 +1325,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .irq_get = gen6_bsd_ring_get_irq, .irq_put = gen6_bsd_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .timestamp_execbuffer = timestamp_execbuffer, + .timestamp_execbuffer = render_ring_timestamp_execbuffer, }; /* Blitter support (SandyBridge+) */ @@ -1293,7 +1456,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .timestamp_execbuffer = timestamp_execbuffer, + .timestamp_execbuffer = blt_timestamp_execbuffer, .cleanup = blt_ring_cleanup, }; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d313e2810552..9297b79ff437 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -33,6 +33,12 @@ struct intel_hw_status_page { #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) +struct intel_timestamp_data { + u64 pid; + u64 before; + u64 after; +} __attribute__((packed, aligned(8))); + struct intel_ring_buffer { const char *name; enum intel_ring_id { @@ -59,6 +65,8 @@ struct intel_ring_buffer { u32 trace_irq_seqno; u32 waiting_seqno; u32 sync_seqno[I915_NUM_RINGS-1]; + struct drm_i915_gem_object *timestamp_obj; + struct intel_timestamp_data *timestamp_head; bool __must_check (*irq_get)(struct intel_ring_buffer *ring); void (*irq_put)(struct intel_ring_buffer *ring); -- cgit v1.2.3