diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-11 13:30:13 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-23 01:05:17 -0400 |
commit | 3638379cfe83604f2759399a998fa90ad0fd56ca (patch) | |
tree | 988708aea6704ef6c2d66a69da7eb0e667096813 | |
parent | e921bcbfba1f973c60e3c537adeb32e0cdf2eb77 (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.c | 43 |
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 | ||
1903 | static 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 | |||
1913 | void intel_edp_psr_exit(struct drm_device *dev) | 1909 | void 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)); |