drm/i915: PSR VLV: Add single frame update.
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Fri, 10 Apr 2015 18:15:10 +0000 (11:15 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 14 Apr 2015 17:15:23 +0000 (19:15 +0200)
According to spec: "In PSR HW or SW mode, SW set this bit before writing
registers for a flip. It will be self-clear when it gets to the PSR
active state."

Some versions of spec mention that this is needed when in
"Persistent mode" but define it as same as "SW mode". Since this
fix the page flip case let's assume this is exactly what we need.

Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_frontbuffer.c
drivers/gpu/drm/i915/intel_psr.c

index 6a2ee0c3816118739c6bd74a78d7ef0740a91e23..082be7161203d4d84b833d46895d74a339fe015c 100644 (file)
@@ -1294,6 +1294,7 @@ void intel_psr_invalidate(struct drm_device *dev,
 void intel_psr_flush(struct drm_device *dev,
                         unsigned frontbuffer_bits);
 void intel_psr_init(struct drm_device *dev);
+void intel_psr_single_frame_update(struct drm_device *dev);
 
 /* intel_runtime_pm.c */
 int intel_power_domains_init(struct drm_i915_private *);
index a20cffb78c0f495055df8de87a0755e3a06cdb16..57095f54c1f2e2611d2442bb9fbf12b645196302 100644 (file)
@@ -243,6 +243,8 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
        /* Remove stale busy bits due to the old buffer. */
        dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
        mutex_unlock(&dev_priv->fb_tracking.lock);
+
+       intel_psr_single_frame_update(dev);
 }
 
 /**
index 5cd374b4a07ec7d73e6986dd070e0ad8afe1447f..5ee0fa57ed1999b4a8432c89265d82bc2f90513e 100644 (file)
@@ -593,6 +593,48 @@ static void intel_psr_exit(struct drm_device *dev)
        dev_priv->psr.active = false;
 }
 
+/**
+ * intel_psr_single_frame_update - Single Frame Update
+ * @dev: DRM device
+ *
+ * Some platforms support a single frame update feature that is used to
+ * send and update only one frame on Remote Frame Buffer.
+ * So far it is only implemented for Valleyview and Cherryview because
+ * hardware requires this to be done before a page flip.
+ */
+void intel_psr_single_frame_update(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_crtc *crtc;
+       enum pipe pipe;
+       u32 val;
+
+       /*
+        * Single frame update is already supported on BDW+ but it requires
+        * many W/A and it isn't really needed.
+        */
+       if (!IS_VALLEYVIEW(dev))
+               return;
+
+       mutex_lock(&dev_priv->psr.lock);
+       if (!dev_priv->psr.enabled) {
+               mutex_unlock(&dev_priv->psr.lock);
+               return;
+       }
+
+       crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+       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);
+
+       mutex_unlock(&dev_priv->psr.lock);
+}
+
 /**
  * intel_psr_invalidate - Invalidade PSR
  * @dev: DRM device