i915_debugfs.c revision 9df30794f609d9412f14cfd0eb7b45dd64d0b14e
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>
30f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson#include <linux/debugfs.h>
312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "drmP.h"
322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "drm.h"
332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "i915_drm.h"
342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#include "i915_drv.h"
352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#define DRM_I915_RING_DEBUG 1
372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#if defined(CONFIG_DEBUG_FS)
402017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
41433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define ACTIVE_LIST	1
42433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define FLUSHING_LIST	2
43433e12f78b68a8069f54956edf766bb21394c197Ben Gamari#define INACTIVE_LIST	3
442017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
45a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
46a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
47a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	if (obj_priv->user_pin_count > 0)
48a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return "P";
49a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	else if (obj_priv->pin_count > 0)
50a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return "p";
51a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	else
52a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		return " ";
53a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
54a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
55a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
56a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
57a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    switch (obj_priv->tiling_mode) {
58a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    default:
59a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_NONE: return " ";
60a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_X: return "X";
61a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    case I915_TILING_Y: return "Y";
62a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson    }
63a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
64a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
65433e12f78b68a8069f54956edf766bb21394c197Ben Gamaristatic int i915_gem_object_list_info(struct seq_file *m, void *data)
662017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
672017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
68433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	uintptr_t list = (uintptr_t) node->info_ent->data;
69433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	struct list_head *head;
702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_object *obj_priv;
735e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	spinlock_t *lock = NULL;
742017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
75433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	switch (list) {
76433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case ACTIVE_LIST:
77433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Active:\n");
785e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth		lock = &dev_priv->mm.active_list_lock;
79433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.active_list;
80433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
81433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case INACTIVE_LIST:
82a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari		seq_printf(m, "Inactive:\n");
83433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.inactive_list;
84433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
85433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	case FLUSHING_LIST:
86433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		seq_printf(m, "Flushing:\n");
87433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		head = &dev_priv->mm.flushing_list;
88433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		break;
89433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	default:
90433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		DRM_INFO("Ooops, unexpected list\n");
91433e12f78b68a8069f54956edf766bb21394c197Ben Gamari		return 0;
922017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
932017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
94a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari	if (lock)
95a17458fc9d9edc98b7c5865cdc42681cf9059f1cBen Gamari		spin_lock(lock);
96433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	list_for_each_entry(obj_priv, head, list)
972017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{
982017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		struct drm_gem_object *obj = obj_priv->obj;
99f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
100fcffb947668073fd9c47da33f8e72add7f62163dChris Wilson		seq_printf(m, "    %p: %s %8zd %08x %08x %d%s%s",
101f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj,
102a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			   get_pin_flag(obj_priv),
103725ceaa08a98fcdb1ec1c302700e33b629aece4bChris Wilson			   obj->size,
104f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			   obj->read_domains, obj->write_domain,
105725ceaa08a98fcdb1ec1c302700e33b629aece4bChris Wilson			   obj_priv->last_rendering_seqno,
106fcffb947668073fd9c47da33f8e72add7f62163dChris Wilson			   obj_priv->dirty ? " dirty" : "",
107fcffb947668073fd9c47da33f8e72add7f62163dChris Wilson			   obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : "");
108f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt
109f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj->name)
110f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt			seq_printf(m, " (name: %d)", obj->name);
111f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
112a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari			seq_printf(m, " (fence: %d)", obj_priv->fence_reg);
113a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari		if (obj_priv->gtt_space != NULL)
114a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari			seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset);
115a01c75b338d7c743a8982011f01a4714ad2956deBen Gamari
116f4ceda89895b56e2c03dd327f13d0256838a20abEric Anholt		seq_printf(m, "\n");
1172017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1185e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth
1195e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	if (lock)
1205e118f4139feafe97e913df67b1f7c1e5083e535Carl Worth	    spin_unlock(lock);
1212017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1222017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1232017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1242017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_request_info(struct seq_file *m, void *data)
1252017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1262017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1272017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1282017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1292017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_i915_gem_request *gem_request;
1302017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1312017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Request:\n");
1322017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
1332017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "    %d @ %d\n",
1342017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   gem_request->seqno,
1352017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   (int) (jiffies - gem_request->emitted_jiffies));
1362017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1372017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1382017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1392017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1402017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_gem_seqno_info(struct seq_file *m, void *data)
1412017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1422017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1432017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1442017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1452017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1462017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1472017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: %d\n",
1482017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
1492017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
1502017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence: hws uninitialized\n");
1512017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
1522017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:  %d\n",
1532017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			dev_priv->mm.waiting_gem_seqno);
1542017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
1552017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
1562017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
1572017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1582017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
1592017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_interrupt_info(struct seq_file *m, void *data)
1602017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
1612017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
1622017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
1632017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
1642017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
165f2b115e69d46344ae7afcaad5823496d2a0d8650Adam Jackson	if (!IS_IRONLAKE(dev)) {
1665f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Interrupt enable:    %08x\n",
1675f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(IER));
1685f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Interrupt identity:  %08x\n",
1695f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(IIR));
1705f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Interrupt mask:      %08x\n",
1715f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(IMR));
1725f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Pipe A stat:         %08x\n",
1735f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(PIPEASTAT));
1745f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Pipe B stat:         %08x\n",
1755f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(PIPEBSTAT));
1765f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang	} else {
1775f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "North Display Interrupt enable:		%08x\n",
1785f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(DEIER));
1795f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "North Display Interrupt identity:	%08x\n",
1805f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(DEIIR));
1815f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "North Display Interrupt mask:		%08x\n",
1825f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(DEIMR));
1835f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "South Display Interrupt enable:		%08x\n",
1845f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(SDEIER));
1855f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "South Display Interrupt identity:	%08x\n",
1865f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(SDEIIR));
1875f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "South Display Interrupt mask:		%08x\n",
1885f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(SDEIMR));
1895f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Graphics Interrupt enable:		%08x\n",
1905f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(GTIER));
1915f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Graphics Interrupt identity:		%08x\n",
1925f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(GTIIR));
1935f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang		seq_printf(m, "Graphics Interrupt mask:		%08x\n",
1945f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang			   I915_READ(GTIMR));
1955f6a169598938d9e5703f06b64c4f4f972561ce5Zhenyu Wang	}
1962017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Interrupts received: %d\n",
1972017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   atomic_read(&dev_priv->irq_received));
1982017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (dev_priv->hw_status_page != NULL) {
1992017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    %d\n",
2002017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i915_get_gem_seqno(dev));
2012017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	} else {
2022017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "Current sequence:    hws uninitialized\n");
2032017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
2042017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "Waiter sequence:     %d\n",
2052017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.waiting_gem_seqno);
2062017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	seq_printf(m, "IRQ sequence:        %d\n",
2072017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		   dev_priv->mm.irq_gem_seqno);
2082017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
2092017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
2102017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
211a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilsonstatic int i915_gem_fence_regs_info(struct seq_file *m, void *data)
212a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson{
213a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	struct drm_info_node *node = (struct drm_info_node *) m->private;
214a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	struct drm_device *dev = node->minor->dev;
215a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
216a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	int i;
217a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
218a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
219a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
220a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	for (i = 0; i < dev_priv->num_fence_regs; i++) {
221a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
222a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
223a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		if (obj == NULL) {
224a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "Fenced object[%2d] = unused\n", i);
225a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		} else {
226a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			struct drm_i915_gem_object *obj_priv;
227a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
228a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			obj_priv = obj->driver_private;
229a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "Fenced object[%2d] = %p: %s "
2300b4d569de222452bcb55a4a536ade6cf4d8d1e30Linus Torvalds				   "%08x %08zx %08x %s %08x %08x %d",
231a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   i, obj, get_pin_flag(obj_priv),
232a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj_priv->gtt_offset,
233a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj->size, obj_priv->stride,
234a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   get_tiling_flag(obj_priv),
235a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj->read_domains, obj->write_domain,
236a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				   obj_priv->last_rendering_seqno);
237a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			if (obj->name)
238a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson				seq_printf(m, " (name: %d)", obj->name);
239a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson			seq_printf(m, "\n");
240a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson		}
241a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	}
242a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
243a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	return 0;
244a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson}
245a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson
2462017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamaristatic int i915_hws_info(struct seq_file *m, void *data)
2472017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
2482017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
2492017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	struct drm_device *dev = node->minor->dev;
2502017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
2512017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	int i;
2522017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	volatile u32 *hws;
2532017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2542017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	hws = (volatile u32 *)dev_priv->hw_status_page;
2552017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	if (hws == NULL)
2562017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		return 0;
2572017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2582017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
2592017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
2602017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   i * 4,
2612017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
2622017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	}
2632017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	return 0;
2642017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
2652017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
2666911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
2676911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
2686911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	int page, i;
2696911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	uint32_t *mem;
2706911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2716911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	for (page = 0; page < page_count; page++) {
272ba86bf8bfc1add5f515db8cf1d6042bb9396a299Chris Wilson		mem = kmap_atomic(pages[page], KM_USER0);
2736911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		for (i = 0; i < PAGE_SIZE; i += 4)
2746911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
275656cb79322319a7bbafec7912d262142e9a38bc0Eric Anholt		kunmap_atomic(mem, KM_USER0);
2766911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
2776911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
2786911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2796911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_batchbuffer_info(struct seq_file *m, void *data)
2806911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
2816911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
2826911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
2836911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
2846911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_gem_object *obj;
2856911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_i915_gem_object *obj_priv;
2866911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	int ret;
2876911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2886911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	spin_lock(&dev_priv->mm.active_list_lock);
2896911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
2906911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
2916911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		obj = obj_priv->obj;
2926911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
2934bdadb9785696439c6e2b3efe34aa76df1149c83Chris Wilson		    ret = i915_gem_object_get_pages(obj, 0);
2946911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    if (ret) {
2956911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    DRM_ERROR("Failed to get pages: %d\n", ret);
2966911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    spin_unlock(&dev_priv->mm.active_list_lock);
2976911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari			    return ret;
2986911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    }
2996911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3006911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
3016911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
3026911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3036911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		    i915_gem_object_put_pages(obj);
3046911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		}
3056911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
3066911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3076911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	spin_unlock(&dev_priv->mm.active_list_lock);
3086911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3096911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
3106911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
3116911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3126911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_ringbuffer_data(struct seq_file *m, void *data)
3136911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
3146911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
3156911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
3166911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
3176911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	u8 *virt;
3186911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	uint32_t *ptr, off;
3196911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3206911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	if (!dev_priv->ring.ring_obj) {
3216911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		seq_printf(m, "No ringbuffer setup\n");
3226911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		return 0;
3236911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
3246911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3256911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	virt = dev_priv->ring.virtual_start;
3266911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3276911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	for (off = 0; off < dev_priv->ring.Size; off += 4) {
3286911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		ptr = (uint32_t *)(virt + off);
3296911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari		seq_printf(m, "%08x :  %08x\n", off, *ptr);
3306911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	}
3316911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3326911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
3336911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
3346911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3356911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamaristatic int i915_ringbuffer_info(struct seq_file *m, void *data)
3366911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari{
3376911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_info_node *node = (struct drm_info_node *) m->private;
3386911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	struct drm_device *dev = node->minor->dev;
3396911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	drm_i915_private_t *dev_priv = dev->dev_private;
3400ef82af7253c1929a3995f271b8b0db462d1a0c3Chris Wilson	unsigned int head, tail;
3416911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3426911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
3436911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
3446911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3456911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingHead :  %08x\n", head);
3466911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingTail :  %08x\n", tail);
3476911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
34876cff81ad1cfa3bd8b52b5e4510702ce2ed28335Ben Gamari	seq_printf(m, "Acthd :     %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
3496911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3506911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	return 0;
3516911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari}
3526911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
3539df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilsonstatic const char *pin_flag(int pinned)
3549df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson{
3559df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	if (pinned > 0)
3569df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		return " P";
3579df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	else if (pinned < 0)
3589df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		return " p";
3599df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	else
3609df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		return "";
3619df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson}
3629df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
3639df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilsonstatic const char *tiling_flag(int tiling)
3649df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson{
3659df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	switch (tiling) {
3669df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	default:
3679df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	case I915_TILING_NONE: return "";
3689df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	case I915_TILING_X: return " X";
3699df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	case I915_TILING_Y: return " Y";
3709df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	}
3719df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson}
3729df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
3739df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilsonstatic const char *dirty_flag(int dirty)
3749df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson{
3759df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	return dirty ? " dirty" : "";
3769df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson}
3779df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
3789df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilsonstatic const char *purgeable_flag(int purgeable)
3799df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson{
3809df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	return purgeable ? " purgeable" : "";
3819df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson}
3829df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
38363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnesstatic int i915_error_state(struct seq_file *m, void *unused)
38463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes{
38563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
38663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_device *dev = node->minor->dev;
38763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
38863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	struct drm_i915_error_state *error;
38963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	unsigned long flags;
3909df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	int i, page, offset, elt;
39163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
39263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	spin_lock_irqsave(&dev_priv->error_lock, flags);
39363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	if (!dev_priv->first_error) {
39463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "no error state collected\n");
39563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		goto out;
39663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	}
39763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
39863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	error = dev_priv->first_error;
39963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
4008a90523639f49dc4b4fa7ae47bb9c8ed73ea8577Jesse Barnes	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
4018a90523639f49dc4b4fa7ae47bb9c8ed73ea8577Jesse Barnes		   error->time.tv_usec);
4029df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
40363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "EIR: 0x%08x\n", error->eir);
40463eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
40563eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
40663eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir);
40763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr);
40863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone);
40963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd);
41063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	if (IS_I965G(dev)) {
41163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
41263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
41363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	}
4149df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	seq_printf(m, "seqno: 0x%08x\n", error->seqno);
4159df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4169df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	if (error->active_bo_count) {
4179df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		seq_printf(m, "Buffers [%d]:\n", error->active_bo_count);
4189df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4199df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		for (i = 0; i < error->active_bo_count; i++) {
4209df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			seq_printf(m, "  %08x %8zd %08x %08x %08x%s%s%s%s",
4219df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   error->active_bo[i].gtt_offset,
4229df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   error->active_bo[i].size,
4239df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   error->active_bo[i].read_domains,
4249df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   error->active_bo[i].write_domain,
4259df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   error->active_bo[i].seqno,
4269df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   pin_flag(error->active_bo[i].pinned),
4279df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   tiling_flag(error->active_bo[i].tiling),
4289df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   dirty_flag(error->active_bo[i].dirty),
4299df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				   purgeable_flag(error->active_bo[i].purgeable));
4309df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4319df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			if (error->active_bo[i].name)
4329df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				seq_printf(m, " (name: %d)", error->active_bo[i].name);
4339df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE)
4349df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg);
4359df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4369df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			seq_printf(m, "\n");
4379df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		}
4389df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	}
4399df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4409df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
4419df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		if (error->batchbuffer[i]) {
4429df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			struct drm_i915_error_object *obj = error->batchbuffer[i];
4439df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4449df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset);
4459df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			offset = 0;
4469df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			for (page = 0; page < obj->page_count; page++) {
4479df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				for (elt = 0; elt < PAGE_SIZE/4; elt++) {
4489df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson					seq_printf(m, "%08x :  %08x\n", offset, obj->pages[page][elt]);
4499df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson					offset += 4;
4509df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				}
4519df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			}
4529df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		}
4539df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	}
4549df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4559df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	if (error->ringbuffer) {
4569df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		struct drm_i915_error_object *obj = error->ringbuffer;
4579df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson
4589df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		seq_printf(m, "--- ringbuffer = 0x%08x\n", obj->gtt_offset);
4599df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		offset = 0;
4609df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		for (page = 0; page < obj->page_count; page++) {
4619df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			for (elt = 0; elt < PAGE_SIZE/4; elt++) {
4629df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				seq_printf(m, "%08x :  %08x\n", offset, obj->pages[page][elt]);
4639df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson				offset += 4;
4649df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson			}
4659df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson		}
4669df30794f609d9412f14cfd0eb7b45dd64d0b14eChris Wilson	}
46763eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
46863eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnesout:
46963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
47063eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes
47163eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	return 0;
47263eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes}
4736911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari
474f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic int i915_rstdby_delays(struct seq_file *m, void *unused)
475f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
476f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
477f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_device *dev = node->minor->dev;
478f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
479f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	u16 crstanddelay = I915_READ16(CRSTANDVID);
480f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
481f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
482f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
483f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 0;
484f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
485f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
486f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic int i915_cur_delayinfo(struct seq_file *m, void *unused)
487f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
488f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
489f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_device *dev = node->minor->dev;
490f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
491f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	u16 rgvswctl = I915_READ16(MEMSWCTL);
492f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
493f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3);
494f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1);
495f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf,
496f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   rgvswctl & 0x3f);
497f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
498f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 0;
499f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
500f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
501f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic int i915_delayfreq_table(struct seq_file *m, void *unused)
502f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
503f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
504f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_device *dev = node->minor->dev;
505f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
506f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	u32 delayfreq;
507f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	int i;
508f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
509f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	for (i = 0; i < 16; i++) {
510f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
511f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq);
512f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	}
513f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
514f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 0;
515f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
516f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
517f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic inline int MAP_TO_MV(int map)
518f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
519f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 1250 - (map * 25);
520f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
521f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
522f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic int i915_inttoext_table(struct seq_file *m, void *unused)
523f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
524f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
525f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_device *dev = node->minor->dev;
526f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
527f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	u32 inttoext;
528f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	int i;
529f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
530f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	for (i = 1; i <= 32; i++) {
531f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
532f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
533f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	}
534f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
535f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 0;
536f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
537f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
538f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnesstatic int i915_drpc_info(struct seq_file *m, void *unused)
539f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes{
540f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
541f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	struct drm_device *dev = node->minor->dev;
542f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
543f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	u32 rgvmodectl = I915_READ(MEMMODECTL);
544f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
545f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
546f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   "yes" : "no");
547f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Boost freq: %d\n",
548f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >>
549f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   MEMMODE_BOOST_FREQ_SHIFT);
550f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "HW control enabled: %s\n",
551f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no");
552f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "SW control enabled: %s\n",
553f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no");
554f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Gated voltage change: %s\n",
555f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no");
556f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Starting frequency: P%d\n",
557f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
558f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Max frequency: P%d\n",
559f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes		   (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT);
560f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
561f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
562f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	return 0;
563f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes}
564f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes
565b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnesstatic int i915_fbc_status(struct seq_file *m, void *unused)
566b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes{
567b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
568b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	struct drm_device *dev = node->minor->dev;
569b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	struct drm_crtc *crtc;
570b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
571b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	bool fbc_enabled = false;
572b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes
573b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	if (!dev_priv->display.fbc_enabled) {
574b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		seq_printf(m, "FBC unsupported on this chipset\n");
575b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		return 0;
576b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	}
577b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes
578b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
579b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		if (!crtc->enabled)
580b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			continue;
581b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		if (dev_priv->display.fbc_enabled(crtc))
582b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			fbc_enabled = true;
583b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	}
584b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes
585b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	if (fbc_enabled) {
586b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		seq_printf(m, "FBC enabled\n");
587b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	} else {
588b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		seq_printf(m, "FBC disabled: ");
589b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		switch (dev_priv->no_fbc_reason) {
590b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		case FBC_STOLEN_TOO_SMALL:
591b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "not enough stolen memory");
592b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			break;
593b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		case FBC_UNSUPPORTED_MODE:
594b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "mode not supported");
595b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			break;
596b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		case FBC_MODE_TOO_LARGE:
597b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "mode too large");
598b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			break;
599b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		case FBC_BAD_PLANE:
600b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "FBC unsupported on plane");
601b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			break;
602b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		case FBC_NOT_TILED:
603b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "scanout buffer not tiled");
604b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			break;
605b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		default:
606b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes			seq_printf(m, "unknown reason");
607b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		}
608b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes		seq_printf(m, "\n");
609b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	}
610b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	return 0;
611b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes}
612b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes
6134a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnesstatic int i915_sr_status(struct seq_file *m, void *unused)
6144a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes{
6154a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	struct drm_info_node *node = (struct drm_info_node *) m->private;
6164a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	struct drm_device *dev = node->minor->dev;
6174a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
6184a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	bool sr_enabled = false;
6194a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes
6204a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev))
6214a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes		sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
6224a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	else if (IS_I915GM(dev))
6234a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes		sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
6244a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	else if (IS_PINEVIEW(dev))
6254a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes		sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
6264a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes
6274a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	seq_printf(m, "self-refresh: %s\n", sr_enabled ? "enabled" :
6284a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes		   "disabled");
6294a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes
6304a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	return 0;
6314a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes}
6324a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes
633f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic int
634f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsoni915_wedged_open(struct inode *inode,
635f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		 struct file *filp)
636f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson{
637f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	filp->private_data = inode->i_private;
638f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	return 0;
639f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson}
640f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
641f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic ssize_t
642f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsoni915_wedged_read(struct file *filp,
643f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		 char __user *ubuf,
644f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		 size_t max,
645f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		 loff_t *ppos)
646f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson{
647f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	struct drm_device *dev = filp->private_data;
648f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
649f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	char buf[80];
650f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	int len;
651f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
652f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	len = snprintf(buf, sizeof (buf),
653f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		       "wedged :  %d\n",
654f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		       atomic_read(&dev_priv->mm.wedged));
655f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
656f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
657f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson}
658f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
659f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic ssize_t
660f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsoni915_wedged_write(struct file *filp,
661f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		  const char __user *ubuf,
662f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		  size_t cnt,
663f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		  loff_t *ppos)
664f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson{
665f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	struct drm_device *dev = filp->private_data;
666f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	drm_i915_private_t *dev_priv = dev->dev_private;
667f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	char buf[20];
668f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	int val = 1;
669f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
670f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	if (cnt > 0) {
671f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		if (cnt > sizeof (buf) - 1)
672f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson			return -EINVAL;
673f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
674f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		if (copy_from_user(buf, ubuf, cnt))
675f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson			return -EFAULT;
676f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		buf[cnt] = 0;
677f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
678f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		val = simple_strtoul(buf, NULL, 0);
679f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	}
680f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
681f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	DRM_INFO("Manually setting wedged to %d\n", val);
682f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
683f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	atomic_set(&dev_priv->mm.wedged, val);
684f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	if (val) {
685f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		DRM_WAKEUP(&dev_priv->irq_queue);
686f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		queue_work(dev_priv->wq, &dev_priv->error_work);
687f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	}
688f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
689f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	return cnt;
690f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson}
691f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
692f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic const struct file_operations i915_wedged_fops = {
693f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	.owner = THIS_MODULE,
694f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	.open = i915_wedged_open,
695f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	.read = i915_wedged_read,
696f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	.write = i915_wedged_write,
697f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson};
698f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
699f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson/* As the drm_debugfs_init() routines are called before dev->dev_private is
700f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson * allocated we need to hook into the minor for release. */
701f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic int
702f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsondrm_add_fake_info_node(struct drm_minor *minor,
703f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		       struct dentry *ent,
704f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		       const void *key)
705f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson{
706f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	struct drm_info_node *node;
707f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
708f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
709f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	if (node == NULL) {
710f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		debugfs_remove(ent);
711f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		return -ENOMEM;
712f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	}
713f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
714f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	node->minor = minor;
715f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	node->dent = ent;
716f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	node->info_ent = (void *) key;
717f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	list_add(&node->list, &minor->debugfs_nodes.list);
718f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
719f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	return 0;
720f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson}
721f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
722f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilsonstatic int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
723f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson{
724f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	struct drm_device *dev = minor->dev;
725f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	struct dentry *ent;
726f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
727f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	ent = debugfs_create_file("i915_wedged",
728f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson				  S_IRUGO | S_IWUSR,
729f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson				  root, dev,
730f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson				  &i915_wedged_fops);
731f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	if (IS_ERR(ent))
732f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		return PTR_ERR(ent);
733f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
734f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
735f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson}
7369e3a6d155ed0a7636b926a798dd7221ea107b274Ben Gamari
73727c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamaristatic struct drm_info_list i915_debugfs_list[] = {
738433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
739433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
740433e12f78b68a8069f54956edf766bb21394c197Ben Gamari	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
7412017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_request", i915_gem_request_info, 0},
7422017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_seqno", i915_gem_seqno_info, 0},
743a6172a80ecb7ac64151960de1f709f78b509c57cChris Wilson	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
7442017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_interrupt", i915_interrupt_info, 0},
7452017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari	{"i915_gem_hws", i915_hws_info, 0},
7466911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
7476911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
7486911a9b8ae8b2a1dab4dfda9c2bd20f7ca2961d6Ben Gamari	{"i915_batchbuffers", i915_batchbuffer_info, 0},
74963eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes	{"i915_error_state", i915_error_state, 0},
750f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	{"i915_rstdby_delays", i915_rstdby_delays, 0},
751f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	{"i915_cur_delayinfo", i915_cur_delayinfo, 0},
752f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	{"i915_delayfreq_table", i915_delayfreq_table, 0},
753f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	{"i915_inttoext_table", i915_inttoext_table, 0},
754f97108d1d0facc7902134ebc453b226bbd4d1cdbJesse Barnes	{"i915_drpc_info", i915_drpc_info, 0},
755b5e50c3f56ee4aa0d0168eab5ece413ac5df76aaJesse Barnes	{"i915_fbc_status", i915_fbc_status, 0},
7564a9bef37e5cf2c73b61ecc9ead52cad2eb4a372bJesse Barnes	{"i915_sr_status", i915_sr_status, 0},
7572017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari};
75827c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamari#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
7592017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
76027c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamariint i915_debugfs_init(struct drm_minor *minor)
7612017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
762f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	int ret;
763f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
764f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	ret = i915_wedged_create(minor->debugfs_root, minor);
765f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson	if (ret)
766f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson		return ret;
767f3cd474bb235f2331c1a6f579bdbf892386e5c7cChris Wilson
76827c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamari	return drm_debugfs_create_files(i915_debugfs_list,
76927c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamari					I915_DEBUGFS_ENTRIES,
7702017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari					minor->debugfs_root, minor);
7712017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
7722017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
77327c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamarivoid i915_debugfs_cleanup(struct drm_minor *minor)
7742017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari{
77527c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamari	drm_debugfs_remove_files(i915_debugfs_list,
77627c202ad7f141d4efa9c64e30bf4a4d3bcd799aeBen Gamari				 I915_DEBUGFS_ENTRIES, minor);
77733db679b4ee94e5a55abb439a87905d76739095aKristian Høgsberg	drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
77833db679b4ee94e5a55abb439a87905d76739095aKristian Høgsberg				 1, minor);
7792017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari}
7802017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari
7812017263e9e72974610179beaa85c4498b9c4b7a4Ben Gamari#endif /* CONFIG_DEBUG_FS */
782