diff options
author | Ben Gamari <bgamari@gmail.com> | 2009-02-17 20:08:49 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 00:24:07 -0400 |
commit | 955b12def42e83287c1bdb1411d99451753c1391 (patch) | |
tree | 5dc5025f500b7a0a86c70ea79f2294e94902e3b2 /drivers/gpu/drm/i915 | |
parent | dd8d7cb49e6e61da96ca44174b063081892c4dc6 (diff) |
drm: Convert proc files to seq_file and introduce debugfs
The old mechanism to formatting proc files is extremely ugly. The
seq_file API was designed specifically for cases like this and greatly
simplifies the process.
Also, most of the files in /proc really don't belong there. This patch
introduces the infrastructure for putting these into debugfs and exposes
all of the proc files in debugfs as well.
This contains the i915 hooks rewrite as well, to make bisectability better.
Signed-off-by: Ben Gamari <bgamari@gmail.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_debugfs.c | 230 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_proc.c | 334 |
5 files changed, 239 insertions, 339 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 793cba39d832..51c5a050aa73 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -7,7 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
7 | i915_suspend.o \ | 7 | i915_suspend.o \ |
8 | i915_gem.o \ | 8 | i915_gem.o \ |
9 | i915_gem_debug.o \ | 9 | i915_gem_debug.o \ |
10 | i915_gem_proc.o \ | 10 | i915_gem_debugfs.o \ |
11 | i915_gem_tiling.o \ | 11 | i915_gem_tiling.o \ |
12 | intel_display.o \ | 12 | intel_display.o \ |
13 | intel_crt.o \ | 13 | intel_crt.o \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d10ec9e5033c..2c0167693450 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -182,8 +182,10 @@ static struct drm_driver driver = { | |||
182 | .get_reg_ofs = drm_core_get_reg_ofs, | 182 | .get_reg_ofs = drm_core_get_reg_ofs, |
183 | .master_create = i915_master_create, | 183 | .master_create = i915_master_create, |
184 | .master_destroy = i915_master_destroy, | 184 | .master_destroy = i915_master_destroy, |
185 | .proc_init = i915_gem_proc_init, | 185 | #if defined(CONFIG_DEBUG_FS) |
186 | .proc_cleanup = i915_gem_proc_cleanup, | 186 | .debugfs_init = i915_gem_debugfs_init, |
187 | .debugfs_cleanup = i915_gem_debugfs_cleanup, | ||
188 | #endif | ||
187 | .gem_init_object = i915_gem_init_object, | 189 | .gem_init_object = i915_gem_init_object, |
188 | .gem_free_object = i915_gem_free_object, | 190 | .gem_free_object = i915_gem_free_object, |
189 | .gem_vm_ops = &i915_gem_vm_ops, | 191 | .gem_vm_ops = &i915_gem_vm_ops, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d6cc9861e0a1..1bc45a78ffcd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -604,8 +604,6 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
604 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 604 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
605 | struct drm_file *file_priv); | 605 | struct drm_file *file_priv); |
606 | void i915_gem_load(struct drm_device *dev); | 606 | void i915_gem_load(struct drm_device *dev); |
607 | int i915_gem_proc_init(struct drm_minor *minor); | ||
608 | void i915_gem_proc_cleanup(struct drm_minor *minor); | ||
609 | int i915_gem_init_object(struct drm_gem_object *obj); | 607 | int i915_gem_init_object(struct drm_gem_object *obj); |
610 | void i915_gem_free_object(struct drm_gem_object *obj); | 608 | void i915_gem_free_object(struct drm_gem_object *obj); |
611 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 609 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
@@ -649,6 +647,10 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
649 | const char *where, uint32_t mark); | 647 | const char *where, uint32_t mark); |
650 | void i915_dump_lru(struct drm_device *dev, const char *where); | 648 | void i915_dump_lru(struct drm_device *dev, const char *where); |
651 | 649 | ||
650 | /* i915_debugfs.c */ | ||
651 | int i915_gem_debugfs_init(struct drm_minor *minor); | ||
652 | void i915_gem_debugfs_cleanup(struct drm_minor *minor); | ||
653 | |||
652 | /* i915_suspend.c */ | 654 | /* i915_suspend.c */ |
653 | extern int i915_save_state(struct drm_device *dev); | 655 | extern int i915_save_state(struct drm_device *dev); |
654 | extern int i915_restore_state(struct drm_device *dev); | 656 | extern int i915_restore_state(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c new file mode 100644 index 000000000000..dd2b0edb9963 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Keith Packard <keithp@keithp.com> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/seq_file.h> | ||
30 | #include "drmP.h" | ||
31 | #include "drm.h" | ||
32 | #include "i915_drm.h" | ||
33 | #include "i915_drv.h" | ||
34 | |||
35 | #define DRM_I915_RING_DEBUG 1 | ||
36 | |||
37 | |||
38 | #if defined(CONFIG_DEBUG_FS) | ||
39 | |||
40 | static int i915_gem_active_info(struct seq_file *m, void *data) | ||
41 | { | ||
42 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
43 | struct drm_device *dev = node->minor->dev; | ||
44 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
45 | struct drm_i915_gem_object *obj_priv; | ||
46 | |||
47 | seq_printf(m, "Active:\n"); | ||
48 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, | ||
49 | list) | ||
50 | { | ||
51 | struct drm_gem_object *obj = obj_priv->obj; | ||
52 | if (obj->name) { | ||
53 | seq_printf(m, " %p(%d): %08x %08x %d\n", | ||
54 | obj, obj->name, | ||
55 | obj->read_domains, obj->write_domain, | ||
56 | obj_priv->last_rendering_seqno); | ||
57 | } else { | ||
58 | seq_printf(m, " %p: %08x %08x %d\n", | ||
59 | obj, | ||
60 | obj->read_domains, obj->write_domain, | ||
61 | obj_priv->last_rendering_seqno); | ||
62 | } | ||
63 | } | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static int i915_gem_flushing_info(struct seq_file *m, void *data) | ||
68 | { | ||
69 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
70 | struct drm_device *dev = node->minor->dev; | ||
71 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
72 | struct drm_i915_gem_object *obj_priv; | ||
73 | |||
74 | seq_printf(m, "Flushing:\n"); | ||
75 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, | ||
76 | list) | ||
77 | { | ||
78 | struct drm_gem_object *obj = obj_priv->obj; | ||
79 | if (obj->name) { | ||
80 | seq_printf(m, " %p(%d): %08x %08x %d\n", | ||
81 | obj, obj->name, | ||
82 | obj->read_domains, obj->write_domain, | ||
83 | obj_priv->last_rendering_seqno); | ||
84 | } else { | ||
85 | seq_printf(m, " %p: %08x %08x %d\n", obj, | ||
86 | obj->read_domains, obj->write_domain, | ||
87 | obj_priv->last_rendering_seqno); | ||
88 | } | ||
89 | } | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static int i915_gem_inactive_info(struct seq_file *m, void *data) | ||
94 | { | ||
95 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
96 | struct drm_device *dev = node->minor->dev; | ||
97 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
98 | struct drm_i915_gem_object *obj_priv; | ||
99 | |||
100 | seq_printf(m, "Inactive:\n"); | ||
101 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, | ||
102 | list) | ||
103 | { | ||
104 | struct drm_gem_object *obj = obj_priv->obj; | ||
105 | if (obj->name) { | ||
106 | seq_printf(m, " %p(%d): %08x %08x %d\n", | ||
107 | obj, obj->name, | ||
108 | obj->read_domains, obj->write_domain, | ||
109 | obj_priv->last_rendering_seqno); | ||
110 | } else { | ||
111 | seq_printf(m, " %p: %08x %08x %d\n", obj, | ||
112 | obj->read_domains, obj->write_domain, | ||
113 | obj_priv->last_rendering_seqno); | ||
114 | } | ||
115 | } | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int i915_gem_request_info(struct seq_file *m, void *data) | ||
120 | { | ||
121 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
122 | struct drm_device *dev = node->minor->dev; | ||
123 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
124 | struct drm_i915_gem_request *gem_request; | ||
125 | |||
126 | seq_printf(m, "Request:\n"); | ||
127 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { | ||
128 | seq_printf(m, " %d @ %d\n", | ||
129 | gem_request->seqno, | ||
130 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
131 | } | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int i915_gem_seqno_info(struct seq_file *m, void *data) | ||
136 | { | ||
137 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
138 | struct drm_device *dev = node->minor->dev; | ||
139 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
140 | |||
141 | if (dev_priv->hw_status_page != NULL) { | ||
142 | seq_printf(m, "Current sequence: %d\n", | ||
143 | i915_get_gem_seqno(dev)); | ||
144 | } else { | ||
145 | seq_printf(m, "Current sequence: hws uninitialized\n"); | ||
146 | } | ||
147 | seq_printf(m, "Waiter sequence: %d\n", | ||
148 | dev_priv->mm.waiting_gem_seqno); | ||
149 | seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | |||
154 | static int i915_interrupt_info(struct seq_file *m, void *data) | ||
155 | { | ||
156 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
157 | struct drm_device *dev = node->minor->dev; | ||
158 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
159 | |||
160 | seq_printf(m, "Interrupt enable: %08x\n", | ||
161 | I915_READ(IER)); | ||
162 | seq_printf(m, "Interrupt identity: %08x\n", | ||
163 | I915_READ(IIR)); | ||
164 | seq_printf(m, "Interrupt mask: %08x\n", | ||
165 | I915_READ(IMR)); | ||
166 | seq_printf(m, "Pipe A stat: %08x\n", | ||
167 | I915_READ(PIPEASTAT)); | ||
168 | seq_printf(m, "Pipe B stat: %08x\n", | ||
169 | I915_READ(PIPEBSTAT)); | ||
170 | seq_printf(m, "Interrupts received: %d\n", | ||
171 | atomic_read(&dev_priv->irq_received)); | ||
172 | if (dev_priv->hw_status_page != NULL) { | ||
173 | seq_printf(m, "Current sequence: %d\n", | ||
174 | i915_get_gem_seqno(dev)); | ||
175 | } else { | ||
176 | seq_printf(m, "Current sequence: hws uninitialized\n"); | ||
177 | } | ||
178 | seq_printf(m, "Waiter sequence: %d\n", | ||
179 | dev_priv->mm.waiting_gem_seqno); | ||
180 | seq_printf(m, "IRQ sequence: %d\n", | ||
181 | dev_priv->mm.irq_gem_seqno); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int i915_hws_info(struct seq_file *m, void *data) | ||
186 | { | ||
187 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
188 | struct drm_device *dev = node->minor->dev; | ||
189 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
190 | int i; | ||
191 | volatile u32 *hws; | ||
192 | |||
193 | hws = (volatile u32 *)dev_priv->hw_status_page; | ||
194 | if (hws == NULL) | ||
195 | return 0; | ||
196 | |||
197 | for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { | ||
198 | seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
199 | i * 4, | ||
200 | hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); | ||
201 | } | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static struct drm_info_list i915_gem_debugfs_list[] = { | ||
206 | {"i915_gem_active", i915_gem_active_info, 0}, | ||
207 | {"i915_gem_flushing", i915_gem_flushing_info, 0}, | ||
208 | {"i915_gem_inactive", i915_gem_inactive_info, 0}, | ||
209 | {"i915_gem_request", i915_gem_request_info, 0}, | ||
210 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | ||
211 | {"i915_gem_interrupt", i915_interrupt_info, 0}, | ||
212 | {"i915_gem_hws", i915_hws_info, 0}, | ||
213 | }; | ||
214 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | ||
215 | |||
216 | int i915_gem_debugfs_init(struct drm_minor *minor) | ||
217 | { | ||
218 | return drm_debugfs_create_files(i915_gem_debugfs_list, | ||
219 | I915_GEM_DEBUGFS_ENTRIES, | ||
220 | minor->debugfs_root, minor); | ||
221 | } | ||
222 | |||
223 | void i915_gem_debugfs_cleanup(struct drm_minor *minor) | ||
224 | { | ||
225 | drm_debugfs_remove_files(i915_gem_debugfs_list, | ||
226 | I915_GEM_DEBUGFS_ENTRIES, minor); | ||
227 | } | ||
228 | |||
229 | #endif /* CONFIG_DEBUG_FS */ | ||
230 | |||
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c deleted file mode 100644 index 4d1b9de0cd8b..000000000000 --- a/drivers/gpu/drm/i915/i915_gem_proc.c +++ /dev/null | |||
@@ -1,334 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Keith Packard <keithp@keithp.com> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | |||
34 | static int i915_gem_active_info(char *buf, char **start, off_t offset, | ||
35 | int request, int *eof, void *data) | ||
36 | { | ||
37 | struct drm_minor *minor = (struct drm_minor *) data; | ||
38 | struct drm_device *dev = minor->dev; | ||
39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
40 | struct drm_i915_gem_object *obj_priv; | ||
41 | int len = 0; | ||
42 | |||
43 | if (offset > DRM_PROC_LIMIT) { | ||
44 | *eof = 1; | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | *start = &buf[offset]; | ||
49 | *eof = 0; | ||
50 | DRM_PROC_PRINT("Active:\n"); | ||
51 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, | ||
52 | list) | ||
53 | { | ||
54 | struct drm_gem_object *obj = obj_priv->obj; | ||
55 | if (obj->name) { | ||
56 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
57 | obj, obj->name, | ||
58 | obj->read_domains, obj->write_domain, | ||
59 | obj_priv->last_rendering_seqno); | ||
60 | } else { | ||
61 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", | ||
62 | obj, | ||
63 | obj->read_domains, obj->write_domain, | ||
64 | obj_priv->last_rendering_seqno); | ||
65 | } | ||
66 | } | ||
67 | if (len > request + offset) | ||
68 | return request; | ||
69 | *eof = 1; | ||
70 | return len - offset; | ||
71 | } | ||
72 | |||
73 | static int i915_gem_flushing_info(char *buf, char **start, off_t offset, | ||
74 | int request, int *eof, void *data) | ||
75 | { | ||
76 | struct drm_minor *minor = (struct drm_minor *) data; | ||
77 | struct drm_device *dev = minor->dev; | ||
78 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
79 | struct drm_i915_gem_object *obj_priv; | ||
80 | int len = 0; | ||
81 | |||
82 | if (offset > DRM_PROC_LIMIT) { | ||
83 | *eof = 1; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | *start = &buf[offset]; | ||
88 | *eof = 0; | ||
89 | DRM_PROC_PRINT("Flushing:\n"); | ||
90 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, | ||
91 | list) | ||
92 | { | ||
93 | struct drm_gem_object *obj = obj_priv->obj; | ||
94 | if (obj->name) { | ||
95 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
96 | obj, obj->name, | ||
97 | obj->read_domains, obj->write_domain, | ||
98 | obj_priv->last_rendering_seqno); | ||
99 | } else { | ||
100 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, | ||
101 | obj->read_domains, obj->write_domain, | ||
102 | obj_priv->last_rendering_seqno); | ||
103 | } | ||
104 | } | ||
105 | if (len > request + offset) | ||
106 | return request; | ||
107 | *eof = 1; | ||
108 | return len - offset; | ||
109 | } | ||
110 | |||
111 | static int i915_gem_inactive_info(char *buf, char **start, off_t offset, | ||
112 | int request, int *eof, void *data) | ||
113 | { | ||
114 | struct drm_minor *minor = (struct drm_minor *) data; | ||
115 | struct drm_device *dev = minor->dev; | ||
116 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
117 | struct drm_i915_gem_object *obj_priv; | ||
118 | int len = 0; | ||
119 | |||
120 | if (offset > DRM_PROC_LIMIT) { | ||
121 | *eof = 1; | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | *start = &buf[offset]; | ||
126 | *eof = 0; | ||
127 | DRM_PROC_PRINT("Inactive:\n"); | ||
128 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, | ||
129 | list) | ||
130 | { | ||
131 | struct drm_gem_object *obj = obj_priv->obj; | ||
132 | if (obj->name) { | ||
133 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
134 | obj, obj->name, | ||
135 | obj->read_domains, obj->write_domain, | ||
136 | obj_priv->last_rendering_seqno); | ||
137 | } else { | ||
138 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, | ||
139 | obj->read_domains, obj->write_domain, | ||
140 | obj_priv->last_rendering_seqno); | ||
141 | } | ||
142 | } | ||
143 | if (len > request + offset) | ||
144 | return request; | ||
145 | *eof = 1; | ||
146 | return len - offset; | ||
147 | } | ||
148 | |||
149 | static int i915_gem_request_info(char *buf, char **start, off_t offset, | ||
150 | int request, int *eof, void *data) | ||
151 | { | ||
152 | struct drm_minor *minor = (struct drm_minor *) data; | ||
153 | struct drm_device *dev = minor->dev; | ||
154 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
155 | struct drm_i915_gem_request *gem_request; | ||
156 | int len = 0; | ||
157 | |||
158 | if (offset > DRM_PROC_LIMIT) { | ||
159 | *eof = 1; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | *start = &buf[offset]; | ||
164 | *eof = 0; | ||
165 | DRM_PROC_PRINT("Request:\n"); | ||
166 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, | ||
167 | list) | ||
168 | { | ||
169 | DRM_PROC_PRINT(" %d @ %d\n", | ||
170 | gem_request->seqno, | ||
171 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
172 | } | ||
173 | if (len > request + offset) | ||
174 | return request; | ||
175 | *eof = 1; | ||
176 | return len - offset; | ||
177 | } | ||
178 | |||
179 | static int i915_gem_seqno_info(char *buf, char **start, off_t offset, | ||
180 | int request, int *eof, void *data) | ||
181 | { | ||
182 | struct drm_minor *minor = (struct drm_minor *) data; | ||
183 | struct drm_device *dev = minor->dev; | ||
184 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
185 | int len = 0; | ||
186 | |||
187 | if (offset > DRM_PROC_LIMIT) { | ||
188 | *eof = 1; | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | *start = &buf[offset]; | ||
193 | *eof = 0; | ||
194 | if (dev_priv->hw_status_page != NULL) { | ||
195 | DRM_PROC_PRINT("Current sequence: %d\n", | ||
196 | i915_get_gem_seqno(dev)); | ||
197 | } else { | ||
198 | DRM_PROC_PRINT("Current sequence: hws uninitialized\n"); | ||
199 | } | ||
200 | DRM_PROC_PRINT("Waiter sequence: %d\n", | ||
201 | dev_priv->mm.waiting_gem_seqno); | ||
202 | DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | ||
203 | if (len > request + offset) | ||
204 | return request; | ||
205 | *eof = 1; | ||
206 | return len - offset; | ||
207 | } | ||
208 | |||
209 | |||
210 | static int i915_interrupt_info(char *buf, char **start, off_t offset, | ||
211 | int request, int *eof, void *data) | ||
212 | { | ||
213 | struct drm_minor *minor = (struct drm_minor *) data; | ||
214 | struct drm_device *dev = minor->dev; | ||
215 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
216 | int len = 0; | ||
217 | |||
218 | if (offset > DRM_PROC_LIMIT) { | ||
219 | *eof = 1; | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | *start = &buf[offset]; | ||
224 | *eof = 0; | ||
225 | DRM_PROC_PRINT("Interrupt enable: %08x\n", | ||
226 | I915_READ(IER)); | ||
227 | DRM_PROC_PRINT("Interrupt identity: %08x\n", | ||
228 | I915_READ(IIR)); | ||
229 | DRM_PROC_PRINT("Interrupt mask: %08x\n", | ||
230 | I915_READ(IMR)); | ||
231 | DRM_PROC_PRINT("Pipe A stat: %08x\n", | ||
232 | I915_READ(PIPEASTAT)); | ||
233 | DRM_PROC_PRINT("Pipe B stat: %08x\n", | ||
234 | I915_READ(PIPEBSTAT)); | ||
235 | DRM_PROC_PRINT("Interrupts received: %d\n", | ||
236 | atomic_read(&dev_priv->irq_received)); | ||
237 | if (dev_priv->hw_status_page != NULL) { | ||
238 | DRM_PROC_PRINT("Current sequence: %d\n", | ||
239 | i915_get_gem_seqno(dev)); | ||
240 | } else { | ||
241 | DRM_PROC_PRINT("Current sequence: hws uninitialized\n"); | ||
242 | } | ||
243 | DRM_PROC_PRINT("Waiter sequence: %d\n", | ||
244 | dev_priv->mm.waiting_gem_seqno); | ||
245 | DRM_PROC_PRINT("IRQ sequence: %d\n", | ||
246 | dev_priv->mm.irq_gem_seqno); | ||
247 | if (len > request + offset) | ||
248 | return request; | ||
249 | *eof = 1; | ||
250 | return len - offset; | ||
251 | } | ||
252 | |||
253 | static int i915_hws_info(char *buf, char **start, off_t offset, | ||
254 | int request, int *eof, void *data) | ||
255 | { | ||
256 | struct drm_minor *minor = (struct drm_minor *) data; | ||
257 | struct drm_device *dev = minor->dev; | ||
258 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
259 | int len = 0, i; | ||
260 | volatile u32 *hws; | ||
261 | |||
262 | if (offset > DRM_PROC_LIMIT) { | ||
263 | *eof = 1; | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | hws = (volatile u32 *)dev_priv->hw_status_page; | ||
268 | if (hws == NULL) { | ||
269 | *eof = 1; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | *start = &buf[offset]; | ||
274 | *eof = 0; | ||
275 | for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { | ||
276 | DRM_PROC_PRINT("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
277 | i * 4, | ||
278 | hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); | ||
279 | } | ||
280 | if (len > request + offset) | ||
281 | return request; | ||
282 | *eof = 1; | ||
283 | return len - offset; | ||
284 | } | ||
285 | |||
286 | static struct drm_proc_list { | ||
287 | /** file name */ | ||
288 | const char *name; | ||
289 | /** proc callback*/ | ||
290 | int (*f) (char *, char **, off_t, int, int *, void *); | ||
291 | } i915_gem_proc_list[] = { | ||
292 | {"i915_gem_active", i915_gem_active_info}, | ||
293 | {"i915_gem_flushing", i915_gem_flushing_info}, | ||
294 | {"i915_gem_inactive", i915_gem_inactive_info}, | ||
295 | {"i915_gem_request", i915_gem_request_info}, | ||
296 | {"i915_gem_seqno", i915_gem_seqno_info}, | ||
297 | {"i915_gem_interrupt", i915_interrupt_info}, | ||
298 | {"i915_gem_hws", i915_hws_info}, | ||
299 | }; | ||
300 | |||
301 | #define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) | ||
302 | |||
303 | int i915_gem_proc_init(struct drm_minor *minor) | ||
304 | { | ||
305 | struct proc_dir_entry *ent; | ||
306 | int i, j; | ||
307 | |||
308 | for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) { | ||
309 | ent = create_proc_entry(i915_gem_proc_list[i].name, | ||
310 | S_IFREG | S_IRUGO, minor->dev_root); | ||
311 | if (!ent) { | ||
312 | DRM_ERROR("Cannot create /proc/dri/.../%s\n", | ||
313 | i915_gem_proc_list[i].name); | ||
314 | for (j = 0; j < i; j++) | ||
315 | remove_proc_entry(i915_gem_proc_list[i].name, | ||
316 | minor->dev_root); | ||
317 | return -1; | ||
318 | } | ||
319 | ent->read_proc = i915_gem_proc_list[i].f; | ||
320 | ent->data = minor; | ||
321 | } | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | void i915_gem_proc_cleanup(struct drm_minor *minor) | ||
326 | { | ||
327 | int i; | ||
328 | |||
329 | if (!minor->dev_root) | ||
330 | return; | ||
331 | |||
332 | for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) | ||
333 | remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root); | ||
334 | } | ||