@@ -569,7 +569,8 @@ static void hsw_pipe_A_crc_wa(struct drm_i915_private *dev_priv,
569
569
static int ivb_pipe_crc_ctl_reg (struct drm_i915_private * dev_priv ,
570
570
enum pipe pipe ,
571
571
enum intel_pipe_crc_source * source ,
572
- uint32_t * val )
572
+ uint32_t * val ,
573
+ bool set_wa )
573
574
{
574
575
if (* source == INTEL_PIPE_CRC_SOURCE_AUTO )
575
576
* source = INTEL_PIPE_CRC_SOURCE_PF ;
@@ -582,7 +583,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
582
583
* val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB ;
583
584
break ;
584
585
case INTEL_PIPE_CRC_SOURCE_PF :
585
- if ((IS_HASWELL (dev_priv ) ||
586
+ if (set_wa && (IS_HASWELL (dev_priv ) ||
586
587
IS_BROADWELL (dev_priv )) && pipe == PIPE_A )
587
588
hsw_pipe_A_crc_wa (dev_priv , true);
588
589
@@ -600,7 +601,8 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
600
601
601
602
static int get_new_crc_ctl_reg (struct drm_i915_private * dev_priv ,
602
603
enum pipe pipe ,
603
- enum intel_pipe_crc_source * source , u32 * val )
604
+ enum intel_pipe_crc_source * source , u32 * val ,
605
+ bool set_wa )
604
606
{
605
607
if (IS_GEN2 (dev_priv ))
606
608
return i8xx_pipe_crc_ctl_reg (source , val );
@@ -611,7 +613,7 @@ static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
611
613
else if (IS_GEN5 (dev_priv ) || IS_GEN6 (dev_priv ))
612
614
return ilk_pipe_crc_ctl_reg (source , val );
613
615
else
614
- return ivb_pipe_crc_ctl_reg (dev_priv , pipe , source , val );
616
+ return ivb_pipe_crc_ctl_reg (dev_priv , pipe , source , val , set_wa );
615
617
}
616
618
617
619
static int pipe_crc_set_source (struct drm_i915_private * dev_priv ,
@@ -636,7 +638,7 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv,
636
638
return - EIO ;
637
639
}
638
640
639
- ret = get_new_crc_ctl_reg (dev_priv , pipe , & source , & val );
641
+ ret = get_new_crc_ctl_reg (dev_priv , pipe , & source , & val , true );
640
642
if (ret != 0 )
641
643
goto out ;
642
644
@@ -916,7 +918,7 @@ int intel_pipe_crc_create(struct drm_minor *minor)
916
918
int intel_crtc_set_crc_source (struct drm_crtc * crtc , const char * source_name ,
917
919
size_t * values_cnt )
918
920
{
919
- struct drm_i915_private * dev_priv = crtc -> dev -> dev_private ;
921
+ struct drm_i915_private * dev_priv = to_i915 ( crtc -> dev ) ;
920
922
struct intel_pipe_crc * pipe_crc = & dev_priv -> pipe_crc [crtc -> index ];
921
923
enum intel_display_power_domain power_domain ;
922
924
enum intel_pipe_crc_source source ;
@@ -934,10 +936,11 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
934
936
return - EIO ;
935
937
}
936
938
937
- ret = get_new_crc_ctl_reg (dev_priv , crtc -> index , & source , & val );
939
+ ret = get_new_crc_ctl_reg (dev_priv , crtc -> index , & source , & val , true );
938
940
if (ret != 0 )
939
941
goto out ;
940
942
943
+ pipe_crc -> source = source ;
941
944
I915_WRITE (PIPE_CRC_CTL (crtc -> index ), val );
942
945
POSTING_READ (PIPE_CRC_CTL (crtc -> index ));
943
946
@@ -959,3 +962,39 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
959
962
960
963
return ret ;
961
964
}
965
+
966
+ void intel_crtc_enable_pipe_crc (struct intel_crtc * intel_crtc )
967
+ {
968
+ struct drm_crtc * crtc = & intel_crtc -> base ;
969
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> dev );
970
+ struct intel_pipe_crc * pipe_crc = & dev_priv -> pipe_crc [crtc -> index ];
971
+ u32 val = 0 ;
972
+
973
+ if (!crtc -> crc .opened )
974
+ return ;
975
+
976
+ if (get_new_crc_ctl_reg (dev_priv , crtc -> index , & pipe_crc -> source , & val , false) < 0 )
977
+ return ;
978
+
979
+ /* Don't need pipe_crc->lock here, IRQs are not generated. */
980
+ pipe_crc -> skipped = 0 ;
981
+
982
+ I915_WRITE (PIPE_CRC_CTL (crtc -> index ), val );
983
+ POSTING_READ (PIPE_CRC_CTL (crtc -> index ));
984
+ }
985
+
986
+ void intel_crtc_disable_pipe_crc (struct intel_crtc * intel_crtc )
987
+ {
988
+ struct drm_crtc * crtc = & intel_crtc -> base ;
989
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> dev );
990
+ struct intel_pipe_crc * pipe_crc = & dev_priv -> pipe_crc [crtc -> index ];
991
+
992
+ /* Swallow crc's until we stop generating them. */
993
+ spin_lock_irq (& pipe_crc -> lock );
994
+ pipe_crc -> skipped = INT_MIN ;
995
+ spin_unlock_irq (& pipe_crc -> lock );
996
+
997
+ I915_WRITE (PIPE_CRC_CTL (crtc -> index ), 0 );
998
+ POSTING_READ (PIPE_CRC_CTL (crtc -> index ));
999
+ synchronize_irq (dev_priv -> drm .irq );
1000
+ }
0 commit comments