@@ -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,
@@ -922,6 +922,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
enum intel_pipe_crc_source source;
u32 val = 0; /* shut up gcc */
int ret = 0;
+ bool dc_off = false;
if (display_crc_ctl_parse_source(source_name, &source) < 0) {
DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
@@ -938,11 +939,19 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
if (ret != 0)
goto out;
+ dc_off = dev_priv->csr.dmc_payload && power_domain == POWER_DOMAIN_PIPE_A;
+ if (dc_off && 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 (dc_off)
+ intel_display_power_put(dev_priv,
+ POWER_DOMAIN_PIPE_A_CRC);
+
if (IS_G4X(dev_priv))
g4x_undo_pipe_scramble_reset(dev_priv, crtc->index);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -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 ( \
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 irrespective of DMC, 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 Cc: Imre Deak <imre.deak@intel.com> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> --- drivers/gpu/drm/i915/intel_display.h | 1 + drivers/gpu/drm/i915/intel_pipe_crc.c | 9 +++++++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 7 +++++++ 3 files changed, 17 insertions(+)