drm/i915: Display WA 827
authorVidya Srinivas <vidya.srinivas@intel.com>
Mon, 9 Apr 2018 03:41:09 +0000 (09:11 +0530)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Mon, 9 Apr 2018 11:40:22 +0000 (13:40 +0200)
Display WA 827 applies to GEN9 (excluede GLK) and CNL.
Switching the plane format from NV12 to RGB and leaving system idle
results in display underrun and corruption.
WA: Set the bit 15 & bit 19 to 1b in the CLKGATE_DIS_PSL
register for the pipe in which NV12 plane is enabled.

v2: Addressed review comments from Maarten and
Juha-Pekka Heikkila. Added reviewed by from
Juha-Pekka Heikkila.

v3: Rebased the series

Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
Signed-off-by: Nabendu Maiti <nabendu.bikash.maiti@intel.com>
Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1523245273-30264-11-git-send-email-vidya.srinivas@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c

index b3a6428aa71dc056dd89d14922bf52a61fd48be6..1f858e2c85f0c8fd7b27dc1ad808fac97bf7ab2f 100644 (file)
@@ -3824,6 +3824,9 @@ enum {
 #define _CLKGATE_DIS_PSL_A             0x46520
 #define _CLKGATE_DIS_PSL_B             0x46524
 #define _CLKGATE_DIS_PSL_C             0x46528
+#define   DUPS1_GATING_DIS             (1 << 15)
+#define   DUPS2_GATING_DIS             (1 << 19)
+#define   DUPS3_GATING_DIS             (1 << 23)
 #define   DPF_GATING_DIS               (1 << 10)
 #define   DPF_RAM_GATING_DIS           (1 << 9)
 #define   DPFR_GATING_DIS              (1 << 8)
index 057f3cf95e862a26134c6f76c61396b6af2f1442..466d2479a8fbc531efd79952d61b7da7dfeedfd3 100644 (file)
@@ -488,6 +488,21 @@ static const struct intel_limit intel_limits_bxt = {
        .p2 = { .p2_slow = 1, .p2_fast = 20 },
 };
 
+static void
+skl_wa_clkgate(struct drm_i915_private *dev_priv, int pipe, bool enable)
+{
+       if (IS_SKYLAKE(dev_priv))
+               return;
+
+       if (enable)
+               I915_WRITE(CLKGATE_DIS_PSL(pipe),
+                          DUPS1_GATING_DIS | DUPS2_GATING_DIS);
+       else
+               I915_WRITE(CLKGATE_DIS_PSL(pipe),
+                          I915_READ(CLKGATE_DIS_PSL(pipe)) &
+                          ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS));
+}
+
 static bool
 needs_modeset(const struct drm_crtc_state *state)
 {
@@ -5103,6 +5118,8 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
 static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_atomic_state *old_state = old_crtc_state->base.state;
        struct intel_crtc_state *pipe_config =
                intel_atomic_get_new_crtc_state(to_intel_atomic_state(old_state),
@@ -5125,6 +5142,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
                                                         to_intel_plane(primary));
                struct intel_plane_state *old_primary_state =
                        to_intel_plane_state(old_pri_state);
+               struct drm_framebuffer *fb = primary_state->base.fb;
 
                intel_fbc_post_update(crtc);
 
@@ -5132,6 +5150,14 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
                    (needs_modeset(&pipe_config->base) ||
                     !old_primary_state->base.visible))
                        intel_post_enable_primary(&crtc->base, pipe_config);
+
+               /* Display WA 827 */
+               if ((INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv)) ||
+                   IS_CANNONLAKE(dev_priv)) {
+                       if (fb && fb->format->format == DRM_FORMAT_NV12)
+                               skl_wa_clkgate(dev_priv, crtc->pipe, false);
+               }
+
        }
 }
 
@@ -5158,6 +5184,14 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
                                                         to_intel_plane(primary));
                struct intel_plane_state *old_primary_state =
                        to_intel_plane_state(old_pri_state);
+               struct drm_framebuffer *fb = primary_state->base.fb;
+
+               /* Display WA 827 */
+               if ((INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv)) ||
+                   IS_CANNONLAKE(dev_priv)) {
+                       if (fb && fb->format->format == DRM_FORMAT_NV12)
+                               skl_wa_clkgate(dev_priv, crtc->pipe, true);
+               }
 
                intel_fbc_pre_update(crtc, pipe_config, primary_state);
                /*