diff mbox

[63/66] drm/i915: Add PPGTT dumper

Message ID 1372375867-1003-64-git-send-email-ben@bwidawsk.net (mailing list archive)
State New, archived
Headers show

Commit Message

Ben Widawsky June 27, 2013, 11:31 p.m. UTC
Dump the aliasing PPGTT with it. The aliasing PPGTT should actually
always be empty.

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  3 +-
 drivers/gpu/drm/i915/i915_drv.h     |  1 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 60 +++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 15f29de..2dfa784 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1839,9 +1839,8 @@  static int i915_ppgtt_info(struct seq_file *m, void *data)
 	}
 	if (dev_priv->gtt.aliasing_ppgtt) {
 		struct i915_hw_ppgtt *ppgtt = dev_priv->gtt.aliasing_ppgtt;
-
 		seq_printf(m, "aliasing PPGTT:\n");
-		seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
+		ppgtt->debug_dump(ppgtt, m);
 	}
 	seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 63ba242..f317d29 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -537,6 +537,7 @@  struct i915_hw_ppgtt {
 	int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
 			 struct intel_ring_buffer *ring);
 	void (*cleanup)(struct i915_hw_ppgtt *ppgtt);
+	void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m);
 };
 
 /* To make things as simple as possible (ie. no refcounting), a VMA's lifetime
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e42059a..cb151fc6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -100,6 +100,65 @@  static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
 	return pte;
 }
 
+static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
+{
+	struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
+	struct i915_hw_context *ctx =
+		container_of(ppgtt, struct i915_hw_context, ppgtt);
+	gen6_gtt_pte_t __iomem *pd_addr;
+	gen6_gtt_pte_t scratch_pte;
+	uint32_t pd_entry;
+	bool found = false;
+	int pte, pde;
+
+	scratch_pte = ppgtt->base.pte_encode(ppgtt->base.scratch.addr,
+					     I915_CACHE_LLC);
+
+
+	pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
+		ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
+
+	seq_printf(m, "  Context %d (pd_offset %x-%x):\n", ctx->id,
+		   ppgtt->pd_offset, ppgtt->pd_offset + ppgtt->num_pd_entries);
+	for (pde = 0; pde < ppgtt->num_pd_entries; pde++) {
+		u32 expected;
+		gen6_gtt_pte_t *pt_vaddr;
+		dma_addr_t pt_addr = ppgtt->pt_dma_addr[pde];
+		pd_entry = readl(pd_addr + pde);
+		expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
+
+		if (pd_entry != expected)
+			seq_printf(m, "\tPDE #%d mismatch: Actual PDE: %x Expected PDE: %x\n",
+				   pde,
+				   pd_entry,
+				   expected);
+#if 0
+		seq_printf(m, "\tPDE: %x\n", pd_entry);
+#endif
+
+		pt_vaddr = kmap_atomic(ppgtt->pt_pages[pde]);
+		for (pte = 0; pte < I915_PPGTT_PT_ENTRIES; pte++) {
+			unsigned long va =
+				(pde * PAGE_SIZE * I915_PPGTT_PT_ENTRIES) +
+				(pte * PAGE_SIZE);
+			if (pt_vaddr[pte] != scratch_pte) {
+				seq_printf(m, "\t\t0x%lx [%03d,%04d]: = %08x %08x %08x %08x\n",
+					   va,
+					   pde, pte,
+					   pt_vaddr[pte],
+					   pt_vaddr[pte],
+					   pt_vaddr[pte],
+					   pt_vaddr[pte]);
+				found = true;
+			}
+		}
+		kunmap_atomic(pt_vaddr);
+	}
+
+	if (!found)
+		seq_puts(m, "\tempty\n");
+}
+
 static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
 {
 	struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
@@ -391,6 +450,7 @@  alloc:
 	ppgtt->enable = gen6_ppgtt_enable;
 	ppgtt->switch_mm = gen6_mm_switch;
 	ppgtt->cleanup = gen6_ppgtt_cleanup;
+	ppgtt->debug_dump = gen6_dump_ppgtt;
 
 	vm->clear_range = gen6_ppgtt_clear_range;
 	vm->insert_entries = gen6_ppgtt_insert_entries;