diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gpu_error.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gpu_error.c | 122 |
1 files changed, 97 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 66cf41765bf9..eab41f9390f8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -229,6 +229,8 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a) | |||
229 | return "wait"; | 229 | return "wait"; |
230 | case HANGCHECK_ACTIVE: | 230 | case HANGCHECK_ACTIVE: |
231 | return "active"; | 231 | return "active"; |
232 | case HANGCHECK_ACTIVE_LOOP: | ||
233 | return "active (loop)"; | ||
232 | case HANGCHECK_KICK: | 234 | case HANGCHECK_KICK: |
233 | return "kick"; | 235 | return "kick"; |
234 | case HANGCHECK_HUNG: | 236 | case HANGCHECK_HUNG: |
@@ -327,6 +329,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
327 | struct drm_device *dev = error_priv->dev; | 329 | struct drm_device *dev = error_priv->dev; |
328 | struct drm_i915_private *dev_priv = dev->dev_private; | 330 | struct drm_i915_private *dev_priv = dev->dev_private; |
329 | struct drm_i915_error_state *error = error_priv->error; | 331 | struct drm_i915_error_state *error = error_priv->error; |
332 | struct drm_i915_error_object *obj; | ||
330 | int i, j, offset, elt; | 333 | int i, j, offset, elt; |
331 | int max_hangcheck_score; | 334 | int max_hangcheck_score; |
332 | 335 | ||
@@ -358,6 +361,12 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
358 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); | 361 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
359 | err_printf(m, "EIR: 0x%08x\n", error->eir); | 362 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
360 | err_printf(m, "IER: 0x%08x\n", error->ier); | 363 | err_printf(m, "IER: 0x%08x\n", error->ier); |
364 | if (INTEL_INFO(dev)->gen >= 8) { | ||
365 | for (i = 0; i < 4; i++) | ||
366 | err_printf(m, "GTIER gt %d: 0x%08x\n", i, | ||
367 | error->gtier[i]); | ||
368 | } else if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev)) | ||
369 | err_printf(m, "GTIER: 0x%08x\n", error->gtier[0]); | ||
361 | err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 370 | err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
362 | err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); | 371 | err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); |
363 | err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); | 372 | err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); |
@@ -395,8 +404,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
395 | error->pinned_bo_count[0]); | 404 | error->pinned_bo_count[0]); |
396 | 405 | ||
397 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { | 406 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
398 | struct drm_i915_error_object *obj; | ||
399 | |||
400 | obj = error->ring[i].batchbuffer; | 407 | obj = error->ring[i].batchbuffer; |
401 | if (obj) { | 408 | if (obj) { |
402 | err_puts(m, dev_priv->ring[i].name); | 409 | err_puts(m, dev_priv->ring[i].name); |
@@ -459,6 +466,18 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
459 | } | 466 | } |
460 | } | 467 | } |
461 | 468 | ||
469 | if ((obj = error->semaphore_obj)) { | ||
470 | err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset); | ||
471 | for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { | ||
472 | err_printf(m, "[%04x] %08x %08x %08x %08x\n", | ||
473 | elt * 4, | ||
474 | obj->pages[0][elt], | ||
475 | obj->pages[0][elt+1], | ||
476 | obj->pages[0][elt+2], | ||
477 | obj->pages[0][elt+3]); | ||
478 | } | ||
479 | } | ||
480 | |||
462 | if (error->overlay) | 481 | if (error->overlay) |
463 | intel_overlay_print_error_state(m, error->overlay); | 482 | intel_overlay_print_error_state(m, error->overlay); |
464 | 483 | ||
@@ -529,6 +548,7 @@ static void i915_error_state_free(struct kref *error_ref) | |||
529 | kfree(error->ring[i].requests); | 548 | kfree(error->ring[i].requests); |
530 | } | 549 | } |
531 | 550 | ||
551 | i915_error_object_free(error->semaphore_obj); | ||
532 | kfree(error->active_bo); | 552 | kfree(error->active_bo); |
533 | kfree(error->overlay); | 553 | kfree(error->overlay); |
534 | kfree(error->display); | 554 | kfree(error->display); |
@@ -746,7 +766,60 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
746 | } | 766 | } |
747 | } | 767 | } |
748 | 768 | ||
769 | |||
770 | static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, | ||
771 | struct drm_i915_error_state *error, | ||
772 | struct intel_engine_cs *ring, | ||
773 | struct drm_i915_error_ring *ering) | ||
774 | { | ||
775 | struct intel_engine_cs *to; | ||
776 | int i; | ||
777 | |||
778 | if (!i915_semaphore_is_enabled(dev_priv->dev)) | ||
779 | return; | ||
780 | |||
781 | if (!error->semaphore_obj) | ||
782 | error->semaphore_obj = | ||
783 | i915_error_object_create(dev_priv, | ||
784 | dev_priv->semaphore_obj, | ||
785 | &dev_priv->gtt.base); | ||
786 | |||
787 | for_each_ring(to, dev_priv, i) { | ||
788 | int idx; | ||
789 | u16 signal_offset; | ||
790 | u32 *tmp; | ||
791 | |||
792 | if (ring == to) | ||
793 | continue; | ||
794 | |||
795 | signal_offset = (GEN8_SIGNAL_OFFSET(ring, i) & (PAGE_SIZE - 1)) | ||
796 | / 4; | ||
797 | tmp = error->semaphore_obj->pages[0]; | ||
798 | idx = intel_ring_sync_index(ring, to); | ||
799 | |||
800 | ering->semaphore_mboxes[idx] = tmp[signal_offset]; | ||
801 | ering->semaphore_seqno[idx] = ring->semaphore.sync_seqno[idx]; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, | ||
806 | struct intel_engine_cs *ring, | ||
807 | struct drm_i915_error_ring *ering) | ||
808 | { | ||
809 | ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(ring->mmio_base)); | ||
810 | ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring->mmio_base)); | ||
811 | ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0]; | ||
812 | ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1]; | ||
813 | |||
814 | if (HAS_VEBOX(dev_priv->dev)) { | ||
815 | ering->semaphore_mboxes[2] = | ||
816 | I915_READ(RING_SYNC_2(ring->mmio_base)); | ||
817 | ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2]; | ||
818 | } | ||
819 | } | ||
820 | |||
749 | static void i915_record_ring_state(struct drm_device *dev, | 821 | static void i915_record_ring_state(struct drm_device *dev, |
822 | struct drm_i915_error_state *error, | ||
750 | struct intel_engine_cs *ring, | 823 | struct intel_engine_cs *ring, |
751 | struct drm_i915_error_ring *ering) | 824 | struct drm_i915_error_ring *ering) |
752 | { | 825 | { |
@@ -755,18 +828,10 @@ static void i915_record_ring_state(struct drm_device *dev, | |||
755 | if (INTEL_INFO(dev)->gen >= 6) { | 828 | if (INTEL_INFO(dev)->gen >= 6) { |
756 | ering->rc_psmi = I915_READ(ring->mmio_base + 0x50); | 829 | ering->rc_psmi = I915_READ(ring->mmio_base + 0x50); |
757 | ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); | 830 | ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); |
758 | ering->semaphore_mboxes[0] | 831 | if (INTEL_INFO(dev)->gen >= 8) |
759 | = I915_READ(RING_SYNC_0(ring->mmio_base)); | 832 | gen8_record_semaphore_state(dev_priv, error, ring, ering); |
760 | ering->semaphore_mboxes[1] | 833 | else |
761 | = I915_READ(RING_SYNC_1(ring->mmio_base)); | 834 | gen6_record_semaphore_state(dev_priv, ring, ering); |
762 | ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0]; | ||
763 | ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1]; | ||
764 | } | ||
765 | |||
766 | if (HAS_VEBOX(dev)) { | ||
767 | ering->semaphore_mboxes[2] = | ||
768 | I915_READ(RING_SYNC_2(ring->mmio_base)); | ||
769 | ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2]; | ||
770 | } | 835 | } |
771 | 836 | ||
772 | if (INTEL_INFO(dev)->gen >= 4) { | 837 | if (INTEL_INFO(dev)->gen >= 4) { |
@@ -871,6 +936,9 @@ static void i915_gem_record_active_context(struct intel_engine_cs *ring, | |||
871 | return; | 936 | return; |
872 | 937 | ||
873 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 938 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
939 | if (!i915_gem_obj_ggtt_bound(obj)) | ||
940 | continue; | ||
941 | |||
874 | if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { | 942 | if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { |
875 | ering->ctx = i915_error_ggtt_object_create(dev_priv, obj); | 943 | ering->ctx = i915_error_ggtt_object_create(dev_priv, obj); |
876 | break; | 944 | break; |
@@ -895,7 +963,7 @@ static void i915_gem_record_rings(struct drm_device *dev, | |||
895 | 963 | ||
896 | error->ring[i].valid = true; | 964 | error->ring[i].valid = true; |
897 | 965 | ||
898 | i915_record_ring_state(dev, ring, &error->ring[i]); | 966 | i915_record_ring_state(dev, error, ring, &error->ring[i]); |
899 | 967 | ||
900 | request = i915_gem_find_active_request(ring); | 968 | request = i915_gem_find_active_request(ring); |
901 | if (request) { | 969 | if (request) { |
@@ -1032,6 +1100,7 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | |||
1032 | struct drm_i915_error_state *error) | 1100 | struct drm_i915_error_state *error) |
1033 | { | 1101 | { |
1034 | struct drm_device *dev = dev_priv->dev; | 1102 | struct drm_device *dev = dev_priv->dev; |
1103 | int i; | ||
1035 | 1104 | ||
1036 | /* General organization | 1105 | /* General organization |
1037 | * 1. Registers specific to a single generation | 1106 | * 1. Registers specific to a single generation |
@@ -1043,7 +1112,8 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | |||
1043 | 1112 | ||
1044 | /* 1: Registers specific to a single generation */ | 1113 | /* 1: Registers specific to a single generation */ |
1045 | if (IS_VALLEYVIEW(dev)) { | 1114 | if (IS_VALLEYVIEW(dev)) { |
1046 | error->ier = I915_READ(GTIER) | I915_READ(VLV_IER); | 1115 | error->gtier[0] = I915_READ(GTIER); |
1116 | error->ier = I915_READ(VLV_IER); | ||
1047 | error->forcewake = I915_READ(FORCEWAKE_VLV); | 1117 | error->forcewake = I915_READ(FORCEWAKE_VLV); |
1048 | } | 1118 | } |
1049 | 1119 | ||
@@ -1076,16 +1146,18 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | |||
1076 | if (HAS_HW_CONTEXTS(dev)) | 1146 | if (HAS_HW_CONTEXTS(dev)) |
1077 | error->ccid = I915_READ(CCID); | 1147 | error->ccid = I915_READ(CCID); |
1078 | 1148 | ||
1079 | if (HAS_PCH_SPLIT(dev)) | 1149 | if (INTEL_INFO(dev)->gen >= 8) { |
1080 | error->ier = I915_READ(DEIER) | I915_READ(GTIER); | 1150 | error->ier = I915_READ(GEN8_DE_MISC_IER); |
1081 | else { | 1151 | for (i = 0; i < 4; i++) |
1082 | if (IS_GEN2(dev)) | 1152 | error->gtier[i] = I915_READ(GEN8_GT_IER(i)); |
1083 | error->ier = I915_READ16(IER); | 1153 | } else if (HAS_PCH_SPLIT(dev)) { |
1084 | else | 1154 | error->ier = I915_READ(DEIER); |
1085 | error->ier = I915_READ(IER); | 1155 | error->gtier[0] = I915_READ(GTIER); |
1156 | } else if (IS_GEN2(dev)) { | ||
1157 | error->ier = I915_READ16(IER); | ||
1158 | } else if (!IS_VALLEYVIEW(dev)) { | ||
1159 | error->ier = I915_READ(IER); | ||
1086 | } | 1160 | } |
1087 | |||
1088 | /* 4: Everything else */ | ||
1089 | error->eir = I915_READ(EIR); | 1161 | error->eir = I915_READ(EIR); |
1090 | error->pgtbl_er = I915_READ(PGTBL_ER); | 1162 | error->pgtbl_er = I915_READ(PGTBL_ER); |
1091 | 1163 | ||