@@ -844,6 +844,56 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
844
844
cpt_serr_int_handler (dev_priv );
845
845
}
846
846
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
+
847
897
void ilk_display_irq_handler (struct drm_i915_private * dev_priv , u32 de_iir )
848
898
{
849
899
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)
862
912
if (de_iir & DE_POISON )
863
913
drm_err (& dev_priv -> drm , "Poison interrupt\n" );
864
914
915
+ if (de_iir & DE_GTT_FAULT )
916
+ ilk_gtt_fault_irq_handler (display );
917
+
865
918
for_each_pipe (dev_priv , pipe ) {
866
919
if (de_iir & DE_PIPE_VBLANK (pipe ))
867
920
intel_handle_vblank (dev_priv , pipe );
@@ -1988,7 +2041,8 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
1988
2041
DE_PLANE_FLIP_DONE_IVB (PLANE_A ) |
1989
2042
DE_DP_A_HOTPLUG_IVB );
1990
2043
} 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 |
1992
2046
DE_AUX_CHANNEL_A | DE_PIPEB_CRC_DONE |
1993
2047
DE_PIPEA_CRC_DONE | DE_POISON );
1994
2048
extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK |
0 commit comments