aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-11 13:30:13 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-23 01:05:17 -0400
commit3638379cfe83604f2759399a998fa90ad0fd56ca (patch)
tree988708aea6704ef6c2d66a69da7eb0e667096813
parente921bcbfba1f973c60e3c537adeb32e0cdf2eb77 (diff)
drm/i915: Lock down psr sw/hw state tracking
Make sure we track the sw side (psr.active) correctly and WARN everywhere it might get out of sync with the hw. v2: Fixup WARN_ON logic inversion, reported by Rodrigo. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0184188b3a2d..f630c23a7bd6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1834,8 +1834,8 @@ static void intel_edp_psr_do_enable(struct intel_dp *intel_dp)
1834 struct drm_device *dev = intel_dig_port->base.base.dev; 1834 struct drm_device *dev = intel_dig_port->base.base.dev;
1835 struct drm_i915_private *dev_priv = dev->dev_private; 1835 struct drm_i915_private *dev_priv = dev->dev_private;
1836 1836
1837 if (intel_edp_is_psr_enabled(dev)) 1837 WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
1838 return; 1838 WARN_ON(dev_priv->psr.active);
1839 1839
1840 /* Enable PSR on the panel */ 1840 /* Enable PSR on the panel */
1841 intel_edp_psr_enable_sink(intel_dp); 1841 intel_edp_psr_enable_sink(intel_dp);
@@ -1876,13 +1876,19 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp)
1876 if (!dev_priv->psr.enabled) 1876 if (!dev_priv->psr.enabled)
1877 return; 1877 return;
1878 1878
1879 I915_WRITE(EDP_PSR_CTL(dev), 1879 if (dev_priv->psr.active) {
1880 I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE); 1880 I915_WRITE(EDP_PSR_CTL(dev),
1881 I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE);
1882
1883 /* Wait till PSR is idle */
1884 if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) &
1885 EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
1886 DRM_ERROR("Timed out waiting for PSR Idle State\n");
1881 1887
1882 /* Wait till PSR is idle */ 1888 dev_priv->psr.active = false;
1883 if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) & 1889 } else {
1884 EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) 1890 WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
1885 DRM_ERROR("Timed out waiting for PSR Idle State\n"); 1891 }
1886 1892
1887 dev_priv->psr.enabled = NULL; 1893 dev_priv->psr.enabled = NULL;
1888} 1894}
@@ -1900,16 +1906,6 @@ static void intel_edp_psr_work(struct work_struct *work)
1900 intel_edp_psr_do_enable(intel_dp); 1906 intel_edp_psr_do_enable(intel_dp);
1901} 1907}
1902 1908
1903static void intel_edp_psr_inactivate(struct drm_device *dev)
1904{
1905 struct drm_i915_private *dev_priv = dev->dev_private;
1906
1907 dev_priv->psr.active = false;
1908
1909 I915_WRITE(EDP_PSR_CTL(dev), I915_READ(EDP_PSR_CTL(dev))
1910 & ~EDP_PSR_ENABLE);
1911}
1912
1913void intel_edp_psr_exit(struct drm_device *dev) 1909void intel_edp_psr_exit(struct drm_device *dev)
1914{ 1910{
1915 struct drm_i915_private *dev_priv = dev->dev_private; 1911 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1922,8 +1918,15 @@ void intel_edp_psr_exit(struct drm_device *dev)
1922 1918
1923 cancel_delayed_work_sync(&dev_priv->psr.work); 1919 cancel_delayed_work_sync(&dev_priv->psr.work);
1924 1920
1925 if (dev_priv->psr.active) 1921 if (dev_priv->psr.active) {
1926 intel_edp_psr_inactivate(dev); 1922 u32 val = I915_READ(EDP_PSR_CTL(dev));
1923
1924 WARN_ON(!(val & EDP_PSR_ENABLE));
1925
1926 I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE);
1927
1928 dev_priv->psr.active = false;
1929 }
1927 1930
1928 schedule_delayed_work(&dev_priv->psr.work, 1931 schedule_delayed_work(&dev_priv->psr.work,
1929 msecs_to_jiffies(100)); 1932 msecs_to_jiffies(100));