[07/10] drm/i915: Disable PSR2 while getting pipe CRC

Submitted by Souza, Jose on Feb. 12, 2019, 1:48 a.m.

Details

Message ID 20190212014812.29118-7-jose.souza@intel.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Intel GFX - Try Bot

Not browsing as part of any series.

Commit Message

Souza, Jose Feb. 12, 2019, 1:48 a.m.
As stated in CRC_CTL spec, CRC must be enabled before enable PSR
because it will be calculate in PSR entry state.
But for PSR2 it is more problematic as a page flip could trigger a
partial screen update causing the CRC value not to be calculated over
the full pipe or plane.

So here if PSR2 is enabled, it will exit and keep PSR2 inactive while
there is CRC users of the pipe used by eDP panel.

BSpec: 7536

Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/intel_drv.h      |  1 +
 drivers/gpu/drm/i915/intel_pipe_crc.c | 10 ++++++++++
 drivers/gpu/drm/i915/intel_psr.c      | 23 +++++++++++++++++++++++
 4 files changed, 35 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 058b4caa121a..c24283ed0b55 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -524,6 +524,7 @@  struct i915_psr {
 	bool sink_not_reliable;
 	bool irq_aux_error;
 	u16 su_x_granularity;
+	bool pipe_crc_enabled;
 };
 
 enum intel_pch {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3b2001f9d067..f4b2a10d047e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2102,6 +2102,7 @@  void intel_psr_short_pulse(struct intel_dp *intel_dp);
 int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
 			    u32 *out_value);
 bool intel_psr_enabled(struct intel_dp *intel_dp);
+void intel_psr_crc_prepare_or_finish(struct drm_i915_private *dev_priv, enum pipe pipe, bool prepare);
 
 /* intel_quirks.c */
 void intel_init_quirks(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index a8554dc4f196..e04a232eba64 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -583,6 +583,14 @@  int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
 	return -EINVAL;
 }
 
+static void intel_crtc_crc_prepare_or_finish(struct drm_crtc *crtc, bool prepare)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	intel_psr_crc_prepare_or_finish(dev_priv, intel_crtc->pipe, prepare);
+}
+
 int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
@@ -609,6 +617,8 @@  int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
 	if (ret != 0)
 		goto out;
 
+	intel_crtc_crc_prepare_or_finish(crtc, source != INTEL_PIPE_CRC_SOURCE_NONE);
+
 	pipe_crc->source = source;
 	I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
 	POSTING_READ(PIPE_CRC_CTL(crtc->index));
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index c80352069232..cfc0e4730779 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -572,6 +572,9 @@  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
+	if (dev_priv->psr.pipe_crc_enabled)
+		return false;
+
 	return true;
 }
 
@@ -1283,3 +1286,23 @@  bool intel_psr_enabled(struct intel_dp *intel_dp)
 
 	return ret;
 }
+
+void intel_psr_crc_prepare_or_finish(struct drm_i915_private *dev_priv, enum pipe pipe, bool prepare)
+{
+	bool fastset = false;
+
+	if (!CAN_PSR(dev_priv))
+		return;
+
+	mutex_lock(&dev_priv->psr.lock);
+
+	if (dev_priv->psr.pipe == pipe) {
+		dev_priv->psr.pipe_crc_enabled = prepare;
+		fastset = !prepare || dev_priv->psr.psr2_enabled;
+	}
+
+	mutex_unlock(&dev_priv->psr.lock);
+
+	if (fastset)
+		intel_psr_fastset_force(dev_priv);
+}