[PATCH] drm/i915/psr: Prevent DC5/6 entry when reading pipe CRCs

Dhinakaran Pandiyan dhinakaran.pandiyan at gmail.com
Sat Jun 30 07:54:55 UTC 2018


We've seen pipe CRC related failures in CI when PSR is enabled. Since
pipe A can be disabled by DMC when PSR is enabled, it is likely that CRCs
aren't available. Grab a power domain reference to enable DC_OFF power well
to handle this. It might well be possible that CRC's are wrong or
unavailable with PSR on non DMC platforms like HSW/BDW too, but let's start
with this.

References: https://bugs.freedesktop.org/show_bug.cgi?id=106103
References: https://bugs.freedesktop.org/show_bug.cgi?id=105750
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
---
 drivers/gpu/drm/i915/intel_display.h    |  1 +
 drivers/gpu/drm/i915/intel_pipe_crc.c   | 13 +++++++++++--
 drivers/gpu/drm/i915/intel_runtime_pm.c |  7 +++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index a77dd29db2ec..5cbdf9a7846d 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -204,6 +204,7 @@ enum intel_display_power_domain {
 	POWER_DOMAIN_AUX_TBT3,
 	POWER_DOMAIN_AUX_TBT4,
 	POWER_DOMAIN_GMBUS,
+	POWER_DOMAIN_PIPE_A_CRC,
 	POWER_DOMAIN_MODESET,
 	POWER_DOMAIN_GT_IRQ,
 	POWER_DOMAIN_INIT,
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 25ec1c2a64b7..43b0f10d11d6 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -477,16 +477,26 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
 		DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
 		return -EIO;
 	}
-
 	ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val, true);
 	if (ret != 0)
 		goto out;
 
+#define NEEDS_DC_OFF(pd) (dev_priv->csr.dmc_payload &&		\
+			  (pd) == POWER_DOMAIN_PIPE_A &&	\
+			  CAN_PSR(dev_priv))
+	if (NEEDS_DC_OFF(power_domain) && source)
+		intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A_CRC);
+
 	pipe_crc->source = source;
+
 	I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
 	POSTING_READ(PIPE_CRC_CTL(crtc->index));
 
 	if (!source) {
+		if (NEEDS_DC_OFF(power_domain))
+			intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A_CRC);
+#undef NEEDS_DC_OFF
+
 		if (IS_G4X(dev_priv))
 			g4x_undo_pipe_scramble_reset(dev_priv, crtc->index);
 		else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -501,7 +511,6 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
 
 out:
 	intel_display_power_put(dev_priv, power_domain);
-
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index d81b2cfe1c5e..fd12bba1be3b 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -144,6 +144,8 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
 		return "AUX_TBT4";
 	case POWER_DOMAIN_GMBUS:
 		return "GMBUS";
+	case POWER_DOMAIN_PIPE_A_CRC:
+		return "PIPE_A_CRC:";
 	case POWER_DOMAIN_INIT:
 		return "INIT";
 	case POWER_DOMAIN_MODESET:
@@ -1800,6 +1802,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT_ULL(POWER_DOMAIN_GT_IRQ) |			\
 	BIT_ULL(POWER_DOMAIN_MODESET) |			\
 	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
+	BIT_ULL(POWER_DOMAIN_PIPE_A_CRC) |		\
 	BIT_ULL(POWER_DOMAIN_INIT))
 
 #define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS (		\
@@ -1822,6 +1825,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT_ULL(POWER_DOMAIN_GT_IRQ) |			\
 	BIT_ULL(POWER_DOMAIN_MODESET) |			\
 	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
+	BIT_ULL(POWER_DOMAIN_PIPE_A_CRC) |		\
 	BIT_ULL(POWER_DOMAIN_GMBUS) |			\
 	BIT_ULL(POWER_DOMAIN_INIT))
 #define BXT_DPIO_CMN_A_POWER_DOMAINS (			\
@@ -1883,6 +1887,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT_ULL(POWER_DOMAIN_GT_IRQ) |			\
 	BIT_ULL(POWER_DOMAIN_MODESET) |			\
 	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
+	BIT_ULL(POWER_DOMAIN_PIPE_A_CRC) |		\
 	BIT_ULL(POWER_DOMAIN_GMBUS) |			\
 	BIT_ULL(POWER_DOMAIN_INIT))
 
@@ -1941,6 +1946,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT_ULL(POWER_DOMAIN_GT_IRQ) |			\
 	BIT_ULL(POWER_DOMAIN_MODESET) |			\
 	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
+	BIT_ULL(POWER_DOMAIN_PIPE_A_CRC) |		\
 	BIT_ULL(POWER_DOMAIN_INIT))
 
 /*
@@ -2006,6 +2012,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	ICL_PW_2_POWER_DOMAINS |			\
 	BIT_ULL(POWER_DOMAIN_MODESET) |			\
 	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
+	BIT_ULL(POWER_DOMAIN_PIPE_A_CRC) |		\
 	BIT_ULL(POWER_DOMAIN_INIT))
 
 #define ICL_DDI_IO_A_POWER_DOMAINS (			\
-- 
2.14.1



More information about the Intel-gfx-trybot mailing list