瀏覽代碼

drm/i915/psr: Restrict single-shot updates to the PSR pipe

The frontbuffer code gives us accurate information about activity,
let's use it. Again this should avoid unecessary updates when multiple
screens are on.

Also realign function paramaters, I couldn't resist that bit of OCD.

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Durgadoss R <durgadoss.r@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Daniel Vetter 10 年之前
父節點
當前提交
20c8838b0e
共有 3 個文件被更改,包括 18 次插入13 次删除
  1. 4 3
      drivers/gpu/drm/i915/intel_drv.h
  2. 1 1
      drivers/gpu/drm/i915/intel_frontbuffer.c
  3. 13 9
      drivers/gpu/drm/i915/intel_psr.c

+ 4 - 3
drivers/gpu/drm/i915/intel_drv.h

@@ -1307,11 +1307,12 @@ void intel_backlight_unregister(struct drm_device *dev);
 void intel_psr_enable(struct intel_dp *intel_dp);
 void intel_psr_enable(struct intel_dp *intel_dp);
 void intel_psr_disable(struct intel_dp *intel_dp);
 void intel_psr_disable(struct intel_dp *intel_dp);
 void intel_psr_invalidate(struct drm_device *dev,
 void intel_psr_invalidate(struct drm_device *dev,
-			      unsigned frontbuffer_bits);
+			  unsigned frontbuffer_bits);
 void intel_psr_flush(struct drm_device *dev,
 void intel_psr_flush(struct drm_device *dev,
-			 unsigned frontbuffer_bits);
+		     unsigned frontbuffer_bits);
 void intel_psr_init(struct drm_device *dev);
 void intel_psr_init(struct drm_device *dev);
-void intel_psr_single_frame_update(struct drm_device *dev);
+void intel_psr_single_frame_update(struct drm_device *dev,
+				   unsigned frontbuffer_bits);
 
 
 /* intel_runtime_pm.c */
 /* intel_runtime_pm.c */
 int intel_power_domains_init(struct drm_i915_private *);
 int intel_power_domains_init(struct drm_i915_private *);

+ 1 - 1
drivers/gpu/drm/i915/intel_frontbuffer.c

@@ -243,7 +243,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
 	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
 	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
 	mutex_unlock(&dev_priv->fb_tracking.lock);
 	mutex_unlock(&dev_priv->fb_tracking.lock);
 
 
-	intel_psr_single_frame_update(dev);
+	intel_psr_single_frame_update(dev, frontbuffer_bits);
 }
 }
 
 
 /**
 /**

+ 13 - 9
drivers/gpu/drm/i915/intel_psr.c

@@ -596,13 +596,15 @@ static void intel_psr_exit(struct drm_device *dev)
 /**
 /**
  * intel_psr_single_frame_update - Single Frame Update
  * intel_psr_single_frame_update - Single Frame Update
  * @dev: DRM device
  * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
  *
  *
  * Some platforms support a single frame update feature that is used to
  * Some platforms support a single frame update feature that is used to
  * send and update only one frame on Remote Frame Buffer.
  * send and update only one frame on Remote Frame Buffer.
  * So far it is only implemented for Valleyview and Cherryview because
  * So far it is only implemented for Valleyview and Cherryview because
  * hardware requires this to be done before a page flip.
  * hardware requires this to be done before a page flip.
  */
  */
-void intel_psr_single_frame_update(struct drm_device *dev)
+void intel_psr_single_frame_update(struct drm_device *dev,
+				   unsigned frontbuffer_bits)
 {
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	struct drm_crtc *crtc;
@@ -624,14 +626,16 @@ void intel_psr_single_frame_update(struct drm_device *dev)
 
 
 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
 	pipe = to_intel_crtc(crtc)->pipe;
 	pipe = to_intel_crtc(crtc)->pipe;
-	val = I915_READ(VLV_PSRCTL(pipe));
 
 
-	/*
-	 * We need to set this bit before writing registers for a flip.
-	 * This bit will be self-clear when it gets to the PSR active state.
-	 */
-	I915_WRITE(VLV_PSRCTL(pipe), val | VLV_EDP_PSR_SINGLE_FRAME_UPDATE);
+	if (frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)) {
+		val = I915_READ(VLV_PSRCTL(pipe));
 
 
+		/*
+		 * We need to set this bit before writing registers for a flip.
+		 * This bit will be self-clear when it gets to the PSR active state.
+		 */
+		I915_WRITE(VLV_PSRCTL(pipe), val | VLV_EDP_PSR_SINGLE_FRAME_UPDATE);
+	}
 	mutex_unlock(&dev_priv->psr.lock);
 	mutex_unlock(&dev_priv->psr.lock);
 }
 }
 
 
@@ -648,7 +652,7 @@ void intel_psr_single_frame_update(struct drm_device *dev)
  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
  */
  */
 void intel_psr_invalidate(struct drm_device *dev,
 void intel_psr_invalidate(struct drm_device *dev,
-			      unsigned frontbuffer_bits)
+			  unsigned frontbuffer_bits)
 {
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	struct drm_crtc *crtc;
@@ -685,7 +689,7 @@ void intel_psr_invalidate(struct drm_device *dev,
  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
  */
  */
 void intel_psr_flush(struct drm_device *dev,
 void intel_psr_flush(struct drm_device *dev,
-			 unsigned frontbuffer_bits)
+		     unsigned frontbuffer_bits)
 {
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	struct drm_crtc *crtc;