drm/i915/bdw: Display execlists info in debugfs
authorOscar Mateo <oscar.mateo@intel.com>
Thu, 7 Aug 2014 12:23:20 +0000 (13:23 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 20 Aug 2014 15:17:49 +0000 (17:17 +0200)
v2: Warn and return if LRCs are not enabled.

v3: Grab the Execlists spinlock (noticed by Daniel Vetter).

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
v4: Lock the struct mutex for atomic state capture

Signed-off-by: Thomas Daniel <thomas.daniel@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
[danvet: Checkpatch.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_lrc.h

index d42db6bc34e07b1af72c3ccdec2832215bb5e518..68335813ef4cab011233ec38dea6976e34c5e846 100644 (file)
@@ -1721,6 +1721,86 @@ static int i915_context_status(struct seq_file *m, void *unused)
        return 0;
 }
 
+static int i915_execlists(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;
+       struct intel_engine_cs *ring;
+       u32 status_pointer;
+       u8 read_pointer;
+       u8 write_pointer;
+       u32 status;
+       u32 ctx_id;
+       struct list_head *cursor;
+       int ring_id, i;
+       int ret;
+
+       if (!i915.enable_execlists) {
+               seq_puts(m, "Logical Ring Contexts are disabled\n");
+               return 0;
+       }
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       for_each_ring(ring, dev_priv, ring_id) {
+               struct intel_ctx_submit_request *head_req = NULL;
+               int count = 0;
+               unsigned long flags;
+
+               seq_printf(m, "%s\n", ring->name);
+
+               status = I915_READ(RING_EXECLIST_STATUS(ring));
+               ctx_id = I915_READ(RING_EXECLIST_STATUS(ring) + 4);
+               seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n",
+                          status, ctx_id);
+
+               status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
+               seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer);
+
+               read_pointer = ring->next_context_status_buffer;
+               write_pointer = status_pointer & 0x07;
+               if (read_pointer > write_pointer)
+                       write_pointer += 6;
+               seq_printf(m, "\tRead pointer: 0x%08X, write pointer 0x%08X\n",
+                          read_pointer, write_pointer);
+
+               for (i = 0; i < 6; i++) {
+                       status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i);
+                       ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i + 4);
+
+                       seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n",
+                                  i, status, ctx_id);
+               }
+
+               spin_lock_irqsave(&ring->execlist_lock, flags);
+               list_for_each(cursor, &ring->execlist_queue)
+                       count++;
+               head_req = list_first_entry_or_null(&ring->execlist_queue,
+                               struct intel_ctx_submit_request, execlist_link);
+               spin_unlock_irqrestore(&ring->execlist_lock, flags);
+
+               seq_printf(m, "\t%d requests in queue\n", count);
+               if (head_req) {
+                       struct drm_i915_gem_object *ctx_obj;
+
+                       ctx_obj = head_req->ctx->engine[ring_id].state;
+                       seq_printf(m, "\tHead request id: %u\n",
+                                  intel_execlists_ctx_id(ctx_obj));
+                       seq_printf(m, "\tHead request tail: %u\n",
+                                  head_req->tail);
+               }
+
+               seq_putc(m, '\n');
+       }
+
+       mutex_unlock(&dev->struct_mutex);
+
+       return 0;
+}
+
 static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = m->private;
@@ -3974,6 +4054,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
        {"i915_opregion", i915_opregion, 0},
        {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
        {"i915_context_status", i915_context_status, 0},
+       {"i915_execlists", i915_execlists, 0},
        {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
        {"i915_swizzle_info", i915_swizzle_info, 0},
        {"i915_ppgtt_info", i915_ppgtt_info, 0},
index 6f6c5a931fafb188122d90e67ded09d4397e946f..cc923a96fa4cf2703166f06fcde38208f97fb5fb 100644 (file)
 
 #define GEN8_LR_CONTEXT_ALIGN 4096
 
-#define RING_ELSP(ring)                        ((ring)->mmio_base+0x230)
-#define RING_EXECLIST_STATUS(ring)     ((ring)->mmio_base+0x234)
-#define RING_CONTEXT_CONTROL(ring)     ((ring)->mmio_base+0x244)
-#define RING_CONTEXT_STATUS_BUF(ring)  ((ring)->mmio_base+0x370)
-#define RING_CONTEXT_STATUS_PTR(ring)  ((ring)->mmio_base+0x3a0)
-
 #define RING_EXECLIST_QFULL            (1 << 0x2)
 #define RING_EXECLIST1_VALID           (1 << 0x3)
 #define RING_EXECLIST0_VALID           (1 << 0x4)
index 331c6c2ba376dac2db7705e8b82b57c46410c3d3..117d1a4eb3b9e21a69b3444f5068893092c141df 100644 (file)
 #ifndef _INTEL_LRC_H_
 #define _INTEL_LRC_H_
 
+/* Execlists regs */
+#define RING_ELSP(ring)                        ((ring)->mmio_base+0x230)
+#define RING_EXECLIST_STATUS(ring)     ((ring)->mmio_base+0x234)
+#define RING_CONTEXT_CONTROL(ring)     ((ring)->mmio_base+0x244)
+#define RING_CONTEXT_STATUS_BUF(ring)  ((ring)->mmio_base+0x370)
+#define RING_CONTEXT_STATUS_PTR(ring)  ((ring)->mmio_base+0x3a0)
+
 /* Logical Rings */
 void intel_logical_ring_stop(struct intel_engine_cs *ring);
 void intel_logical_ring_cleanup(struct intel_engine_cs *ring);