For DG2, wa_22014263786 is applicable only if the number of active
planes is greater than 1 in pipe A and pipe B. Cursor planes and
any planes on pipe C or pipe D are not considered for this.

Bspec: 54077, 72197
Signed-off-by: Vinod Govindapillai <[email protected]>
---
 .../gpu/drm/i915/display/intel_display_wa.c   | 29 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_fbc.c      |  6 ++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c 
b/drivers/gpu/drm/i915/display/intel_display_wa.c
index a00af39f7538..ffc2356283aa 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.c
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.c
@@ -7,6 +7,7 @@
 
 #include "i915_reg.h"
 #include "intel_de.h"
+#include "intel_display_types.h"
 #include "intel_display_core.h"
 #include "intel_display_regs.h"
 #include "intel_display_wa.h"
@@ -53,6 +54,32 @@ static bool intel_display_needs_wa_16025573575(struct 
intel_display *display)
                DISPLAY_VERx100(display) == 3500;
 }
 
+static bool intel_display_needs_wa_22014263786(struct intel_display *display)
+{
+       if (!IS_DISPLAY_VERx100(display, 1100, 1400))
+               return false;
+
+       if (display->platform.dg2) {
+               u8 pipe_mask = PIPE_A | PIPE_B;
+               int num_active_planes = 0;
+               struct intel_crtc *crtc;
+
+               for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) 
{
+                       const struct intel_crtc_state *crtc_state =
+                               to_intel_crtc_state(crtc->base.state);
+                       u8 active_planes =
+                               crtc_state->active_planes & ~BIT(PLANE_CURSOR);
+
+                       num_active_planes += hweight8(active_planes);
+               }
+
+               if (num_active_planes <= 1)
+                       return false;
+       }
+
+       return true;
+}
+
 /*
  * Wa_14011503117:
  * Fixes: Before enabling the scaler DE fatal error is masked
@@ -69,7 +96,7 @@ bool __intel_display_wa(struct intel_display *display, enum 
intel_display_wa wa,
        case INTEL_DISPLAY_WA_14011503117:
                return DISPLAY_VER(display) == 13;
        case INTEL_DISPLAY_WA_22014263786:
-               return IS_DISPLAY_VERx100(display, 1100, 1400);
+               return intel_display_needs_wa_22014263786(display);
        case INTEL_DISPLAY_WA_15018326506:
                return display->platform.battlemage;
        case INTEL_DISPLAY_WA_14025769978:
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c 
b/drivers/gpu/drm/i915/display/intel_fbc.c
index fef2f35ff1e9..5b0a83cb5386 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -944,10 +944,16 @@ static void intel_fbc_program_workarounds(struct 
intel_fbc *fbc)
         * Wa_22014263786
         * Fixes: Screen flicker with FBC and Package C state enabled
         * Workaround: Forced SLB invalidation before start of new frame.
+        *             For DG2, wa is applied only if the number of planes
+        *             in PIPE A and PIPE B is > 1. If the wa condition is
+        *             not met, this chicken bit must be unset for DG2.
         */
        if (intel_display_wa(display, 22014263786))
                intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
                             0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION);
+       else if (display->platform.dg2)
+               intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
+                            DPFC_CHICKEN_FORCE_SLB_INVALIDATION, 0);
 
        /* wa_18038517565 Disable DPFC clock gating before FBC enable */
        if (display->platform.dg2 || DISPLAY_VER(display) >= 14)
-- 
2.43.0

Reply via email to