i915_debugfs.c revision a17458fc9d9edc98b7c5865cdc42681cf9059f1c
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
44a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
45a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
46a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	if (obj_priv->user_pin_count > 0)
47a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return "P";
48a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	else if (obj_priv->pin_count > 0)
49a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return "p";
50a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	else
51a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return " ";
52a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
53a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
54a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
55a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
56a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    switch (obj_priv->tiling_mode) {
57a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    default:
58a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_NONE: return " ";
59a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_X: return "X";
60a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_Y: return "Y";
61a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    }
62a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
63a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
64433e12f78b68a8069f54956edf766bb21394c197Ben Gamaristatic int i915_gem_object_list_info(struct seq_file *m, void *data)
652017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
662017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
67433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	uintptr_t list = (uintptr_t) node->info_ent->data;
68433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	struct list_head *head;
692017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_object *obj_priv;
725e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	spinlock_t *lock = NULL;
732017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
74433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	switch (list) {
75433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case ACTIVE_LIST:
76433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Active:\n");
775e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth		lock = &dev_priv->mm.active_list_lock;
78433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.active_list;
79433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
80433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case INACTIVE_LIST:
81a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari		seq_printf(m, "Inactive:\n");
82433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.inactive_list;
83433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
84433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case FLUSHING_LIST:
85433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Flushing:\n");
86433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.flushing_list;
87433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
88433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	default:
89433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		DRM_INFO("Ooops, unexpected list\n");
90433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		return 0;
912017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
922017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
93a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari	if (lock)
94a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari		spin_lock(lock);
95433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	list_for_each_entry(obj_priv, head, list)
962017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{
972017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		struct drm_gem_object *obj = obj_priv->obj;
98f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
99f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		seq_printf(m, "    %p: %s %08x %08x %d",
100f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj,
101a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			   get_pin_flag(obj_priv),
102f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj->read_domains, obj->write_domain,
103f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj_priv->last_rendering_seqno);
104f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
105f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj->name)
106f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			seq_printf(m, " (name: %d)", obj->name);
107f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
108a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari			seq_printf(m, " (fence: %d)", obj_priv->fence_reg);
109a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari		if (obj_priv->gtt_space != NULL)
110a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari			seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset);
111a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari
112f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		seq_printf(m, "\n");
1132017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1145e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth
1155e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	if (lock)
1165e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	    spin_unlock(lock);
1172017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1182017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1192017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1202017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_request_info(struct seq_file *m, void *data)
1212017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1222017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1232017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1242017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1252017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_request *gem_request;
1262017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1272017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Request:\n");
1282017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
1292017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "    %d @ %d\n",
1302017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   gem_request->seqno,
1312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   (int) (jiffies - gem_request->emitted_jiffies));
1322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_seqno_info(struct seq_file *m, void *data)
1372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1402017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1412017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1422017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1432017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: %d\n",
1442017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
1452017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
1462017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: hws uninitialized\n");
1472017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1482017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:  %d\n",
1492017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			dev_priv->mm.waiting_gem_seqno);
1502017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
1512017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1522017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1532017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1542017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1552017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_interrupt_info(struct seq_file *m, void *data)
1562017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1572017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1582017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1592017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1602017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1612017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt enable:    %08x\n",
1622017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IER));
1632017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt identity:  %08x\n",
1642017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IIR));
1652017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupt mask:      %08x\n",
1662017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(IMR));
1672017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Pipe A stat:         %08x\n",
1682017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(PIPEASTAT));
1692017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Pipe B stat:         %08x\n",
1702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   I915_READ(PIPEBSTAT));
1712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupts received: %d\n",
1722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   atomic_read(&dev_priv->irq_received));
1732017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1742017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    %d\n",
1752017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
1762017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
1772017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    hws uninitialized\n");
1782017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1792017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:     %d\n",
1802017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.waiting_gem_seqno);
1812017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:        %d\n",
1822017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.irq_gem_seqno);
1832017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1842017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1852017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
186a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic int i915_gem_fence_regs_info(struct seq_file *m, void *data)
187a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
188a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	struct drm_info_node *node = (struct drm_info_node *) m->private;
189a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	struct drm_device *dev = node->minor->dev;
190a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
191a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	int i;
192a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
193a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
194a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
195a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	for (i = 0; i < dev_priv->num_fence_regs; i++) {
196a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
197a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
198a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		if (obj == NULL) {
199a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "Fenced object[%2d] = unused\n", i);
200a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		} else {
201a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			struct drm_i915_gem_object *obj_priv;
202a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
203a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			obj_priv = obj->driver_private;
204a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "Fenced object[%2d] = %p: %s "
2050b4d569de222452bcb55a4a536ade6cf4d8d1e30Linus Torvalds				   "%08x %08zx %08x %s %08x %08x %d",
206a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   i, obj, get_pin_flag(obj_priv),
207a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj_priv->gtt_offset,
208a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj->size, obj_priv->stride,
209a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   get_tiling_flag(obj_priv),
210a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj->read_domains, obj->write_domain,
211a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj_priv->last_rendering_seqno);
212a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			if (obj->name)
213a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				seq_printf(m, " (name: %d)", obj->name);
214a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "\n");
215a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		}
216a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	}
217a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
218a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	return 0;
219a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
220a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
2212017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_hws_info(struct seq_file *m, void *data)
2222017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
2232017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
2242017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
2252017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
2262017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	int i;
2272017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	volatile u32 *hws;
2282017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2292017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	hws = (volatile u32 *)dev_priv->hw_status_page;
2302017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (hws == NULL)
2312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		return 0;
2322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
2342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
2352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i * 4,
2362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
2372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
2382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
2392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
2402017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2416911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
2426911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
2436911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	int page, i;
2446911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	uint32_t *mem;
2456911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2466911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	for (page = 0; page < page_count; page++) {
2476911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		mem = kmap(pages[page]);
2486911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		for (i = 0; i < PAGE_SIZE; i += 4)
2496911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
2506911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		kunmap(pages[page]);
2516911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
2526911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
2536911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2546911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_batchbuffer_info(struct seq_file *m, void *data)
2556911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
2566911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
2576911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
2586911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
2596911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_gem_object *obj;
2606911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_i915_gem_object *obj_priv;
2616911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	int ret;
2626911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2636911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	spin_lock(&dev_priv->mm.active_list_lock);
2646911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2656911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
2666911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		obj = obj_priv->obj;
2676911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
2686911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    ret = i915_gem_object_get_pages(obj);
2696911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    if (ret) {
2706911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    DRM_ERROR("Failed to get pages: %d\n", ret);
2716911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    spin_unlock(&dev_priv->mm.active_list_lock);
2726911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    return ret;
2736911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    }
2746911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2756911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
2766911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
2776911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2786911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    i915_gem_object_put_pages(obj);
2796911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		}
2806911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
2816911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2826911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	spin_unlock(&dev_priv->mm.active_list_lock);
2836911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2846911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
2856911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
2866911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2876911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_ringbuffer_data(struct seq_file *m, void *data)
2886911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
2896911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
2906911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
2916911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
2926911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	u8 *virt;
2936911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	uint32_t *ptr, off;
2946911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2956911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	if (!dev_priv->ring.ring_obj) {
2966911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		seq_printf(m, "No ringbuffer setup\n");
2976911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		return 0;
2986911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
2996911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3006911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	virt = dev_priv->ring.virtual_start;
3016911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3026911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	for (off = 0; off < dev_priv->ring.Size; off += 4) {
3036911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		ptr = (uint32_t *)(virt + off);
3046911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		seq_printf(m, "%08x :  %08x\n", off, *ptr);
3056911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
3066911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3076911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
3086911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
3096911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3106911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_ringbuffer_info(struct seq_file *m, void *data)
3116911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
3126911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
3136911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
3146911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
3156911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	unsigned int head, tail, mask;
3166911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3176911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
3186911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
3196911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	mask = dev_priv->ring.tail_mask;
3206911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3216911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingHead :  %08x\n", head);
3226911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingTail :  %08x\n", tail);
3236911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingMask :  %08x\n", mask);
3246911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
32576cff81ad1cfa3bd8b52b5e4510702ce2ed28335Ben Gamari	seq_printf(m, "Acthd :     %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
3266911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3276911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
3286911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
3296911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
33063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnesstatic int i915_error_state(struct seq_file *m, void *unused)
33163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes{
33263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
33363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_device *dev = node->minor->dev;
33463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
33563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_i915_error_state *error;
33663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	unsigned long flags;
33763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
33863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	spin_lock_irqsave(&dev_priv->error_lock, flags);
33963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	if (!dev_priv->first_error) {
34063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "no error state collected\n");
34163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		goto out;
34263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	}
34363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
34463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	error = dev_priv->first_error;
34563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
34663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "EIR: 0x%08x\n", error->eir);
34763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
34863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
34963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir);
35063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr);
35163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone);
35263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd);
35363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	if (IS_I965G(dev)) {
35463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
35563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
35663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	}
35763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
35863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnesout:
35963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
36063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
36163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	return 0;
36263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes}
3636911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3642017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic struct drm_info_list i915_gem_debugfs_list[] = {
365433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
366433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
367433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
3682017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_request", i915_gem_request_info, 0},
3692017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_seqno", i915_gem_seqno_info, 0},
370a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
3712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_interrupt", i915_interrupt_info, 0},
3722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_hws", i915_hws_info, 0},
3736911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
3746911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
3756911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_batchbuffers", i915_batchbuffer_info, 0},
37663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	{"i915_error_state", i915_error_state, 0},
3772017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari};
3782017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
3792017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
3802017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamariint i915_gem_debugfs_init(struct drm_minor *minor)
3812017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
3822017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return drm_debugfs_create_files(i915_gem_debugfs_list,
3832017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari					I915_GEM_DEBUGFS_ENTRIES,
3842017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari					minor->debugfs_root, minor);
3852017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
3862017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
3872017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamarivoid i915_gem_debugfs_cleanup(struct drm_minor *minor)
3882017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
3892017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_debugfs_remove_files(i915_gem_debugfs_list,
3902017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari				 I915_GEM_DEBUGFS_ENTRIES, minor);
3912017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
3922017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
3932017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#endif /* CONFIG_DEBUG_FS */
3942017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
395