diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 1000 |
1 files changed, 799 insertions, 201 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5e43d7076789..0a893f7400fa 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm.h" | 33 | #include "drm.h" |
34 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
35 | #include "intel_ringbuffer.h" | ||
35 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
37 | 38 | ||
@@ -40,23 +41,64 @@ | |||
40 | 41 | ||
41 | #if defined(CONFIG_DEBUG_FS) | 42 | #if defined(CONFIG_DEBUG_FS) |
42 | 43 | ||
43 | #define ACTIVE_LIST 1 | 44 | enum { |
44 | #define FLUSHING_LIST 2 | 45 | ACTIVE_LIST, |
45 | #define INACTIVE_LIST 3 | 46 | FLUSHING_LIST, |
47 | INACTIVE_LIST, | ||
48 | PINNED_LIST, | ||
49 | DEFERRED_FREE_LIST, | ||
50 | }; | ||
51 | |||
52 | static const char *yesno(int v) | ||
53 | { | ||
54 | return v ? "yes" : "no"; | ||
55 | } | ||
56 | |||
57 | static int i915_capabilities(struct seq_file *m, void *data) | ||
58 | { | ||
59 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
60 | struct drm_device *dev = node->minor->dev; | ||
61 | const struct intel_device_info *info = INTEL_INFO(dev); | ||
62 | |||
63 | seq_printf(m, "gen: %d\n", info->gen); | ||
64 | #define B(x) seq_printf(m, #x ": %s\n", yesno(info->x)) | ||
65 | B(is_mobile); | ||
66 | B(is_i85x); | ||
67 | B(is_i915g); | ||
68 | B(is_i945gm); | ||
69 | B(is_g33); | ||
70 | B(need_gfx_hws); | ||
71 | B(is_g4x); | ||
72 | B(is_pineview); | ||
73 | B(is_broadwater); | ||
74 | B(is_crestline); | ||
75 | B(has_fbc); | ||
76 | B(has_pipe_cxsr); | ||
77 | B(has_hotplug); | ||
78 | B(cursor_needs_physical); | ||
79 | B(has_overlay); | ||
80 | B(overlay_needs_physical); | ||
81 | B(supports_tv); | ||
82 | B(has_bsd_ring); | ||
83 | B(has_blt_ring); | ||
84 | #undef B | ||
46 | 85 | ||
47 | static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) | 86 | return 0; |
87 | } | ||
88 | |||
89 | static const char *get_pin_flag(struct drm_i915_gem_object *obj) | ||
48 | { | 90 | { |
49 | if (obj_priv->user_pin_count > 0) | 91 | if (obj->user_pin_count > 0) |
50 | return "P"; | 92 | return "P"; |
51 | else if (obj_priv->pin_count > 0) | 93 | else if (obj->pin_count > 0) |
52 | return "p"; | 94 | return "p"; |
53 | else | 95 | else |
54 | return " "; | 96 | return " "; |
55 | } | 97 | } |
56 | 98 | ||
57 | static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) | 99 | static const char *get_tiling_flag(struct drm_i915_gem_object *obj) |
58 | { | 100 | { |
59 | switch (obj_priv->tiling_mode) { | 101 | switch (obj->tiling_mode) { |
60 | default: | 102 | default: |
61 | case I915_TILING_NONE: return " "; | 103 | case I915_TILING_NONE: return " "; |
62 | case I915_TILING_X: return "X"; | 104 | case I915_TILING_X: return "X"; |
@@ -64,6 +106,51 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) | |||
64 | } | 106 | } |
65 | } | 107 | } |
66 | 108 | ||
109 | static const char *cache_level_str(int type) | ||
110 | { | ||
111 | switch (type) { | ||
112 | case I915_CACHE_NONE: return " uncached"; | ||
113 | case I915_CACHE_LLC: return " snooped (LLC)"; | ||
114 | case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; | ||
115 | default: return ""; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static void | ||
120 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | ||
121 | { | ||
122 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", | ||
123 | &obj->base, | ||
124 | get_pin_flag(obj), | ||
125 | get_tiling_flag(obj), | ||
126 | obj->base.size, | ||
127 | obj->base.read_domains, | ||
128 | obj->base.write_domain, | ||
129 | obj->last_rendering_seqno, | ||
130 | obj->last_fenced_seqno, | ||
131 | cache_level_str(obj->cache_level), | ||
132 | obj->dirty ? " dirty" : "", | ||
133 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | ||
134 | if (obj->base.name) | ||
135 | seq_printf(m, " (name: %d)", obj->base.name); | ||
136 | if (obj->fence_reg != I915_FENCE_REG_NONE) | ||
137 | seq_printf(m, " (fence: %d)", obj->fence_reg); | ||
138 | if (obj->gtt_space != NULL) | ||
139 | seq_printf(m, " (gtt offset: %08x, size: %08x)", | ||
140 | obj->gtt_offset, (unsigned int)obj->gtt_space->size); | ||
141 | if (obj->pin_mappable || obj->fault_mappable) { | ||
142 | char s[3], *t = s; | ||
143 | if (obj->pin_mappable) | ||
144 | *t++ = 'p'; | ||
145 | if (obj->fault_mappable) | ||
146 | *t++ = 'f'; | ||
147 | *t = '\0'; | ||
148 | seq_printf(m, " (%s mappable)", s); | ||
149 | } | ||
150 | if (obj->ring != NULL) | ||
151 | seq_printf(m, " (%s)", obj->ring->name); | ||
152 | } | ||
153 | |||
67 | static int i915_gem_object_list_info(struct seq_file *m, void *data) | 154 | static int i915_gem_object_list_info(struct seq_file *m, void *data) |
68 | { | 155 | { |
69 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 156 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -71,57 +158,167 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
71 | struct list_head *head; | 158 | struct list_head *head; |
72 | struct drm_device *dev = node->minor->dev; | 159 | struct drm_device *dev = node->minor->dev; |
73 | drm_i915_private_t *dev_priv = dev->dev_private; | 160 | drm_i915_private_t *dev_priv = dev->dev_private; |
74 | struct drm_i915_gem_object *obj_priv; | 161 | struct drm_i915_gem_object *obj; |
75 | spinlock_t *lock = NULL; | 162 | size_t total_obj_size, total_gtt_size; |
163 | int count, ret; | ||
164 | |||
165 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
166 | if (ret) | ||
167 | return ret; | ||
76 | 168 | ||
77 | switch (list) { | 169 | switch (list) { |
78 | case ACTIVE_LIST: | 170 | case ACTIVE_LIST: |
79 | seq_printf(m, "Active:\n"); | 171 | seq_printf(m, "Active:\n"); |
80 | lock = &dev_priv->mm.active_list_lock; | 172 | head = &dev_priv->mm.active_list; |
81 | head = &dev_priv->render_ring.active_list; | ||
82 | break; | 173 | break; |
83 | case INACTIVE_LIST: | 174 | case INACTIVE_LIST: |
84 | seq_printf(m, "Inactive:\n"); | 175 | seq_printf(m, "Inactive:\n"); |
85 | head = &dev_priv->mm.inactive_list; | 176 | head = &dev_priv->mm.inactive_list; |
86 | break; | 177 | break; |
178 | case PINNED_LIST: | ||
179 | seq_printf(m, "Pinned:\n"); | ||
180 | head = &dev_priv->mm.pinned_list; | ||
181 | break; | ||
87 | case FLUSHING_LIST: | 182 | case FLUSHING_LIST: |
88 | seq_printf(m, "Flushing:\n"); | 183 | seq_printf(m, "Flushing:\n"); |
89 | head = &dev_priv->mm.flushing_list; | 184 | head = &dev_priv->mm.flushing_list; |
90 | break; | 185 | break; |
186 | case DEFERRED_FREE_LIST: | ||
187 | seq_printf(m, "Deferred free:\n"); | ||
188 | head = &dev_priv->mm.deferred_free_list; | ||
189 | break; | ||
91 | default: | 190 | default: |
92 | DRM_INFO("Ooops, unexpected list\n"); | 191 | mutex_unlock(&dev->struct_mutex); |
93 | return 0; | 192 | return -EINVAL; |
193 | } | ||
194 | |||
195 | total_obj_size = total_gtt_size = count = 0; | ||
196 | list_for_each_entry(obj, head, mm_list) { | ||
197 | seq_printf(m, " "); | ||
198 | describe_obj(m, obj); | ||
199 | seq_printf(m, "\n"); | ||
200 | total_obj_size += obj->base.size; | ||
201 | total_gtt_size += obj->gtt_space->size; | ||
202 | count++; | ||
94 | } | 203 | } |
204 | mutex_unlock(&dev->struct_mutex); | ||
95 | 205 | ||
96 | if (lock) | 206 | seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", |
97 | spin_lock(lock); | 207 | count, total_obj_size, total_gtt_size); |
98 | list_for_each_entry(obj_priv, head, list) | 208 | return 0; |
99 | { | 209 | } |
100 | seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", | ||
101 | &obj_priv->base, | ||
102 | get_pin_flag(obj_priv), | ||
103 | obj_priv->base.size, | ||
104 | obj_priv->base.read_domains, | ||
105 | obj_priv->base.write_domain, | ||
106 | obj_priv->last_rendering_seqno, | ||
107 | obj_priv->dirty ? " dirty" : "", | ||
108 | obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | ||
109 | |||
110 | if (obj_priv->base.name) | ||
111 | seq_printf(m, " (name: %d)", obj_priv->base.name); | ||
112 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | ||
113 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); | ||
114 | if (obj_priv->gtt_space != NULL) | ||
115 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
116 | 210 | ||
211 | #define count_objects(list, member) do { \ | ||
212 | list_for_each_entry(obj, list, member) { \ | ||
213 | size += obj->gtt_space->size; \ | ||
214 | ++count; \ | ||
215 | if (obj->map_and_fenceable) { \ | ||
216 | mappable_size += obj->gtt_space->size; \ | ||
217 | ++mappable_count; \ | ||
218 | } \ | ||
219 | } \ | ||
220 | } while(0) | ||
221 | |||
222 | static int i915_gem_object_info(struct seq_file *m, void* data) | ||
223 | { | ||
224 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
225 | struct drm_device *dev = node->minor->dev; | ||
226 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
227 | u32 count, mappable_count; | ||
228 | size_t size, mappable_size; | ||
229 | struct drm_i915_gem_object *obj; | ||
230 | int ret; | ||
231 | |||
232 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | seq_printf(m, "%u objects, %zu bytes\n", | ||
237 | dev_priv->mm.object_count, | ||
238 | dev_priv->mm.object_memory); | ||
239 | |||
240 | size = count = mappable_size = mappable_count = 0; | ||
241 | count_objects(&dev_priv->mm.gtt_list, gtt_list); | ||
242 | seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", | ||
243 | count, mappable_count, size, mappable_size); | ||
244 | |||
245 | size = count = mappable_size = mappable_count = 0; | ||
246 | count_objects(&dev_priv->mm.active_list, mm_list); | ||
247 | count_objects(&dev_priv->mm.flushing_list, mm_list); | ||
248 | seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", | ||
249 | count, mappable_count, size, mappable_size); | ||
250 | |||
251 | size = count = mappable_size = mappable_count = 0; | ||
252 | count_objects(&dev_priv->mm.pinned_list, mm_list); | ||
253 | seq_printf(m, " %u [%u] pinned objects, %zu [%zu] bytes\n", | ||
254 | count, mappable_count, size, mappable_size); | ||
255 | |||
256 | size = count = mappable_size = mappable_count = 0; | ||
257 | count_objects(&dev_priv->mm.inactive_list, mm_list); | ||
258 | seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", | ||
259 | count, mappable_count, size, mappable_size); | ||
260 | |||
261 | size = count = mappable_size = mappable_count = 0; | ||
262 | count_objects(&dev_priv->mm.deferred_free_list, mm_list); | ||
263 | seq_printf(m, " %u [%u] freed objects, %zu [%zu] bytes\n", | ||
264 | count, mappable_count, size, mappable_size); | ||
265 | |||
266 | size = count = mappable_size = mappable_count = 0; | ||
267 | list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { | ||
268 | if (obj->fault_mappable) { | ||
269 | size += obj->gtt_space->size; | ||
270 | ++count; | ||
271 | } | ||
272 | if (obj->pin_mappable) { | ||
273 | mappable_size += obj->gtt_space->size; | ||
274 | ++mappable_count; | ||
275 | } | ||
276 | } | ||
277 | seq_printf(m, "%u pinned mappable objects, %zu bytes\n", | ||
278 | mappable_count, mappable_size); | ||
279 | seq_printf(m, "%u fault mappable objects, %zu bytes\n", | ||
280 | count, size); | ||
281 | |||
282 | seq_printf(m, "%zu [%zu] gtt total\n", | ||
283 | dev_priv->mm.gtt_total, dev_priv->mm.mappable_gtt_total); | ||
284 | |||
285 | mutex_unlock(&dev->struct_mutex); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int i915_gem_gtt_info(struct seq_file *m, void* data) | ||
291 | { | ||
292 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
293 | struct drm_device *dev = node->minor->dev; | ||
294 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
295 | struct drm_i915_gem_object *obj; | ||
296 | size_t total_obj_size, total_gtt_size; | ||
297 | int count, ret; | ||
298 | |||
299 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
300 | if (ret) | ||
301 | return ret; | ||
302 | |||
303 | total_obj_size = total_gtt_size = count = 0; | ||
304 | list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { | ||
305 | seq_printf(m, " "); | ||
306 | describe_obj(m, obj); | ||
117 | seq_printf(m, "\n"); | 307 | seq_printf(m, "\n"); |
308 | total_obj_size += obj->base.size; | ||
309 | total_gtt_size += obj->gtt_space->size; | ||
310 | count++; | ||
118 | } | 311 | } |
119 | 312 | ||
120 | if (lock) | 313 | mutex_unlock(&dev->struct_mutex); |
121 | spin_unlock(lock); | 314 | |
315 | seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", | ||
316 | count, total_obj_size, total_gtt_size); | ||
317 | |||
122 | return 0; | 318 | return 0; |
123 | } | 319 | } |
124 | 320 | ||
321 | |||
125 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) | 322 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) |
126 | { | 323 | { |
127 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 324 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -130,21 +327,21 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) | |||
130 | struct intel_crtc *crtc; | 327 | struct intel_crtc *crtc; |
131 | 328 | ||
132 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | 329 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { |
133 | const char *pipe = crtc->pipe ? "B" : "A"; | 330 | const char pipe = pipe_name(crtc->pipe); |
134 | const char *plane = crtc->plane ? "B" : "A"; | 331 | const char plane = plane_name(crtc->plane); |
135 | struct intel_unpin_work *work; | 332 | struct intel_unpin_work *work; |
136 | 333 | ||
137 | spin_lock_irqsave(&dev->event_lock, flags); | 334 | spin_lock_irqsave(&dev->event_lock, flags); |
138 | work = crtc->unpin_work; | 335 | work = crtc->unpin_work; |
139 | if (work == NULL) { | 336 | if (work == NULL) { |
140 | seq_printf(m, "No flip due on pipe %s (plane %s)\n", | 337 | seq_printf(m, "No flip due on pipe %c (plane %c)\n", |
141 | pipe, plane); | 338 | pipe, plane); |
142 | } else { | 339 | } else { |
143 | if (!work->pending) { | 340 | if (!work->pending) { |
144 | seq_printf(m, "Flip queued on pipe %s (plane %s)\n", | 341 | seq_printf(m, "Flip queued on pipe %c (plane %c)\n", |
145 | pipe, plane); | 342 | pipe, plane); |
146 | } else { | 343 | } else { |
147 | seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n", | 344 | seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n", |
148 | pipe, plane); | 345 | pipe, plane); |
149 | } | 346 | } |
150 | if (work->enable_stall_check) | 347 | if (work->enable_stall_check) |
@@ -154,14 +351,14 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) | |||
154 | seq_printf(m, "%d prepares\n", work->pending); | 351 | seq_printf(m, "%d prepares\n", work->pending); |
155 | 352 | ||
156 | if (work->old_fb_obj) { | 353 | if (work->old_fb_obj) { |
157 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); | 354 | struct drm_i915_gem_object *obj = work->old_fb_obj; |
158 | if(obj_priv) | 355 | if (obj) |
159 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | 356 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); |
160 | } | 357 | } |
161 | if (work->pending_flip_obj) { | 358 | if (work->pending_flip_obj) { |
162 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); | 359 | struct drm_i915_gem_object *obj = work->pending_flip_obj; |
163 | if(obj_priv) | 360 | if (obj) |
164 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | 361 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); |
165 | } | 362 | } |
166 | } | 363 | } |
167 | spin_unlock_irqrestore(&dev->event_lock, flags); | 364 | spin_unlock_irqrestore(&dev->event_lock, flags); |
@@ -176,32 +373,83 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
176 | struct drm_device *dev = node->minor->dev; | 373 | struct drm_device *dev = node->minor->dev; |
177 | drm_i915_private_t *dev_priv = dev->dev_private; | 374 | drm_i915_private_t *dev_priv = dev->dev_private; |
178 | struct drm_i915_gem_request *gem_request; | 375 | struct drm_i915_gem_request *gem_request; |
376 | int ret, count; | ||
377 | |||
378 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
379 | if (ret) | ||
380 | return ret; | ||
179 | 381 | ||
180 | seq_printf(m, "Request:\n"); | 382 | count = 0; |
181 | list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, | 383 | if (!list_empty(&dev_priv->ring[RCS].request_list)) { |
182 | list) { | 384 | seq_printf(m, "Render requests:\n"); |
183 | seq_printf(m, " %d @ %d\n", | 385 | list_for_each_entry(gem_request, |
184 | gem_request->seqno, | 386 | &dev_priv->ring[RCS].request_list, |
185 | (int) (jiffies - gem_request->emitted_jiffies)); | 387 | list) { |
388 | seq_printf(m, " %d @ %d\n", | ||
389 | gem_request->seqno, | ||
390 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
391 | } | ||
392 | count++; | ||
393 | } | ||
394 | if (!list_empty(&dev_priv->ring[VCS].request_list)) { | ||
395 | seq_printf(m, "BSD requests:\n"); | ||
396 | list_for_each_entry(gem_request, | ||
397 | &dev_priv->ring[VCS].request_list, | ||
398 | list) { | ||
399 | seq_printf(m, " %d @ %d\n", | ||
400 | gem_request->seqno, | ||
401 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
402 | } | ||
403 | count++; | ||
186 | } | 404 | } |
405 | if (!list_empty(&dev_priv->ring[BCS].request_list)) { | ||
406 | seq_printf(m, "BLT requests:\n"); | ||
407 | list_for_each_entry(gem_request, | ||
408 | &dev_priv->ring[BCS].request_list, | ||
409 | list) { | ||
410 | seq_printf(m, " %d @ %d\n", | ||
411 | gem_request->seqno, | ||
412 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
413 | } | ||
414 | count++; | ||
415 | } | ||
416 | mutex_unlock(&dev->struct_mutex); | ||
417 | |||
418 | if (count == 0) | ||
419 | seq_printf(m, "No requests\n"); | ||
420 | |||
187 | return 0; | 421 | return 0; |
188 | } | 422 | } |
189 | 423 | ||
424 | static void i915_ring_seqno_info(struct seq_file *m, | ||
425 | struct intel_ring_buffer *ring) | ||
426 | { | ||
427 | if (ring->get_seqno) { | ||
428 | seq_printf(m, "Current sequence (%s): %d\n", | ||
429 | ring->name, ring->get_seqno(ring)); | ||
430 | seq_printf(m, "Waiter sequence (%s): %d\n", | ||
431 | ring->name, ring->waiting_seqno); | ||
432 | seq_printf(m, "IRQ sequence (%s): %d\n", | ||
433 | ring->name, ring->irq_seqno); | ||
434 | } | ||
435 | } | ||
436 | |||
190 | static int i915_gem_seqno_info(struct seq_file *m, void *data) | 437 | static int i915_gem_seqno_info(struct seq_file *m, void *data) |
191 | { | 438 | { |
192 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 439 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
193 | struct drm_device *dev = node->minor->dev; | 440 | struct drm_device *dev = node->minor->dev; |
194 | drm_i915_private_t *dev_priv = dev->dev_private; | 441 | drm_i915_private_t *dev_priv = dev->dev_private; |
442 | int ret, i; | ||
443 | |||
444 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
445 | if (ret) | ||
446 | return ret; | ||
447 | |||
448 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
449 | i915_ring_seqno_info(m, &dev_priv->ring[i]); | ||
450 | |||
451 | mutex_unlock(&dev->struct_mutex); | ||
195 | 452 | ||
196 | if (dev_priv->render_ring.status_page.page_addr != NULL) { | ||
197 | seq_printf(m, "Current sequence: %d\n", | ||
198 | i915_get_gem_seqno(dev, &dev_priv->render_ring)); | ||
199 | } else { | ||
200 | seq_printf(m, "Current sequence: hws uninitialized\n"); | ||
201 | } | ||
202 | seq_printf(m, "Waiter sequence: %d\n", | ||
203 | dev_priv->mm.waiting_gem_seqno); | ||
204 | seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | ||
205 | return 0; | 453 | return 0; |
206 | } | 454 | } |
207 | 455 | ||
@@ -211,6 +459,11 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
211 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 459 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
212 | struct drm_device *dev = node->minor->dev; | 460 | struct drm_device *dev = node->minor->dev; |
213 | drm_i915_private_t *dev_priv = dev->dev_private; | 461 | drm_i915_private_t *dev_priv = dev->dev_private; |
462 | int ret, i, pipe; | ||
463 | |||
464 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
465 | if (ret) | ||
466 | return ret; | ||
214 | 467 | ||
215 | if (!HAS_PCH_SPLIT(dev)) { | 468 | if (!HAS_PCH_SPLIT(dev)) { |
216 | seq_printf(m, "Interrupt enable: %08x\n", | 469 | seq_printf(m, "Interrupt enable: %08x\n", |
@@ -219,10 +472,10 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
219 | I915_READ(IIR)); | 472 | I915_READ(IIR)); |
220 | seq_printf(m, "Interrupt mask: %08x\n", | 473 | seq_printf(m, "Interrupt mask: %08x\n", |
221 | I915_READ(IMR)); | 474 | I915_READ(IMR)); |
222 | seq_printf(m, "Pipe A stat: %08x\n", | 475 | for_each_pipe(pipe) |
223 | I915_READ(PIPEASTAT)); | 476 | seq_printf(m, "Pipe %c stat: %08x\n", |
224 | seq_printf(m, "Pipe B stat: %08x\n", | 477 | pipe_name(pipe), |
225 | I915_READ(PIPEBSTAT)); | 478 | I915_READ(PIPESTAT(pipe))); |
226 | } else { | 479 | } else { |
227 | seq_printf(m, "North Display Interrupt enable: %08x\n", | 480 | seq_printf(m, "North Display Interrupt enable: %08x\n", |
228 | I915_READ(DEIER)); | 481 | I915_READ(DEIER)); |
@@ -245,16 +498,16 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
245 | } | 498 | } |
246 | seq_printf(m, "Interrupts received: %d\n", | 499 | seq_printf(m, "Interrupts received: %d\n", |
247 | atomic_read(&dev_priv->irq_received)); | 500 | atomic_read(&dev_priv->irq_received)); |
248 | if (dev_priv->render_ring.status_page.page_addr != NULL) { | 501 | for (i = 0; i < I915_NUM_RINGS; i++) { |
249 | seq_printf(m, "Current sequence: %d\n", | 502 | if (IS_GEN6(dev)) { |
250 | i915_get_gem_seqno(dev, &dev_priv->render_ring)); | 503 | seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", |
251 | } else { | 504 | dev_priv->ring[i].name, |
252 | seq_printf(m, "Current sequence: hws uninitialized\n"); | 505 | I915_READ_IMR(&dev_priv->ring[i])); |
506 | } | ||
507 | i915_ring_seqno_info(m, &dev_priv->ring[i]); | ||
253 | } | 508 | } |
254 | seq_printf(m, "Waiter sequence: %d\n", | 509 | mutex_unlock(&dev->struct_mutex); |
255 | dev_priv->mm.waiting_gem_seqno); | 510 | |
256 | seq_printf(m, "IRQ sequence: %d\n", | ||
257 | dev_priv->mm.irq_gem_seqno); | ||
258 | return 0; | 511 | return 0; |
259 | } | 512 | } |
260 | 513 | ||
@@ -263,33 +516,26 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) | |||
263 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 516 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
264 | struct drm_device *dev = node->minor->dev; | 517 | struct drm_device *dev = node->minor->dev; |
265 | drm_i915_private_t *dev_priv = dev->dev_private; | 518 | drm_i915_private_t *dev_priv = dev->dev_private; |
266 | int i; | 519 | int i, ret; |
520 | |||
521 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
522 | if (ret) | ||
523 | return ret; | ||
267 | 524 | ||
268 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); | 525 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); |
269 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); | 526 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); |
270 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 527 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
271 | struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; | 528 | struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; |
272 | 529 | ||
273 | if (obj == NULL) { | 530 | seq_printf(m, "Fenced object[%2d] = ", i); |
274 | seq_printf(m, "Fenced object[%2d] = unused\n", i); | 531 | if (obj == NULL) |
275 | } else { | 532 | seq_printf(m, "unused"); |
276 | struct drm_i915_gem_object *obj_priv; | 533 | else |
277 | 534 | describe_obj(m, obj); | |
278 | obj_priv = to_intel_bo(obj); | 535 | seq_printf(m, "\n"); |
279 | seq_printf(m, "Fenced object[%2d] = %p: %s " | ||
280 | "%08x %08zx %08x %s %08x %08x %d", | ||
281 | i, obj, get_pin_flag(obj_priv), | ||
282 | obj_priv->gtt_offset, | ||
283 | obj->size, obj_priv->stride, | ||
284 | get_tiling_flag(obj_priv), | ||
285 | obj->read_domains, obj->write_domain, | ||
286 | obj_priv->last_rendering_seqno); | ||
287 | if (obj->name) | ||
288 | seq_printf(m, " (name: %d)", obj->name); | ||
289 | seq_printf(m, "\n"); | ||
290 | } | ||
291 | } | 536 | } |
292 | 537 | ||
538 | mutex_unlock(&dev->struct_mutex); | ||
293 | return 0; | 539 | return 0; |
294 | } | 540 | } |
295 | 541 | ||
@@ -298,10 +544,12 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
298 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 544 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
299 | struct drm_device *dev = node->minor->dev; | 545 | struct drm_device *dev = node->minor->dev; |
300 | drm_i915_private_t *dev_priv = dev->dev_private; | 546 | drm_i915_private_t *dev_priv = dev->dev_private; |
547 | struct intel_ring_buffer *ring; | ||
548 | const volatile u32 __iomem *hws; | ||
301 | int i; | 549 | int i; |
302 | volatile u32 *hws; | ||
303 | 550 | ||
304 | hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; | 551 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
552 | hws = (volatile u32 __iomem *)ring->status_page.page_addr; | ||
305 | if (hws == NULL) | 553 | if (hws == NULL) |
306 | return 0; | 554 | return 0; |
307 | 555 | ||
@@ -313,16 +561,19 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
313 | return 0; | 561 | return 0; |
314 | } | 562 | } |
315 | 563 | ||
316 | static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count) | 564 | static void i915_dump_object(struct seq_file *m, |
565 | struct io_mapping *mapping, | ||
566 | struct drm_i915_gem_object *obj) | ||
317 | { | 567 | { |
318 | int page, i; | 568 | int page, page_count, i; |
319 | uint32_t *mem; | ||
320 | 569 | ||
570 | page_count = obj->base.size / PAGE_SIZE; | ||
321 | for (page = 0; page < page_count; page++) { | 571 | for (page = 0; page < page_count; page++) { |
322 | mem = kmap_atomic(pages[page], KM_USER0); | 572 | u32 *mem = io_mapping_map_wc(mapping, |
573 | obj->gtt_offset + page * PAGE_SIZE); | ||
323 | for (i = 0; i < PAGE_SIZE; i += 4) | 574 | for (i = 0; i < PAGE_SIZE; i += 4) |
324 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 575 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
325 | kunmap_atomic(mem, KM_USER0); | 576 | io_mapping_unmap(mem); |
326 | } | 577 | } |
327 | } | 578 | } |
328 | 579 | ||
@@ -331,32 +582,21 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
331 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 582 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
332 | struct drm_device *dev = node->minor->dev; | 583 | struct drm_device *dev = node->minor->dev; |
333 | drm_i915_private_t *dev_priv = dev->dev_private; | 584 | drm_i915_private_t *dev_priv = dev->dev_private; |
334 | struct drm_gem_object *obj; | 585 | struct drm_i915_gem_object *obj; |
335 | struct drm_i915_gem_object *obj_priv; | ||
336 | int ret; | 586 | int ret; |
337 | 587 | ||
338 | spin_lock(&dev_priv->mm.active_list_lock); | 588 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
339 | 589 | if (ret) | |
340 | list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, | 590 | return ret; |
341 | list) { | ||
342 | obj = &obj_priv->base; | ||
343 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | ||
344 | ret = i915_gem_object_get_pages(obj, 0); | ||
345 | if (ret) { | ||
346 | DRM_ERROR("Failed to get pages: %d\n", ret); | ||
347 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset); | ||
352 | i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE); | ||
353 | 591 | ||
354 | i915_gem_object_put_pages(obj); | 592 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
593 | if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { | ||
594 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); | ||
595 | i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); | ||
355 | } | 596 | } |
356 | } | 597 | } |
357 | 598 | ||
358 | spin_unlock(&dev_priv->mm.active_list_lock); | 599 | mutex_unlock(&dev->struct_mutex); |
359 | |||
360 | return 0; | 600 | return 0; |
361 | } | 601 | } |
362 | 602 | ||
@@ -365,20 +605,26 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) | |||
365 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 605 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
366 | struct drm_device *dev = node->minor->dev; | 606 | struct drm_device *dev = node->minor->dev; |
367 | drm_i915_private_t *dev_priv = dev->dev_private; | 607 | drm_i915_private_t *dev_priv = dev->dev_private; |
368 | u8 *virt; | 608 | struct intel_ring_buffer *ring; |
369 | uint32_t *ptr, off; | 609 | int ret; |
370 | 610 | ||
371 | if (!dev_priv->render_ring.gem_object) { | 611 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
372 | seq_printf(m, "No ringbuffer setup\n"); | 612 | if (ret) |
373 | return 0; | 613 | return ret; |
374 | } | ||
375 | 614 | ||
376 | virt = dev_priv->render_ring.virtual_start; | 615 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
616 | if (!ring->obj) { | ||
617 | seq_printf(m, "No ringbuffer setup\n"); | ||
618 | } else { | ||
619 | const u8 __iomem *virt = ring->virtual_start; | ||
620 | uint32_t off; | ||
377 | 621 | ||
378 | for (off = 0; off < dev_priv->render_ring.size; off += 4) { | 622 | for (off = 0; off < ring->size; off += 4) { |
379 | ptr = (uint32_t *)(virt + off); | 623 | uint32_t *ptr = (uint32_t *)(virt + off); |
380 | seq_printf(m, "%08x : %08x\n", off, *ptr); | 624 | seq_printf(m, "%08x : %08x\n", off, *ptr); |
625 | } | ||
381 | } | 626 | } |
627 | mutex_unlock(&dev->struct_mutex); | ||
382 | 628 | ||
383 | return 0; | 629 | return 0; |
384 | } | 630 | } |
@@ -388,19 +634,38 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
388 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 634 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
389 | struct drm_device *dev = node->minor->dev; | 635 | struct drm_device *dev = node->minor->dev; |
390 | drm_i915_private_t *dev_priv = dev->dev_private; | 636 | drm_i915_private_t *dev_priv = dev->dev_private; |
391 | unsigned int head, tail; | 637 | struct intel_ring_buffer *ring; |
392 | 638 | ||
393 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 639 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
394 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 640 | if (ring->size == 0) |
641 | return 0; | ||
395 | 642 | ||
396 | seq_printf(m, "RingHead : %08x\n", head); | 643 | seq_printf(m, "Ring %s:\n", ring->name); |
397 | seq_printf(m, "RingTail : %08x\n", tail); | 644 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); |
398 | seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); | 645 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); |
399 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | 646 | seq_printf(m, " Size : %08x\n", ring->size); |
647 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); | ||
648 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); | ||
649 | if (IS_GEN6(dev)) { | ||
650 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); | ||
651 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); | ||
652 | } | ||
653 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); | ||
654 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); | ||
400 | 655 | ||
401 | return 0; | 656 | return 0; |
402 | } | 657 | } |
403 | 658 | ||
659 | static const char *ring_str(int ring) | ||
660 | { | ||
661 | switch (ring) { | ||
662 | case RING_RENDER: return " render"; | ||
663 | case RING_BSD: return " bsd"; | ||
664 | case RING_BLT: return " blt"; | ||
665 | default: return ""; | ||
666 | } | ||
667 | } | ||
668 | |||
404 | static const char *pin_flag(int pinned) | 669 | static const char *pin_flag(int pinned) |
405 | { | 670 | { |
406 | if (pinned > 0) | 671 | if (pinned > 0) |
@@ -431,6 +696,37 @@ static const char *purgeable_flag(int purgeable) | |||
431 | return purgeable ? " purgeable" : ""; | 696 | return purgeable ? " purgeable" : ""; |
432 | } | 697 | } |
433 | 698 | ||
699 | static void print_error_buffers(struct seq_file *m, | ||
700 | const char *name, | ||
701 | struct drm_i915_error_buffer *err, | ||
702 | int count) | ||
703 | { | ||
704 | seq_printf(m, "%s [%d]:\n", name, count); | ||
705 | |||
706 | while (count--) { | ||
707 | seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", | ||
708 | err->gtt_offset, | ||
709 | err->size, | ||
710 | err->read_domains, | ||
711 | err->write_domain, | ||
712 | err->seqno, | ||
713 | pin_flag(err->pinned), | ||
714 | tiling_flag(err->tiling), | ||
715 | dirty_flag(err->dirty), | ||
716 | purgeable_flag(err->purgeable), | ||
717 | ring_str(err->ring), | ||
718 | cache_level_str(err->cache_level)); | ||
719 | |||
720 | if (err->name) | ||
721 | seq_printf(m, " (name: %d)", err->name); | ||
722 | if (err->fence_reg != I915_FENCE_REG_NONE) | ||
723 | seq_printf(m, " (fence: %d)", err->fence_reg); | ||
724 | |||
725 | seq_printf(m, "\n"); | ||
726 | err++; | ||
727 | } | ||
728 | } | ||
729 | |||
434 | static int i915_error_state(struct seq_file *m, void *unused) | 730 | static int i915_error_state(struct seq_file *m, void *unused) |
435 | { | 731 | { |
436 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 732 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -452,47 +748,54 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
452 | error->time.tv_usec); | 748 | error->time.tv_usec); |
453 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); | 749 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); |
454 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | 750 | seq_printf(m, "EIR: 0x%08x\n", error->eir); |
455 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 751 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
456 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | 752 | if (INTEL_INFO(dev)->gen >= 6) { |
753 | seq_printf(m, "ERROR: 0x%08x\n", error->error); | ||
754 | seq_printf(m, "Blitter command stream:\n"); | ||
755 | seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); | ||
756 | seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); | ||
757 | seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); | ||
758 | seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); | ||
759 | seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); | ||
760 | seq_printf(m, "Video (BSD) command stream:\n"); | ||
761 | seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); | ||
762 | seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); | ||
763 | seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); | ||
764 | seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); | ||
765 | seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); | ||
766 | } | ||
767 | seq_printf(m, "Render command stream:\n"); | ||
768 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
457 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | 769 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); |
458 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | 770 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); |
459 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | 771 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); |
460 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | 772 | if (INTEL_INFO(dev)->gen >= 4) { |
461 | if (IS_I965G(dev)) { | ||
462 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
463 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | 773 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); |
774 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
464 | } | 775 | } |
465 | seq_printf(m, "seqno: 0x%08x\n", error->seqno); | 776 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); |
466 | 777 | seq_printf(m, " seqno: 0x%08x\n", error->seqno); | |
467 | if (error->active_bo_count) { | 778 | |
468 | seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); | 779 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
469 | 780 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); | |
470 | for (i = 0; i < error->active_bo_count; i++) { | 781 | |
471 | seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s", | 782 | if (error->active_bo) |
472 | error->active_bo[i].gtt_offset, | 783 | print_error_buffers(m, "Active", |
473 | error->active_bo[i].size, | 784 | error->active_bo, |
474 | error->active_bo[i].read_domains, | 785 | error->active_bo_count); |
475 | error->active_bo[i].write_domain, | 786 | |
476 | error->active_bo[i].seqno, | 787 | if (error->pinned_bo) |
477 | pin_flag(error->active_bo[i].pinned), | 788 | print_error_buffers(m, "Pinned", |
478 | tiling_flag(error->active_bo[i].tiling), | 789 | error->pinned_bo, |
479 | dirty_flag(error->active_bo[i].dirty), | 790 | error->pinned_bo_count); |
480 | purgeable_flag(error->active_bo[i].purgeable)); | ||
481 | |||
482 | if (error->active_bo[i].name) | ||
483 | seq_printf(m, " (name: %d)", error->active_bo[i].name); | ||
484 | if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE) | ||
485 | seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg); | ||
486 | |||
487 | seq_printf(m, "\n"); | ||
488 | } | ||
489 | } | ||
490 | 791 | ||
491 | for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { | 792 | for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { |
492 | if (error->batchbuffer[i]) { | 793 | if (error->batchbuffer[i]) { |
493 | struct drm_i915_error_object *obj = error->batchbuffer[i]; | 794 | struct drm_i915_error_object *obj = error->batchbuffer[i]; |
494 | 795 | ||
495 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); | 796 | seq_printf(m, "%s --- gtt_offset = 0x%08x\n", |
797 | dev_priv->ring[i].name, | ||
798 | obj->gtt_offset); | ||
496 | offset = 0; | 799 | offset = 0; |
497 | for (page = 0; page < obj->page_count; page++) { | 800 | for (page = 0; page < obj->page_count; page++) { |
498 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | 801 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
@@ -503,15 +806,20 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
503 | } | 806 | } |
504 | } | 807 | } |
505 | 808 | ||
506 | if (error->ringbuffer) { | 809 | for (i = 0; i < ARRAY_SIZE(error->ringbuffer); i++) { |
507 | struct drm_i915_error_object *obj = error->ringbuffer; | 810 | if (error->ringbuffer[i]) { |
508 | 811 | struct drm_i915_error_object *obj = error->ringbuffer[i]; | |
509 | seq_printf(m, "--- ringbuffer = 0x%08x\n", obj->gtt_offset); | 812 | seq_printf(m, "%s --- ringbuffer = 0x%08x\n", |
510 | offset = 0; | 813 | dev_priv->ring[i].name, |
511 | for (page = 0; page < obj->page_count; page++) { | 814 | obj->gtt_offset); |
512 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | 815 | offset = 0; |
513 | seq_printf(m, "%08x : %08x\n", offset, obj->pages[page][elt]); | 816 | for (page = 0; page < obj->page_count; page++) { |
514 | offset += 4; | 817 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
818 | seq_printf(m, "%08x : %08x\n", | ||
819 | offset, | ||
820 | obj->pages[page][elt]); | ||
821 | offset += 4; | ||
822 | } | ||
515 | } | 823 | } |
516 | } | 824 | } |
517 | } | 825 | } |
@@ -519,6 +827,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
519 | if (error->overlay) | 827 | if (error->overlay) |
520 | intel_overlay_print_error_state(m, error->overlay); | 828 | intel_overlay_print_error_state(m, error->overlay); |
521 | 829 | ||
830 | if (error->display) | ||
831 | intel_display_print_error_state(m, dev, error->display); | ||
832 | |||
522 | out: | 833 | out: |
523 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 834 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
524 | 835 | ||
@@ -542,15 +853,82 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) | |||
542 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 853 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
543 | struct drm_device *dev = node->minor->dev; | 854 | struct drm_device *dev = node->minor->dev; |
544 | drm_i915_private_t *dev_priv = dev->dev_private; | 855 | drm_i915_private_t *dev_priv = dev->dev_private; |
545 | u16 rgvswctl = I915_READ16(MEMSWCTL); | 856 | int ret; |
546 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); | ||
547 | 857 | ||
548 | seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); | 858 | if (IS_GEN5(dev)) { |
549 | seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); | 859 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
550 | seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> | 860 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); |
551 | MEMSTAT_VID_SHIFT); | 861 | |
552 | seq_printf(m, "Current P-state: %d\n", | 862 | seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); |
553 | (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | 863 | seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); |
864 | seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> | ||
865 | MEMSTAT_VID_SHIFT); | ||
866 | seq_printf(m, "Current P-state: %d\n", | ||
867 | (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | ||
868 | } else if (IS_GEN6(dev)) { | ||
869 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
870 | u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); | ||
871 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
872 | u32 rpstat; | ||
873 | u32 rpupei, rpcurup, rpprevup; | ||
874 | u32 rpdownei, rpcurdown, rpprevdown; | ||
875 | int max_freq; | ||
876 | |||
877 | /* RPSTAT1 is in the GT power well */ | ||
878 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
879 | if (ret) | ||
880 | return ret; | ||
881 | |||
882 | gen6_gt_force_wake_get(dev_priv); | ||
883 | |||
884 | rpstat = I915_READ(GEN6_RPSTAT1); | ||
885 | rpupei = I915_READ(GEN6_RP_CUR_UP_EI); | ||
886 | rpcurup = I915_READ(GEN6_RP_CUR_UP); | ||
887 | rpprevup = I915_READ(GEN6_RP_PREV_UP); | ||
888 | rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI); | ||
889 | rpcurdown = I915_READ(GEN6_RP_CUR_DOWN); | ||
890 | rpprevdown = I915_READ(GEN6_RP_PREV_DOWN); | ||
891 | |||
892 | gen6_gt_force_wake_put(dev_priv); | ||
893 | mutex_unlock(&dev->struct_mutex); | ||
894 | |||
895 | seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); | ||
896 | seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat); | ||
897 | seq_printf(m, "Render p-state ratio: %d\n", | ||
898 | (gt_perf_status & 0xff00) >> 8); | ||
899 | seq_printf(m, "Render p-state VID: %d\n", | ||
900 | gt_perf_status & 0xff); | ||
901 | seq_printf(m, "Render p-state limit: %d\n", | ||
902 | rp_state_limits & 0xff); | ||
903 | seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >> | ||
904 | GEN6_CAGF_SHIFT) * 50); | ||
905 | seq_printf(m, "RP CUR UP EI: %dus\n", rpupei & | ||
906 | GEN6_CURICONT_MASK); | ||
907 | seq_printf(m, "RP CUR UP: %dus\n", rpcurup & | ||
908 | GEN6_CURBSYTAVG_MASK); | ||
909 | seq_printf(m, "RP PREV UP: %dus\n", rpprevup & | ||
910 | GEN6_CURBSYTAVG_MASK); | ||
911 | seq_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei & | ||
912 | GEN6_CURIAVG_MASK); | ||
913 | seq_printf(m, "RP CUR DOWN: %dus\n", rpcurdown & | ||
914 | GEN6_CURBSYTAVG_MASK); | ||
915 | seq_printf(m, "RP PREV DOWN: %dus\n", rpprevdown & | ||
916 | GEN6_CURBSYTAVG_MASK); | ||
917 | |||
918 | max_freq = (rp_state_cap & 0xff0000) >> 16; | ||
919 | seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", | ||
920 | max_freq * 50); | ||
921 | |||
922 | max_freq = (rp_state_cap & 0xff00) >> 8; | ||
923 | seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", | ||
924 | max_freq * 50); | ||
925 | |||
926 | max_freq = rp_state_cap & 0xff; | ||
927 | seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", | ||
928 | max_freq * 50); | ||
929 | } else { | ||
930 | seq_printf(m, "no P-state info available\n"); | ||
931 | } | ||
554 | 932 | ||
555 | return 0; | 933 | return 0; |
556 | } | 934 | } |
@@ -599,7 +977,7 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
599 | struct drm_device *dev = node->minor->dev; | 977 | struct drm_device *dev = node->minor->dev; |
600 | drm_i915_private_t *dev_priv = dev->dev_private; | 978 | drm_i915_private_t *dev_priv = dev->dev_private; |
601 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 979 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
602 | u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); | 980 | u32 rstdbyctl = I915_READ(RSTDBYCTL); |
603 | u16 crstandvid = I915_READ16(CRSTANDVID); | 981 | u16 crstandvid = I915_READ16(CRSTANDVID); |
604 | 982 | ||
605 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? | 983 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
@@ -622,6 +1000,30 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
622 | seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); | 1000 | seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); |
623 | seq_printf(m, "Render standby enabled: %s\n", | 1001 | seq_printf(m, "Render standby enabled: %s\n", |
624 | (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); | 1002 | (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); |
1003 | seq_printf(m, "Current RS state: "); | ||
1004 | switch (rstdbyctl & RSX_STATUS_MASK) { | ||
1005 | case RSX_STATUS_ON: | ||
1006 | seq_printf(m, "on\n"); | ||
1007 | break; | ||
1008 | case RSX_STATUS_RC1: | ||
1009 | seq_printf(m, "RC1\n"); | ||
1010 | break; | ||
1011 | case RSX_STATUS_RC1E: | ||
1012 | seq_printf(m, "RC1E\n"); | ||
1013 | break; | ||
1014 | case RSX_STATUS_RS1: | ||
1015 | seq_printf(m, "RS1\n"); | ||
1016 | break; | ||
1017 | case RSX_STATUS_RS2: | ||
1018 | seq_printf(m, "RS2 (RC6)\n"); | ||
1019 | break; | ||
1020 | case RSX_STATUS_RS3: | ||
1021 | seq_printf(m, "RC3 (RC6+)\n"); | ||
1022 | break; | ||
1023 | default: | ||
1024 | seq_printf(m, "unknown\n"); | ||
1025 | break; | ||
1026 | } | ||
625 | 1027 | ||
626 | return 0; | 1028 | return 0; |
627 | } | 1029 | } |
@@ -642,6 +1044,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
642 | } else { | 1044 | } else { |
643 | seq_printf(m, "FBC disabled: "); | 1045 | seq_printf(m, "FBC disabled: "); |
644 | switch (dev_priv->no_fbc_reason) { | 1046 | switch (dev_priv->no_fbc_reason) { |
1047 | case FBC_NO_OUTPUT: | ||
1048 | seq_printf(m, "no outputs"); | ||
1049 | break; | ||
645 | case FBC_STOLEN_TOO_SMALL: | 1050 | case FBC_STOLEN_TOO_SMALL: |
646 | seq_printf(m, "not enough stolen memory"); | 1051 | seq_printf(m, "not enough stolen memory"); |
647 | break; | 1052 | break; |
@@ -660,6 +1065,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
660 | case FBC_MULTIPLE_PIPES: | 1065 | case FBC_MULTIPLE_PIPES: |
661 | seq_printf(m, "multiple pipes are enabled"); | 1066 | seq_printf(m, "multiple pipes are enabled"); |
662 | break; | 1067 | break; |
1068 | case FBC_MODULE_PARAM: | ||
1069 | seq_printf(m, "disabled per module param (default off)"); | ||
1070 | break; | ||
663 | default: | 1071 | default: |
664 | seq_printf(m, "unknown reason"); | 1072 | seq_printf(m, "unknown reason"); |
665 | } | 1073 | } |
@@ -675,15 +1083,17 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
675 | drm_i915_private_t *dev_priv = dev->dev_private; | 1083 | drm_i915_private_t *dev_priv = dev->dev_private; |
676 | bool sr_enabled = false; | 1084 | bool sr_enabled = false; |
677 | 1085 | ||
678 | if (IS_I965GM(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 1086 | if (HAS_PCH_SPLIT(dev)) |
1087 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | ||
1088 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) | ||
679 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 1089 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
680 | else if (IS_I915GM(dev)) | 1090 | else if (IS_I915GM(dev)) |
681 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; | 1091 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; |
682 | else if (IS_PINEVIEW(dev)) | 1092 | else if (IS_PINEVIEW(dev)) |
683 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; | 1093 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; |
684 | 1094 | ||
685 | seq_printf(m, "self-refresh: %s\n", sr_enabled ? "enabled" : | 1095 | seq_printf(m, "self-refresh: %s\n", |
686 | "disabled"); | 1096 | sr_enabled ? "enabled" : "disabled"); |
687 | 1097 | ||
688 | return 0; | 1098 | return 0; |
689 | } | 1099 | } |
@@ -694,10 +1104,16 @@ static int i915_emon_status(struct seq_file *m, void *unused) | |||
694 | struct drm_device *dev = node->minor->dev; | 1104 | struct drm_device *dev = node->minor->dev; |
695 | drm_i915_private_t *dev_priv = dev->dev_private; | 1105 | drm_i915_private_t *dev_priv = dev->dev_private; |
696 | unsigned long temp, chipset, gfx; | 1106 | unsigned long temp, chipset, gfx; |
1107 | int ret; | ||
1108 | |||
1109 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1110 | if (ret) | ||
1111 | return ret; | ||
697 | 1112 | ||
698 | temp = i915_mch_val(dev_priv); | 1113 | temp = i915_mch_val(dev_priv); |
699 | chipset = i915_chipset_val(dev_priv); | 1114 | chipset = i915_chipset_val(dev_priv); |
700 | gfx = i915_gfx_val(dev_priv); | 1115 | gfx = i915_gfx_val(dev_priv); |
1116 | mutex_unlock(&dev->struct_mutex); | ||
701 | 1117 | ||
702 | seq_printf(m, "GMCH temp: %ld\n", temp); | 1118 | seq_printf(m, "GMCH temp: %ld\n", temp); |
703 | seq_printf(m, "Chipset power: %ld\n", chipset); | 1119 | seq_printf(m, "Chipset power: %ld\n", chipset); |
@@ -718,6 +1134,108 @@ static int i915_gfxec(struct seq_file *m, void *unused) | |||
718 | return 0; | 1134 | return 0; |
719 | } | 1135 | } |
720 | 1136 | ||
1137 | static int i915_opregion(struct seq_file *m, void *unused) | ||
1138 | { | ||
1139 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1140 | struct drm_device *dev = node->minor->dev; | ||
1141 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1142 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
1143 | int ret; | ||
1144 | |||
1145 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1146 | if (ret) | ||
1147 | return ret; | ||
1148 | |||
1149 | if (opregion->header) | ||
1150 | seq_write(m, opregion->header, OPREGION_SIZE); | ||
1151 | |||
1152 | mutex_unlock(&dev->struct_mutex); | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | ||
1158 | { | ||
1159 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1160 | struct drm_device *dev = node->minor->dev; | ||
1161 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1162 | struct intel_fbdev *ifbdev; | ||
1163 | struct intel_framebuffer *fb; | ||
1164 | int ret; | ||
1165 | |||
1166 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
1167 | if (ret) | ||
1168 | return ret; | ||
1169 | |||
1170 | ifbdev = dev_priv->fbdev; | ||
1171 | fb = to_intel_framebuffer(ifbdev->helper.fb); | ||
1172 | |||
1173 | seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, obj ", | ||
1174 | fb->base.width, | ||
1175 | fb->base.height, | ||
1176 | fb->base.depth, | ||
1177 | fb->base.bits_per_pixel); | ||
1178 | describe_obj(m, fb->obj); | ||
1179 | seq_printf(m, "\n"); | ||
1180 | |||
1181 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { | ||
1182 | if (&fb->base == ifbdev->helper.fb) | ||
1183 | continue; | ||
1184 | |||
1185 | seq_printf(m, "user size: %d x %d, depth %d, %d bpp, obj ", | ||
1186 | fb->base.width, | ||
1187 | fb->base.height, | ||
1188 | fb->base.depth, | ||
1189 | fb->base.bits_per_pixel); | ||
1190 | describe_obj(m, fb->obj); | ||
1191 | seq_printf(m, "\n"); | ||
1192 | } | ||
1193 | |||
1194 | mutex_unlock(&dev->mode_config.mutex); | ||
1195 | |||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | static int i915_context_status(struct seq_file *m, void *unused) | ||
1200 | { | ||
1201 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1202 | struct drm_device *dev = node->minor->dev; | ||
1203 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1204 | int ret; | ||
1205 | |||
1206 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
1207 | if (ret) | ||
1208 | return ret; | ||
1209 | |||
1210 | if (dev_priv->pwrctx) { | ||
1211 | seq_printf(m, "power context "); | ||
1212 | describe_obj(m, dev_priv->pwrctx); | ||
1213 | seq_printf(m, "\n"); | ||
1214 | } | ||
1215 | |||
1216 | if (dev_priv->renderctx) { | ||
1217 | seq_printf(m, "render context "); | ||
1218 | describe_obj(m, dev_priv->renderctx); | ||
1219 | seq_printf(m, "\n"); | ||
1220 | } | ||
1221 | |||
1222 | mutex_unlock(&dev->mode_config.mutex); | ||
1223 | |||
1224 | return 0; | ||
1225 | } | ||
1226 | |||
1227 | static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) | ||
1228 | { | ||
1229 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1230 | struct drm_device *dev = node->minor->dev; | ||
1231 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1232 | |||
1233 | seq_printf(m, "forcewake count = %d\n", | ||
1234 | atomic_read(&dev_priv->forcewake_count)); | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
721 | static int | 1239 | static int |
722 | i915_wedged_open(struct inode *inode, | 1240 | i915_wedged_open(struct inode *inode, |
723 | struct file *filp) | 1241 | struct file *filp) |
@@ -741,6 +1259,9 @@ i915_wedged_read(struct file *filp, | |||
741 | "wedged : %d\n", | 1259 | "wedged : %d\n", |
742 | atomic_read(&dev_priv->mm.wedged)); | 1260 | atomic_read(&dev_priv->mm.wedged)); |
743 | 1261 | ||
1262 | if (len > sizeof (buf)) | ||
1263 | len = sizeof (buf); | ||
1264 | |||
744 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); | 1265 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); |
745 | } | 1266 | } |
746 | 1267 | ||
@@ -751,7 +1272,6 @@ i915_wedged_write(struct file *filp, | |||
751 | loff_t *ppos) | 1272 | loff_t *ppos) |
752 | { | 1273 | { |
753 | struct drm_device *dev = filp->private_data; | 1274 | struct drm_device *dev = filp->private_data; |
754 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
755 | char buf[20]; | 1275 | char buf[20]; |
756 | int val = 1; | 1276 | int val = 1; |
757 | 1277 | ||
@@ -767,12 +1287,7 @@ i915_wedged_write(struct file *filp, | |||
767 | } | 1287 | } |
768 | 1288 | ||
769 | DRM_INFO("Manually setting wedged to %d\n", val); | 1289 | DRM_INFO("Manually setting wedged to %d\n", val); |
770 | 1290 | i915_handle_error(dev, val); | |
771 | atomic_set(&dev_priv->mm.wedged, val); | ||
772 | if (val) { | ||
773 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
774 | queue_work(dev_priv->wq, &dev_priv->error_work); | ||
775 | } | ||
776 | 1291 | ||
777 | return cnt; | 1292 | return cnt; |
778 | } | 1293 | } |
@@ -782,6 +1297,7 @@ static const struct file_operations i915_wedged_fops = { | |||
782 | .open = i915_wedged_open, | 1297 | .open = i915_wedged_open, |
783 | .read = i915_wedged_read, | 1298 | .read = i915_wedged_read, |
784 | .write = i915_wedged_write, | 1299 | .write = i915_wedged_write, |
1300 | .llseek = default_llseek, | ||
785 | }; | 1301 | }; |
786 | 1302 | ||
787 | /* As the drm_debugfs_init() routines are called before dev->dev_private is | 1303 | /* As the drm_debugfs_init() routines are called before dev->dev_private is |
@@ -822,18 +1338,90 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | |||
822 | return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); | 1338 | return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); |
823 | } | 1339 | } |
824 | 1340 | ||
1341 | static int i915_forcewake_open(struct inode *inode, struct file *file) | ||
1342 | { | ||
1343 | struct drm_device *dev = inode->i_private; | ||
1344 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1345 | int ret; | ||
1346 | |||
1347 | if (!IS_GEN6(dev)) | ||
1348 | return 0; | ||
1349 | |||
1350 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1351 | if (ret) | ||
1352 | return ret; | ||
1353 | gen6_gt_force_wake_get(dev_priv); | ||
1354 | mutex_unlock(&dev->struct_mutex); | ||
1355 | |||
1356 | return 0; | ||
1357 | } | ||
1358 | |||
1359 | int i915_forcewake_release(struct inode *inode, struct file *file) | ||
1360 | { | ||
1361 | struct drm_device *dev = inode->i_private; | ||
1362 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1363 | |||
1364 | if (!IS_GEN6(dev)) | ||
1365 | return 0; | ||
1366 | |||
1367 | /* | ||
1368 | * It's bad that we can potentially hang userspace if struct_mutex gets | ||
1369 | * forever stuck. However, if we cannot acquire this lock it means that | ||
1370 | * almost certainly the driver has hung, is not unload-able. Therefore | ||
1371 | * hanging here is probably a minor inconvenience not to be seen my | ||
1372 | * almost every user. | ||
1373 | */ | ||
1374 | mutex_lock(&dev->struct_mutex); | ||
1375 | gen6_gt_force_wake_put(dev_priv); | ||
1376 | mutex_unlock(&dev->struct_mutex); | ||
1377 | |||
1378 | return 0; | ||
1379 | } | ||
1380 | |||
1381 | static const struct file_operations i915_forcewake_fops = { | ||
1382 | .owner = THIS_MODULE, | ||
1383 | .open = i915_forcewake_open, | ||
1384 | .release = i915_forcewake_release, | ||
1385 | }; | ||
1386 | |||
1387 | static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) | ||
1388 | { | ||
1389 | struct drm_device *dev = minor->dev; | ||
1390 | struct dentry *ent; | ||
1391 | |||
1392 | ent = debugfs_create_file("i915_forcewake_user", | ||
1393 | S_IRUSR, | ||
1394 | root, dev, | ||
1395 | &i915_forcewake_fops); | ||
1396 | if (IS_ERR(ent)) | ||
1397 | return PTR_ERR(ent); | ||
1398 | |||
1399 | return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); | ||
1400 | } | ||
1401 | |||
825 | static struct drm_info_list i915_debugfs_list[] = { | 1402 | static struct drm_info_list i915_debugfs_list[] = { |
1403 | {"i915_capabilities", i915_capabilities, 0}, | ||
1404 | {"i915_gem_objects", i915_gem_object_info, 0}, | ||
1405 | {"i915_gem_gtt", i915_gem_gtt_info, 0}, | ||
826 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 1406 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
827 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 1407 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
828 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 1408 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
1409 | {"i915_gem_pinned", i915_gem_object_list_info, 0, (void *) PINNED_LIST}, | ||
1410 | {"i915_gem_deferred_free", i915_gem_object_list_info, 0, (void *) DEFERRED_FREE_LIST}, | ||
829 | {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, | 1411 | {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, |
830 | {"i915_gem_request", i915_gem_request_info, 0}, | 1412 | {"i915_gem_request", i915_gem_request_info, 0}, |
831 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | 1413 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, |
832 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 1414 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
833 | {"i915_gem_interrupt", i915_interrupt_info, 0}, | 1415 | {"i915_gem_interrupt", i915_interrupt_info, 0}, |
834 | {"i915_gem_hws", i915_hws_info, 0}, | 1416 | {"i915_gem_hws", i915_hws_info, 0, (void *)RCS}, |
835 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 1417 | {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS}, |
836 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 1418 | {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, |
1419 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RCS}, | ||
1420 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RCS}, | ||
1421 | {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)VCS}, | ||
1422 | {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, | ||
1423 | {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, | ||
1424 | {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, | ||
837 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 1425 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
838 | {"i915_error_state", i915_error_state, 0}, | 1426 | {"i915_error_state", i915_error_state, 0}, |
839 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, | 1427 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, |
@@ -845,6 +1433,10 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
845 | {"i915_gfxec", i915_gfxec, 0}, | 1433 | {"i915_gfxec", i915_gfxec, 0}, |
846 | {"i915_fbc_status", i915_fbc_status, 0}, | 1434 | {"i915_fbc_status", i915_fbc_status, 0}, |
847 | {"i915_sr_status", i915_sr_status, 0}, | 1435 | {"i915_sr_status", i915_sr_status, 0}, |
1436 | {"i915_opregion", i915_opregion, 0}, | ||
1437 | {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, | ||
1438 | {"i915_context_status", i915_context_status, 0}, | ||
1439 | {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, | ||
848 | }; | 1440 | }; |
849 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) | 1441 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
850 | 1442 | ||
@@ -856,6 +1448,10 @@ int i915_debugfs_init(struct drm_minor *minor) | |||
856 | if (ret) | 1448 | if (ret) |
857 | return ret; | 1449 | return ret; |
858 | 1450 | ||
1451 | ret = i915_forcewake_create(minor->debugfs_root, minor); | ||
1452 | if (ret) | ||
1453 | return ret; | ||
1454 | |||
859 | return drm_debugfs_create_files(i915_debugfs_list, | 1455 | return drm_debugfs_create_files(i915_debugfs_list, |
860 | I915_DEBUGFS_ENTRIES, | 1456 | I915_DEBUGFS_ENTRIES, |
861 | minor->debugfs_root, minor); | 1457 | minor->debugfs_root, minor); |
@@ -865,6 +1461,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) | |||
865 | { | 1461 | { |
866 | drm_debugfs_remove_files(i915_debugfs_list, | 1462 | drm_debugfs_remove_files(i915_debugfs_list, |
867 | I915_DEBUGFS_ENTRIES, minor); | 1463 | I915_DEBUGFS_ENTRIES, minor); |
1464 | drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, | ||
1465 | 1, minor); | ||
868 | drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, | 1466 | drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, |
869 | 1, minor); | 1467 | 1, minor); |
870 | } | 1468 | } |