Display workarounds do not need to be re-applied on a GPU reset
(this is, in Ville's words: "at the very least wasted effort [...]
and could even be actively harmful in case we end up clobbering
something the current display configuration depends on"). Therefore,
they have to be applied in a different place that GT ones so they
deserve their own category.

Initially, populate this with the WAs that were being applied in
init_clock_gating. Actually discriminating which of these WAS is
a real display WA, a GT WA or a context WA is left for the next
patch (as it requires a good deal of careful review).

v2: Rebased to carry the init_early nomenclature over (Chris)
v3:
  - Rebased to before the WAs are stored
  - Initially populate with all WAs in init_clock_gating
v4: Rebased

Suggested-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk> (v2)
Signed-off-by: Oscar Mateo <oscar.ma...@intel.com>
Cc: Mika Kuoppala <mika.kuopp...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c          | 304 +-----------------------------
 drivers/gpu/drm/i915/intel_workarounds.c | 309 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_workarounds.h |   2 +
 3 files changed, 319 insertions(+), 296 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b026b02..6917a9d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -29,6 +29,7 @@
 #include <drm/drm_plane_helper.h>
 #include "i915_drv.h"
 #include "intel_drv.h"
+#include "intel_workarounds.h"
 #include "../../../platform/x86/intel_ips.h"
 #include <linux/module.h>
 #include <drm/drm_atomic_helper.h>
@@ -53,92 +54,6 @@
  * require higher latency to switch to and wake up.
  */
 
-static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       if (HAS_LLC(dev_priv)) {
-               /*
-                * WaCompressedResourceDisplayNewHashMode:skl,kbl
-                * Display WA #0390: skl,kbl
-                *
-                * Must match Sampler, Pixel Back End, and Media. See
-                * WaCompressedResourceSamplerPbeMediaNewHashMode.
-                */
-               I915_WRITE(CHICKEN_PAR1_1,
-                          I915_READ(CHICKEN_PAR1_1) |
-                          SKL_DE_COMPRESSED_HASH_MODE);
-       }
-
-       /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
-       I915_WRITE(CHICKEN_PAR1_1,
-                  I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
-
-       /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
-       I915_WRITE(GEN8_CHICKEN_DCPR_1,
-                  I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
-
-       /* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
-       /* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
-       I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
-                  DISP_FBC_WM_DIS |
-                  DISP_FBC_MEMORY_WAKE);
-
-       /* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
-       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-                  ILK_DPFC_DISABLE_DUMMY0);
-
-       if (IS_SKYLAKE(dev_priv)) {
-               /* WaDisableDopClockGating */
-               I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
-                          & ~GEN7_DOP_CLOCK_GATE_ENABLE);
-       }
-}
-
-static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       gen9_init_clock_gating(dev_priv);
-
-       /* WaDisableSDEUnitClockGating:bxt */
-       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-       /*
-        * FIXME:
-        * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
-        */
-       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-                  GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
-
-       /*
-        * Wa: Backlight PWM may stop in the asserted state, causing backlight
-        * to stay fully on.
-        */
-       I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
-                  PWM1_GATING_DIS | PWM2_GATING_DIS);
-}
-
-static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       gen9_init_clock_gating(dev_priv);
-
-       /*
-        * WaDisablePWMClockGating:glk
-        * Backlight PWM may stop in the asserted state, causing backlight
-        * to stay fully on.
-        */
-       I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
-                  PWM1_GATING_DIS | PWM2_GATING_DIS);
-
-       /* WaDDIIOTimeout:glk */
-       if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
-               u32 val = I915_READ(CHICKEN_MISC_2);
-               val &= ~(GLK_CL0_PWR_DOWN |
-                        GLK_CL1_PWR_DOWN |
-                        GLK_CL2_PWR_DOWN);
-               I915_WRITE(CHICKEN_MISC_2, val);
-       }
-
-}
-
 static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv)
 {
        u32 tmp;
@@ -8457,168 +8372,9 @@ static void lpt_suspend_hw(struct drm_i915_private 
*dev_priv)
        }
 }
 
-static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
-                                  int general_prio_credits,
-                                  int high_prio_credits)
-{
-       u32 misccpctl;
-       u32 val;
-
-       /* WaTempDisableDOPClkGating:bdw */
-       misccpctl = I915_READ(GEN7_MISCCPCTL);
-       I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
-
-       val = I915_READ(GEN8_L3SQCREG1);
-       val &= ~L3_PRIO_CREDITS_MASK;
-       val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
-       val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
-       I915_WRITE(GEN8_L3SQCREG1, val);
-
-       /*
-        * Wait at least 100 clocks before re-enabling clock gating.
-        * See the definition of L3SQCREG1 in BSpec.
-        */
-       POSTING_READ(GEN8_L3SQCREG1);
-       udelay(1);
-       I915_WRITE(GEN7_MISCCPCTL, misccpctl);
-}
-
-static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       if (!HAS_PCH_CNP(dev_priv))
-               return;
-
-       /* Display WA #1181: cnp */
-       I915_WRITE(SOUTH_DSPCLK_GATE_D, I915_READ(SOUTH_DSPCLK_GATE_D) |
-                  CNP_PWM_CGE_GATING_DISABLE);
-}
-
-static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       u32 val;
-       cnp_init_clock_gating(dev_priv);
-
-       /* This is not an Wa. Enable for better image quality */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
-
-       /* WaEnableChickenDCPR:cnl */
-       I915_WRITE(GEN8_CHICKEN_DCPR_1,
-                  I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
-
-       /* WaFbcWakeMemOn:cnl */
-       I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
-                  DISP_FBC_MEMORY_WAKE);
-
-       val = I915_READ(SLICE_UNIT_LEVEL_CLKGATE);
-       /* ReadHitWriteOnlyDisable:cnl */
-       val |= RCCUNIT_CLKGATE_DIS;
-       /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
-       if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
-               val |= SARBUNIT_CLKGATE_DIS;
-       I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, val);
-
-       /* WaDisableVFclkgate:cnl */
-       val = I915_READ(UNSLICE_UNIT_LEVEL_CLKGATE);
-       val |= VFUNIT_CLKGATE_DIS;
-       I915_WRITE(UNSLICE_UNIT_LEVEL_CLKGATE, val);
-}
-
-static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       cnp_init_clock_gating(dev_priv);
-       gen9_init_clock_gating(dev_priv);
-
-       /* WaFbcNukeOnHostModify:cfl */
-       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
-static void kbl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       gen9_init_clock_gating(dev_priv);
-
-       /* WaDisableSDEUnitClockGating:kbl */
-       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
-               I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-                          GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-       /* WaDisableGamClockGating:kbl */
-       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
-               I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
-                          GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
-
-       /* WaFbcNukeOnHostModify:kbl */
-       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
-static void skl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       gen9_init_clock_gating(dev_priv);
-
-       /* WAC6entrylatency:skl */
-       I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
-                  FBC_LLC_FULLY_OPEN);
-
-       /* WaFbcNukeOnHostModify:skl */
-       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
 static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-       /* The GTT cache must be disabled if the system is using 2M pages. */
-       bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
-                                                I915_GTT_PAGE_SIZE_2M);
-       enum pipe pipe;
-
-       /* WaSwitchSolVfFArbitrationPriority:bdw */
-       I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
-
-       /* WaPsrDPAMaskVBlankInSRD:bdw */
-       I915_WRITE(CHICKEN_PAR1_1,
-                  I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
-
-       /* WaPsrDPRSUnmaskVBlankInSRD:bdw */
-       for_each_pipe(dev_priv, pipe) {
-               I915_WRITE(CHICKEN_PIPESL_1(pipe),
-                          I915_READ(CHICKEN_PIPESL_1(pipe)) |
-                          BDW_DPRS_MASK_VBLANK_SRD);
-       }
-
-       /* WaVSRefCountFullforceMissDisable:bdw */
-       /* WaDSRefCountFullforceMissDisable:bdw */
-       I915_WRITE(GEN7_FF_THREAD_MODE,
-                  I915_READ(GEN7_FF_THREAD_MODE) &
-                  ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
-
-       I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
-                  _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
-
-       /* WaDisableSDEUnitClockGating:bdw */
-       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-       /* WaProgramL3SqcReg1Default:bdw */
-       gen8_set_l3sqc_credits(dev_priv, 30, 2);
-
-       /* WaGttCachingOffByDefault:bdw */
-       I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
-
-       /* WaKVMNotificationOnConfigChange:bdw */
-       I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
-                  | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
-
        lpt_init_clock_gating(dev_priv);
-
-       /* WaDisableDopClockGating:bdw
-        *
-        * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
-        * clock gating.
-        */
-       I915_WRITE(GEN6_UCGCTL1,
-                  I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
 }
 
 static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -8844,40 +8600,6 @@ static void vlv_init_clock_gating(struct 
drm_i915_private *dev_priv)
        I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
 }
 
-static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-       /* WaVSRefCountFullforceMissDisable:chv */
-       /* WaDSRefCountFullforceMissDisable:chv */
-       I915_WRITE(GEN7_FF_THREAD_MODE,
-                  I915_READ(GEN7_FF_THREAD_MODE) &
-                  ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
-
-       /* WaDisableSemaphoreAndSyncFlipWait:chv */
-       I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
-                  _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
-
-       /* WaDisableCSUnitClockGating:chv */
-       I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
-                  GEN6_CSUNIT_CLOCK_GATE_DISABLE);
-
-       /* WaDisableSDEUnitClockGating:chv */
-       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-       /*
-        * WaProgramL3SqcReg1Default:chv
-        * See gfxspecs/Related Documents/Performance Guide/
-        * LSQC Setting Recommendations.
-        */
-       gen8_set_l3sqc_credits(dev_priv, 38, 2);
-
-       /*
-        * GTT cache may not work with big pages, so if those
-        * are ever enabled GTT cache may need to be disabled.
-        */
-       I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
-}
-
 static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
 {
        uint32_t dspclk_gate;
@@ -8979,6 +8701,7 @@ static void i830_init_clock_gating(struct 
drm_i915_private *dev_priv)
 void intel_init_clock_gating(struct drm_i915_private *dev_priv)
 {
        dev_priv->display.init_clock_gating(dev_priv);
+       intel_disp_workarounds_apply(dev_priv);
 }
 
 void intel_suspend_hw(struct drm_i915_private *dev_priv)
@@ -8997,28 +8720,17 @@ static void nop_init_clock_gating(struct 
drm_i915_private *dev_priv)
  * @dev_priv: device private
  *
  * Setup the hooks that configure which clocks of a given platform can be
- * gated and also apply various GT and display specific workarounds for these
- * platforms. Note that some GT specific workarounds are applied separately
- * when GPU contexts or batchbuffers start their execution.
+ * gated.
  */
 void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
 {
-       if (IS_CANNONLAKE(dev_priv))
-               dev_priv->display.init_clock_gating = cnl_init_clock_gating;
-       else if (IS_COFFEELAKE(dev_priv))
-               dev_priv->display.init_clock_gating = cfl_init_clock_gating;
-       else if (IS_SKYLAKE(dev_priv))
-               dev_priv->display.init_clock_gating = skl_init_clock_gating;
-       else if (IS_KABYLAKE(dev_priv))
-               dev_priv->display.init_clock_gating = kbl_init_clock_gating;
-       else if (IS_BROXTON(dev_priv))
-               dev_priv->display.init_clock_gating = bxt_init_clock_gating;
-       else if (IS_GEMINILAKE(dev_priv))
-               dev_priv->display.init_clock_gating = glk_init_clock_gating;
+       if (IS_CANNONLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
+           IS_GEMINILAKE(dev_priv) || IS_KABYLAKE(dev_priv)   ||
+           IS_BROXTON(dev_priv)    || IS_SKYLAKE(dev_priv)    ||
+           IS_CHERRYVIEW(dev_priv))
+               dev_priv->display.init_clock_gating = nop_init_clock_gating;
        else if (IS_BROADWELL(dev_priv))
                dev_priv->display.init_clock_gating = bdw_init_clock_gating;
-       else if (IS_CHERRYVIEW(dev_priv))
-               dev_priv->display.init_clock_gating = chv_init_clock_gating;
        else if (IS_HASWELL(dev_priv))
                dev_priv->display.init_clock_gating = hsw_init_clock_gating;
        else if (IS_IVYBRIDGE(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
b/drivers/gpu/drm/i915/intel_workarounds.c
index abd4e23..8a27c13 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -647,6 +647,315 @@ void intel_gt_workarounds_apply(struct drm_i915_private 
*dev_priv)
                MISSING_CASE(INTEL_GEN(dev_priv));
 }
 
+static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
+                                  int general_prio_credits,
+                                  int high_prio_credits)
+{
+       u32 misccpctl;
+       u32 val;
+
+       /* WaTempDisableDOPClkGating:bdw */
+       misccpctl = I915_READ(GEN7_MISCCPCTL);
+       I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+
+       val = I915_READ(GEN8_L3SQCREG1);
+       val &= ~L3_PRIO_CREDITS_MASK;
+       val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
+       val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
+       I915_WRITE(GEN8_L3SQCREG1, val);
+
+       /*
+        * Wait at least 100 clocks before re-enabling clock gating.
+        * See the definition of L3SQCREG1 in BSpec.
+        */
+       POSTING_READ(GEN8_L3SQCREG1);
+       udelay(1);
+       I915_WRITE(GEN7_MISCCPCTL, misccpctl);
+}
+
+static void bdw_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       /* The GTT cache must be disabled if the system is using 2M pages. */
+       bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
+                                                I915_GTT_PAGE_SIZE_2M);
+       enum pipe pipe;
+
+       /* WaSwitchSolVfFArbitrationPriority:bdw */
+       I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
+
+       /* WaPsrDPAMaskVBlankInSRD:bdw */
+       I915_WRITE(CHICKEN_PAR1_1,
+                  I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
+
+       /* WaPsrDPRSUnmaskVBlankInSRD:bdw */
+       for_each_pipe(dev_priv, pipe) {
+               I915_WRITE(CHICKEN_PIPESL_1(pipe),
+                          I915_READ(CHICKEN_PIPESL_1(pipe)) |
+                          BDW_DPRS_MASK_VBLANK_SRD);
+       }
+
+       /* WaVSRefCountFullforceMissDisable:bdw */
+       /* WaDSRefCountFullforceMissDisable:bdw */
+       I915_WRITE(GEN7_FF_THREAD_MODE,
+                  I915_READ(GEN7_FF_THREAD_MODE) &
+                  ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+       I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+                  _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+       /* WaDisableSDEUnitClockGating:bdw */
+       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+       /* WaProgramL3SqcReg1Default:bdw */
+       gen8_set_l3sqc_credits(dev_priv, 30, 2);
+
+       /* WaGttCachingOffByDefault:bdw */
+       I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
+
+       /* WaKVMNotificationOnConfigChange:bdw */
+       I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
+                  | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
+
+       /* WaDisableDopClockGating:bdw
+        *
+        * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
+        * clock gating.
+        */
+       I915_WRITE(GEN6_UCGCTL1,
+                  I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
+}
+
+static void chv_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       /* WaVSRefCountFullforceMissDisable:chv */
+       /* WaDSRefCountFullforceMissDisable:chv */
+       I915_WRITE(GEN7_FF_THREAD_MODE,
+                  I915_READ(GEN7_FF_THREAD_MODE) &
+                  ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+       /* WaDisableSemaphoreAndSyncFlipWait:chv */
+       I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+                  _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+       /* WaDisableCSUnitClockGating:chv */
+       I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
+                  GEN6_CSUNIT_CLOCK_GATE_DISABLE);
+
+       /* WaDisableSDEUnitClockGating:chv */
+       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+       /*
+        * WaProgramL3SqcReg1Default:chv
+        * See gfxspecs/Related Documents/Performance Guide/
+        * LSQC Setting Recommendations.
+        */
+       gen8_set_l3sqc_credits(dev_priv, 38, 2);
+
+       /*
+        * GTT cache may not work with big pages, so if those
+        * are ever enabled GTT cache may need to be disabled.
+        */
+       I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
+}
+
+static void gen9_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       if (HAS_LLC(dev_priv)) {
+               /*
+                * WaCompressedResourceDisplayNewHashMode:skl,kbl
+                * Display WA #0390: skl,kbl
+                *
+                * Must match Sampler, Pixel Back End, and Media. See
+                * WaCompressedResourceSamplerPbeMediaNewHashMode.
+                */
+               I915_WRITE(CHICKEN_PAR1_1,
+                          I915_READ(CHICKEN_PAR1_1) |
+                          SKL_DE_COMPRESSED_HASH_MODE);
+       }
+
+       /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
+       I915_WRITE(CHICKEN_PAR1_1,
+                  I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+
+       /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
+       I915_WRITE(GEN8_CHICKEN_DCPR_1,
+                  I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+       /* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
+       /* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
+       I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+                  DISP_FBC_WM_DIS |
+                  DISP_FBC_MEMORY_WAKE);
+
+       /* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
+       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+                  ILK_DPFC_DISABLE_DUMMY0);
+
+       if (IS_SKYLAKE(dev_priv)) {
+               /* WaDisableDopClockGating */
+               I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
+                          & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+       }
+}
+
+static void skl_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       gen9_disp_workarounds_apply(dev_priv);
+
+       /* WAC6entrylatency:skl */
+       I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
+                  FBC_LLC_FULLY_OPEN);
+
+       /* WaFbcNukeOnHostModify:skl */
+       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void bxt_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       gen9_disp_workarounds_apply(dev_priv);
+
+       /* WaDisableSDEUnitClockGating:bxt */
+       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+       /*
+        * FIXME:
+        * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
+        */
+       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+                  GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
+
+       /*
+        * Wa: Backlight PWM may stop in the asserted state, causing backlight
+        * to stay fully on.
+        */
+       I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
+                  PWM1_GATING_DIS | PWM2_GATING_DIS);
+}
+
+static void kbl_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       gen9_disp_workarounds_apply(dev_priv);
+
+       /* WaDisableSDEUnitClockGating:kbl */
+       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+               I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+                          GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+       /* WaDisableGamClockGating:kbl */
+       if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+               I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
+                          GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
+
+       /* WaFbcNukeOnHostModify:kbl */
+       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void glk_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       gen9_disp_workarounds_apply(dev_priv);
+
+       /*
+        * WaDisablePWMClockGating:glk
+        * Backlight PWM may stop in the asserted state, causing backlight
+        * to stay fully on.
+        */
+       I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
+                  PWM1_GATING_DIS | PWM2_GATING_DIS);
+
+       /* WaDDIIOTimeout:glk */
+       if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
+               u32 val = I915_READ(CHICKEN_MISC_2);
+               val &= ~(GLK_CL0_PWR_DOWN |
+                        GLK_CL1_PWR_DOWN |
+                        GLK_CL2_PWR_DOWN);
+               I915_WRITE(CHICKEN_MISC_2, val);
+       }
+}
+
+static void cnp_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       if (!HAS_PCH_CNP(dev_priv))
+               return;
+
+       /* Display WA #1181: cnp */
+       I915_WRITE(SOUTH_DSPCLK_GATE_D, I915_READ(SOUTH_DSPCLK_GATE_D) |
+                  CNP_PWM_CGE_GATING_DISABLE);
+}
+
+static void cfl_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       cnp_disp_workarounds_apply(dev_priv);
+       gen9_disp_workarounds_apply(dev_priv);
+
+       /* WaFbcNukeOnHostModify:cfl */
+       I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+                  ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void cnl_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       u32 val;
+       cnp_disp_workarounds_apply(dev_priv);
+
+       /* This is not an Wa. Enable for better image quality */
+       I915_WRITE(_3D_CHICKEN3,
+                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
+
+       /* WaEnableChickenDCPR:cnl */
+       I915_WRITE(GEN8_CHICKEN_DCPR_1,
+                  I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+       /* WaFbcWakeMemOn:cnl */
+       I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+                  DISP_FBC_MEMORY_WAKE);
+
+       val = I915_READ(SLICE_UNIT_LEVEL_CLKGATE);
+       /* ReadHitWriteOnlyDisable:cnl */
+       val |= RCCUNIT_CLKGATE_DIS;
+       /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
+       if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
+               val |= SARBUNIT_CLKGATE_DIS;
+       I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, val);
+
+       /* WaDisableVFclkgate:cnl */
+       val = I915_READ(UNSLICE_UNIT_LEVEL_CLKGATE);
+       val |= VFUNIT_CLKGATE_DIS;
+       I915_WRITE(UNSLICE_UNIT_LEVEL_CLKGATE, val);
+}
+
+/*
+ * FIXME: Some of the WAs applied here are incorrectly classified as Display
+ * WAs. We still need to go through them and apply them in the right place.
+ */
+void intel_disp_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+       if (INTEL_GEN(dev_priv) < 8)
+               return;
+       else if (IS_BROADWELL(dev_priv))
+               bdw_disp_workarounds_apply(dev_priv);
+       else if (IS_CHERRYVIEW(dev_priv))
+               chv_disp_workarounds_apply(dev_priv);
+       else if (IS_SKYLAKE(dev_priv))
+               skl_disp_workarounds_apply(dev_priv);
+       else if (IS_BROXTON(dev_priv))
+               bxt_disp_workarounds_apply(dev_priv);
+       else if (IS_KABYLAKE(dev_priv))
+               kbl_disp_workarounds_apply(dev_priv);
+       else if (IS_GEMINILAKE(dev_priv))
+               glk_disp_workarounds_apply(dev_priv);
+       else if (IS_COFFEELAKE(dev_priv))
+               cfl_disp_workarounds_apply(dev_priv);
+       else if (IS_CANNONLAKE(dev_priv))
+               cnl_disp_workarounds_apply(dev_priv);
+       else
+               MISSING_CASE(INTEL_GEN(dev_priv));
+}
+
 static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
                                 i915_reg_t reg)
 {
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h 
b/drivers/gpu/drm/i915/intel_workarounds.h
index 8c01a3b..5c37f65 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -12,6 +12,8 @@
 
 void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
 
+void intel_disp_workarounds_apply(struct drm_i915_private *dev_priv);
+
 int intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
 
 int intel_engine_init_bb_workarounds(struct intel_engine_cs *engine);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to