i915_debugfs.c revision f4ceda89895b56e2c03dd327f13d0256838a20ab
12017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari/*
22017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * Copyright © 2008 Intel Corporation
32017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *
42017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * Permission is hereby granted, free of charge, to any person obtaining a
52017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * copy of this software and associated documentation files (the "Software"),
62017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * to deal in the Software without restriction, including without limitation
72017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * the rights to use, copy, modify, merge, publish, distribute, sublicense,
82017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * and/or sell copies of the Software, and to permit persons to whom the
92017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * Software is furnished to do so, subject to the following conditions:
102017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *
112017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * The above copyright notice and this permission notice (including the next
122017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * paragraph) shall be included in all copies or substantial portions of the
132017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * Software.
142017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *
152017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
162017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
172017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
182017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
192017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
202017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
212017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * IN THE SOFTWARE.
222017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *
232017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari * Authors:
242017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *    Eric Anholt <eric@anholt.net>
252017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *    Keith Packard <keithp@keithp.com>
262017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari *
272017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari */
282017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
292017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include <linux/seq_file.h>
302017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "drmP.h"
312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "drm.h"
322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "i915_drm.h"
332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "i915_drv.h"
342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#define DRM_I915_RING_DEBUG 1
362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#if defined(CONFIG_DEBUG_FS)
392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
40433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define ACTIVE_LIST	1
41433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define FLUSHING_LIST	2
42433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define INACTIVE_LIST	3
432017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
44433e12f78b68a8069f54956edf766bb21394c197Ben Gamaristatic int i915_gem_object_list_info(struct seq_file *m, void *data)
452017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
462017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
47433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	uintptr_t list = (uintptr_t) node->info_ent->data;
48433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	struct list_head *head;
492017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
502017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
512017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_object *obj_priv;
522017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
53433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	switch (list) {
54433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case ACTIVE_LIST:
55433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Active:\n");
56433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.active_list;
57433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
58433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case INACTIVE_LIST:
59433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Inctive:\n");
60433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.inactive_list;
61433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
62433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case FLUSHING_LIST:
63433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Flushing:\n");
64433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.flushing_list;
65433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
66433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	default:
67433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		DRM_INFO("Ooops, unexpected list\n");
68433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		return 0;
692017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
71433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	list_for_each_entry(obj_priv, head, list)
722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{
73f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		char *pin_description;
742017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		struct drm_gem_object *obj = obj_priv->obj;
75f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
76f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj_priv->user_pin_count > 0)
77f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			pin_description = "P";
78f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		else if (obj_priv->pin_count > 0)
79f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			pin_description = "p";
80f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		else
81f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			pin_description = " ";
82f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
83f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		seq_printf(m, "    %p: %s %08x %08x %d",
84f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj,
85f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   pin_description,
86f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj->read_domains, obj->write_domain,
87f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj_priv->last_rendering_seqno);
88f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
89f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj->name)
90f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			seq_printf(m, " (name: %d)", obj->name);
91f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
92f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			seq_printf(m, " (fence: %d\n", obj_priv->fence_reg);
93f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		seq_printf(m, "\n");
942017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
952017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
962017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
972017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
982017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_request_info(struct seq_file *m, void *data)
992017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1002017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1012017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1022017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1032017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_request *gem_request;
1042017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1052017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Request:\n");
1062017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
1072017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "    %d @ %d\n",
1082017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   gem_request->seqno,
1092017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   (int) (jiffies - gem_request->emitted_jiffies));
1102017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1112017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1122017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1132017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1142017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_seqno_info(struct seq_file *m, void *data)
1152017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1162017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1172017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1182017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1192017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1202017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1212017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: %d\n",
1222017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
1232017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
1242017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: hws uninitialized\n");
1252017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1262017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:  %d\n",
1272017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			dev_priv->mm.waiting_gem_seqno);
1282017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
1292017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1302017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_interrupt_info(struct seq_file *m, void *data)
1342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt enable:    %08x\n",
1402017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IER));
1412017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt identity:  %08x\n",
1422017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IIR));
1432017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt mask:      %08x\n",
1442017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IMR));
1452017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Pipe A stat:         %08x\n",
1462017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(PIPEASTAT));
1472017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Pipe B stat:         %08x\n",
1482017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(PIPEBSTAT));
1492017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupts received: %d\n",
1502017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   atomic_read(&dev_priv->irq_received));
1512017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1522017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    %d\n",
1532017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
1542017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
1552017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    hws uninitialized\n");
1562017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1572017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:     %d\n",
1582017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.waiting_gem_seqno);
1592017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:        %d\n",
1602017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.irq_gem_seqno);
1612017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1622017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1632017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1642017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_hws_info(struct seq_file *m, void *data)
1652017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1662017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1672017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1682017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1692017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	int i;
1702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	volatile u32 *hws;
1712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	hws = (volatile u32 *)dev_priv->hw_status_page;
1732017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (hws == NULL)
1742017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		return 0;
1752017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1762017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
1772017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1782017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i * 4,
1792017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
1802017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1812017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1822017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1832017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1842017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic struct drm_info_list i915_gem_debugfs_list[] = {
185433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
186433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
187433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
1882017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_request", i915_gem_request_info, 0},
1892017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_seqno", i915_gem_seqno_info, 0},
1902017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_interrupt", i915_interrupt_info, 0},
1912017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_hws", i915_hws_info, 0},
1922017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari};
1932017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
1942017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1952017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamariint i915_gem_debugfs_init(struct drm_minor *minor)
1962017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1972017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return drm_debugfs_create_files(i915_gem_debugfs_list,
1982017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari					I915_GEM_DEBUGFS_ENTRIES,
1992017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari					minor->debugfs_root, minor);
2002017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
2012017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2022017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamarivoid i915_gem_debugfs_cleanup(struct drm_minor *minor)
2032017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
2042017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_debugfs_remove_files(i915_gem_debugfs_list,
2052017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari				 I915_GEM_DEBUGFS_ENTRIES, minor);
2062017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
2072017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2082017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#endif /* CONFIG_DEBUG_FS */
2092017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
210