@@ -844,6 +844,56 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
844844 cpt_serr_int_handler (dev_priv );
845845}
846846
847+ static u32 ilk_gtt_fault_pipe_fault_mask (enum pipe pipe )
848+ {
849+ switch (pipe ) {
850+ case PIPE_A :
851+ return GTT_FAULT_SPRITE_A_FAULT |
852+ GTT_FAULT_PRIMARY_A_FAULT |
853+ GTT_FAULT_CURSOR_A_FAULT ;
854+ case PIPE_B :
855+ return GTT_FAULT_SPRITE_B_FAULT |
856+ GTT_FAULT_PRIMARY_B_FAULT |
857+ GTT_FAULT_CURSOR_B_FAULT ;
858+ default :
859+ return 0 ;
860+ }
861+ }
862+
863+ static const struct pipe_fault_handler ilk_pipe_fault_handlers [] = {
864+ { .fault = GTT_FAULT_SPRITE_A_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_SPRITE0 , },
865+ { .fault = GTT_FAULT_SPRITE_B_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_SPRITE0 , },
866+ { .fault = GTT_FAULT_PRIMARY_A_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_PRIMARY , },
867+ { .fault = GTT_FAULT_PRIMARY_B_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_PRIMARY , },
868+ { .fault = GTT_FAULT_CURSOR_A_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_CURSOR , },
869+ { .fault = GTT_FAULT_CURSOR_B_FAULT , .handle = handle_plane_fault , .plane_id = PLANE_CURSOR , },
870+ {}
871+ };
872+
873+ static void ilk_gtt_fault_irq_handler (struct intel_display * display )
874+ {
875+ enum pipe pipe ;
876+ u32 gtt_fault ;
877+
878+ gtt_fault = intel_de_read (display , ILK_GTT_FAULT );
879+ intel_de_write (display , ILK_GTT_FAULT , gtt_fault );
880+
881+ if (gtt_fault & GTT_FAULT_INVALID_GTT_PTE )
882+ drm_err_ratelimited (display -> drm , "Invalid GTT PTE\n" );
883+
884+ if (gtt_fault & GTT_FAULT_INVALID_PTE_DATA )
885+ drm_err_ratelimited (display -> drm , "Invalid PTE data\n" );
886+
887+ for_each_pipe (display , pipe ) {
888+ u32 fault_errors ;
889+
890+ fault_errors = gtt_fault & ilk_gtt_fault_pipe_fault_mask (pipe );
891+ if (fault_errors )
892+ intel_pipe_fault_irq_handler (display , ilk_pipe_fault_handlers ,
893+ pipe , fault_errors );
894+ }
895+ }
896+
847897void ilk_display_irq_handler (struct drm_i915_private * dev_priv , u32 de_iir )
848898{
849899 struct intel_display * display = & dev_priv -> display ;
@@ -862,6 +912,9 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir)
862912 if (de_iir & DE_POISON )
863913 drm_err (& dev_priv -> drm , "Poison interrupt\n" );
864914
915+ if (de_iir & DE_GTT_FAULT )
916+ ilk_gtt_fault_irq_handler (display );
917+
865918 for_each_pipe (dev_priv , pipe ) {
866919 if (de_iir & DE_PIPE_VBLANK (pipe ))
867920 intel_handle_vblank (dev_priv , pipe );
@@ -1988,7 +2041,8 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
19882041 DE_PLANE_FLIP_DONE_IVB (PLANE_A ) |
19892042 DE_DP_A_HOTPLUG_IVB );
19902043 } else {
1991- display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
2044+ display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE |
2045+ DE_PCH_EVENT | DE_GTT_FAULT |
19922046 DE_AUX_CHANNEL_A | DE_PIPEB_CRC_DONE |
19932047 DE_PIPEA_CRC_DONE | DE_POISON );
19942048 extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK |
0 commit comments