aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c246
1 files changed, 239 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b86b7b7130c..7ebc84c2881 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -26,6 +26,7 @@
26 * 26 *
27 */ 27 */
28 28
29#include <linux/sysrq.h>
29#include "drmP.h" 30#include "drmP.h"
30#include "drm.h" 31#include "drm.h"
31#include "i915_drm.h" 32#include "i915_drm.h"
@@ -41,9 +42,10 @@
41 * we leave them always unmasked in IMR and then control enabling them through 42 * we leave them always unmasked in IMR and then control enabling them through
42 * PIPESTAT alone. 43 * PIPESTAT alone.
43 */ 44 */
44#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ 45#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
45 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ 46 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
46 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 47 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
48 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
47 49
48/** Interrupts that we mask and unmask at runtime. */ 50/** Interrupts that we mask and unmask at runtime. */
49#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) 51#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
@@ -188,7 +190,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
188 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; 190 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
189 191
190 if (!i915_pipe_enabled(dev, pipe)) { 192 if (!i915_pipe_enabled(dev, pipe)) {
191 DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); 193 DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
192 return 0; 194 return 0;
193 } 195 }
194 196
@@ -217,7 +219,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
217 int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; 219 int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
218 220
219 if (!i915_pipe_enabled(dev, pipe)) { 221 if (!i915_pipe_enabled(dev, pipe)) {
220 DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); 222 DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
221 return 0; 223 return 0;
222 } 224 }
223 225
@@ -232,7 +234,17 @@ static void i915_hotplug_work_func(struct work_struct *work)
232 drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, 234 drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
233 hotplug_work); 235 hotplug_work);
234 struct drm_device *dev = dev_priv->dev; 236 struct drm_device *dev = dev_priv->dev;
235 237 struct drm_mode_config *mode_config = &dev->mode_config;
238 struct drm_connector *connector;
239
240 if (mode_config->num_connector) {
241 list_for_each_entry(connector, &mode_config->connector_list, head) {
242 struct intel_output *intel_output = to_intel_output(connector);
243
244 if (intel_output->hot_plug)
245 (*intel_output->hot_plug) (intel_output);
246 }
247 }
236 /* Just fire off a uevent and let userspace tell us what to do */ 248 /* Just fire off a uevent and let userspace tell us what to do */
237 drm_sysfs_hotplug_event(dev); 249 drm_sysfs_hotplug_event(dev);
238} 250}
@@ -278,6 +290,201 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
278 return ret; 290 return ret;
279} 291}
280 292
293/**
294 * i915_error_work_func - do process context error handling work
295 * @work: work struct
296 *
297 * Fire an error uevent so userspace can see that a hang or error
298 * was detected.
299 */
300static void i915_error_work_func(struct work_struct *work)
301{
302 drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
303 error_work);
304 struct drm_device *dev = dev_priv->dev;
305 char *event_string = "ERROR=1";
306 char *envp[] = { event_string, NULL };
307
308 DRM_DEBUG("generating error event\n");
309
310 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
311}
312
313/**
314 * i915_capture_error_state - capture an error record for later analysis
315 * @dev: drm device
316 *
317 * Should be called when an error is detected (either a hang or an error
318 * interrupt) to capture error state from the time of the error. Fills
319 * out a structure which becomes available in debugfs for user level tools
320 * to pick up.
321 */
322static void i915_capture_error_state(struct drm_device *dev)
323{
324 struct drm_i915_private *dev_priv = dev->dev_private;
325 struct drm_i915_error_state *error;
326 unsigned long flags;
327
328 spin_lock_irqsave(&dev_priv->error_lock, flags);
329 if (dev_priv->first_error)
330 goto out;
331
332 error = kmalloc(sizeof(*error), GFP_ATOMIC);
333 if (!error) {
334 DRM_DEBUG("out ot memory, not capturing error state\n");
335 goto out;
336 }
337
338 error->eir = I915_READ(EIR);
339 error->pgtbl_er = I915_READ(PGTBL_ER);
340 error->pipeastat = I915_READ(PIPEASTAT);
341 error->pipebstat = I915_READ(PIPEBSTAT);
342 error->instpm = I915_READ(INSTPM);
343 if (!IS_I965G(dev)) {
344 error->ipeir = I915_READ(IPEIR);
345 error->ipehr = I915_READ(IPEHR);
346 error->instdone = I915_READ(INSTDONE);
347 error->acthd = I915_READ(ACTHD);
348 } else {
349 error->ipeir = I915_READ(IPEIR_I965);
350 error->ipehr = I915_READ(IPEHR_I965);
351 error->instdone = I915_READ(INSTDONE_I965);
352 error->instps = I915_READ(INSTPS);
353 error->instdone1 = I915_READ(INSTDONE1);
354 error->acthd = I915_READ(ACTHD_I965);
355 }
356
357 do_gettimeofday(&error->time);
358
359 dev_priv->first_error = error;
360
361out:
362 spin_unlock_irqrestore(&dev_priv->error_lock, flags);
363}
364
365/**
366 * i915_handle_error - handle an error interrupt
367 * @dev: drm device
368 *
369 * Do some basic checking of regsiter state at error interrupt time and
370 * dump it to the syslog. Also call i915_capture_error_state() to make
371 * sure we get a record and make it available in debugfs. Fire a uevent
372 * so userspace knows something bad happened (should trigger collection
373 * of a ring dump etc.).
374 */
375static void i915_handle_error(struct drm_device *dev)
376{
377 struct drm_i915_private *dev_priv = dev->dev_private;
378 u32 eir = I915_READ(EIR);
379 u32 pipea_stats = I915_READ(PIPEASTAT);
380 u32 pipeb_stats = I915_READ(PIPEBSTAT);
381
382 i915_capture_error_state(dev);
383
384 printk(KERN_ERR "render error detected, EIR: 0x%08x\n",
385 eir);
386
387 if (IS_G4X(dev)) {
388 if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
389 u32 ipeir = I915_READ(IPEIR_I965);
390
391 printk(KERN_ERR " IPEIR: 0x%08x\n",
392 I915_READ(IPEIR_I965));
393 printk(KERN_ERR " IPEHR: 0x%08x\n",
394 I915_READ(IPEHR_I965));
395 printk(KERN_ERR " INSTDONE: 0x%08x\n",
396 I915_READ(INSTDONE_I965));
397 printk(KERN_ERR " INSTPS: 0x%08x\n",
398 I915_READ(INSTPS));
399 printk(KERN_ERR " INSTDONE1: 0x%08x\n",
400 I915_READ(INSTDONE1));
401 printk(KERN_ERR " ACTHD: 0x%08x\n",
402 I915_READ(ACTHD_I965));
403 I915_WRITE(IPEIR_I965, ipeir);
404 (void)I915_READ(IPEIR_I965);
405 }
406 if (eir & GM45_ERROR_PAGE_TABLE) {
407 u32 pgtbl_err = I915_READ(PGTBL_ER);
408 printk(KERN_ERR "page table error\n");
409 printk(KERN_ERR " PGTBL_ER: 0x%08x\n",
410 pgtbl_err);
411 I915_WRITE(PGTBL_ER, pgtbl_err);
412 (void)I915_READ(PGTBL_ER);
413 }
414 }
415
416 if (IS_I9XX(dev)) {
417 if (eir & I915_ERROR_PAGE_TABLE) {
418 u32 pgtbl_err = I915_READ(PGTBL_ER);
419 printk(KERN_ERR "page table error\n");
420 printk(KERN_ERR " PGTBL_ER: 0x%08x\n",
421 pgtbl_err);
422 I915_WRITE(PGTBL_ER, pgtbl_err);
423 (void)I915_READ(PGTBL_ER);
424 }
425 }
426
427 if (eir & I915_ERROR_MEMORY_REFRESH) {
428 printk(KERN_ERR "memory refresh error\n");
429 printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
430 pipea_stats);
431 printk(KERN_ERR "PIPEBSTAT: 0x%08x\n",
432 pipeb_stats);
433 /* pipestat has already been acked */
434 }
435 if (eir & I915_ERROR_INSTRUCTION) {
436 printk(KERN_ERR "instruction error\n");
437 printk(KERN_ERR " INSTPM: 0x%08x\n",
438 I915_READ(INSTPM));
439 if (!IS_I965G(dev)) {
440 u32 ipeir = I915_READ(IPEIR);
441
442 printk(KERN_ERR " IPEIR: 0x%08x\n",
443 I915_READ(IPEIR));
444 printk(KERN_ERR " IPEHR: 0x%08x\n",
445 I915_READ(IPEHR));
446 printk(KERN_ERR " INSTDONE: 0x%08x\n",
447 I915_READ(INSTDONE));
448 printk(KERN_ERR " ACTHD: 0x%08x\n",
449 I915_READ(ACTHD));
450 I915_WRITE(IPEIR, ipeir);
451 (void)I915_READ(IPEIR);
452 } else {
453 u32 ipeir = I915_READ(IPEIR_I965);
454
455 printk(KERN_ERR " IPEIR: 0x%08x\n",
456 I915_READ(IPEIR_I965));
457 printk(KERN_ERR " IPEHR: 0x%08x\n",
458 I915_READ(IPEHR_I965));
459 printk(KERN_ERR " INSTDONE: 0x%08x\n",
460 I915_READ(INSTDONE_I965));
461 printk(KERN_ERR " INSTPS: 0x%08x\n",
462 I915_READ(INSTPS));
463 printk(KERN_ERR " INSTDONE1: 0x%08x\n",
464 I915_READ(INSTDONE1));
465 printk(KERN_ERR " ACTHD: 0x%08x\n",
466 I915_READ(ACTHD_I965));
467 I915_WRITE(IPEIR_I965, ipeir);
468 (void)I915_READ(IPEIR_I965);
469 }
470 }
471
472 I915_WRITE(EIR, eir);
473 (void)I915_READ(EIR);
474 eir = I915_READ(EIR);
475 if (eir) {
476 /*
477 * some errors might have become stuck,
478 * mask them.
479 */
480 DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir);
481 I915_WRITE(EMR, I915_READ(EMR) | eir);
482 I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
483 }
484
485 queue_work(dev_priv->wq, &dev_priv->error_work);
486}
487
281irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 488irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
282{ 489{
283 struct drm_device *dev = (struct drm_device *) arg; 490 struct drm_device *dev = (struct drm_device *) arg;
@@ -319,15 +526,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
319 pipea_stats = I915_READ(PIPEASTAT); 526 pipea_stats = I915_READ(PIPEASTAT);
320 pipeb_stats = I915_READ(PIPEBSTAT); 527 pipeb_stats = I915_READ(PIPEBSTAT);
321 528
529 if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
530 i915_handle_error(dev);
531
322 /* 532 /*
323 * Clear the PIPE(A|B)STAT regs before the IIR 533 * Clear the PIPE(A|B)STAT regs before the IIR
324 */ 534 */
325 if (pipea_stats & 0x8000ffff) { 535 if (pipea_stats & 0x8000ffff) {
536 if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS)
537 DRM_DEBUG("pipe a underrun\n");
326 I915_WRITE(PIPEASTAT, pipea_stats); 538 I915_WRITE(PIPEASTAT, pipea_stats);
327 irq_received = 1; 539 irq_received = 1;
328 } 540 }
329 541
330 if (pipeb_stats & 0x8000ffff) { 542 if (pipeb_stats & 0x8000ffff) {
543 if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS)
544 DRM_DEBUG("pipe b underrun\n");
331 I915_WRITE(PIPEBSTAT, pipeb_stats); 545 I915_WRITE(PIPEBSTAT, pipeb_stats);
332 irq_received = 1; 546 irq_received = 1;
333 } 547 }
@@ -346,7 +560,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
346 DRM_DEBUG("hotplug event received, stat 0x%08x\n", 560 DRM_DEBUG("hotplug event received, stat 0x%08x\n",
347 hotplug_status); 561 hotplug_status);
348 if (hotplug_status & dev_priv->hotplug_supported_mask) 562 if (hotplug_status & dev_priv->hotplug_supported_mask)
349 schedule_work(&dev_priv->hotplug_work); 563 queue_work(dev_priv->wq,
564 &dev_priv->hotplug_work);
350 565
351 I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); 566 I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
352 I915_READ(PORT_HOTPLUG_STAT); 567 I915_READ(PORT_HOTPLUG_STAT);
@@ -699,6 +914,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
699 atomic_set(&dev_priv->irq_received, 0); 914 atomic_set(&dev_priv->irq_received, 0);
700 915
701 INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); 916 INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
917 INIT_WORK(&dev_priv->error_work, i915_error_work_func);
702 918
703 if (IS_IGDNG(dev)) { 919 if (IS_IGDNG(dev)) {
704 igdng_irq_preinstall(dev); 920 igdng_irq_preinstall(dev);
@@ -722,6 +938,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
722{ 938{
723 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 939 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
724 u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; 940 u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
941 u32 error_mask;
725 942
726 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 943 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
727 944
@@ -758,6 +975,21 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
758 i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); 975 i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
759 } 976 }
760 977
978 /*
979 * Enable some error detection, note the instruction error mask
980 * bit is reserved, so we leave it masked.
981 */
982 if (IS_G4X(dev)) {
983 error_mask = ~(GM45_ERROR_PAGE_TABLE |
984 GM45_ERROR_MEM_PRIV |
985 GM45_ERROR_CP_PRIV |
986 I915_ERROR_MEMORY_REFRESH);
987 } else {
988 error_mask = ~(I915_ERROR_PAGE_TABLE |
989 I915_ERROR_MEMORY_REFRESH);
990 }
991 I915_WRITE(EMR, error_mask);
992
761 /* Disable pipe interrupt enables, clear pending pipe status */ 993 /* Disable pipe interrupt enables, clear pending pipe status */
762 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); 994 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
763 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); 995 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);