@@ -2010,6 +2010,7 @@ struct i915_wa_reg_table {
struct i915_workarounds {
u32 ctx_count;
u32 gt_count;
+ u32 disp_count;
u32 hw_whitelist_count[I915_NUM_ENGINES];
};
@@ -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>
@@ -9013,6 +9014,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_display_workarounds_apply(dev_priv);
}
void intel_suspend_hw(struct drm_i915_private *dev_priv)
@@ -33,6 +33,10 @@
.name = (wa), \
.type = I915_WA_TYPE_GT
+#define WA_DISP(wa) \
+ .name = (wa), \
+ .type = I915_WA_TYPE_DISPLAY
+
#define WA_WHITELIST(wa) \
.name = (wa), \
.type = I915_WA_TYPE_WHITELIST
@@ -868,6 +872,126 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)
DRM_DEBUG_DRIVER("Number of GT specific w/a: %u\n", total_count);
}
+static struct i915_wa_reg gen8_disp_was[] = {
+};
+
+static struct i915_wa_reg bdw_disp_was[] = {
+};
+
+static struct i915_wa_reg chv_disp_was[] = {
+};
+
+static struct i915_wa_reg gen9_disp_was[] = {
+};
+
+static struct i915_wa_reg skl_disp_was[] = {
+};
+
+static struct i915_wa_reg bxt_disp_was[] = {
+};
+
+static struct i915_wa_reg kbl_disp_was[] = {
+};
+
+static struct i915_wa_reg glk_disp_was[] = {
+};
+
+static struct i915_wa_reg cfl_disp_was[] = {
+};
+
+static struct i915_wa_reg cnl_disp_was[] = {
+};
+
+static const struct i915_wa_reg_table bdw_disp_wa_tbl[] = {
+ { gen8_disp_was, ARRAY_SIZE(gen8_disp_was) },
+ { bdw_disp_was, ARRAY_SIZE(bdw_disp_was) },
+};
+
+static const struct i915_wa_reg_table chv_disp_wa_tbl[] = {
+ { gen8_disp_was, ARRAY_SIZE(gen8_disp_was) },
+ { chv_disp_was, ARRAY_SIZE(chv_disp_was) },
+};
+
+static const struct i915_wa_reg_table skl_disp_wa_tbl[] = {
+ { gen9_disp_was, ARRAY_SIZE(gen9_disp_was) },
+ { skl_disp_was, ARRAY_SIZE(skl_disp_was) },
+};
+
+static const struct i915_wa_reg_table bxt_disp_wa_tbl[] = {
+ { gen9_disp_was, ARRAY_SIZE(gen9_disp_was) },
+ { bxt_disp_was, ARRAY_SIZE(bxt_disp_was) },
+};
+
+static const struct i915_wa_reg_table kbl_disp_wa_tbl[] = {
+ { gen9_disp_was, ARRAY_SIZE(gen9_disp_was) },
+ { kbl_disp_was, ARRAY_SIZE(kbl_disp_was) },
+};
+
+static const struct i915_wa_reg_table glk_disp_wa_tbl[] = {
+ { gen9_disp_was, ARRAY_SIZE(gen9_disp_was) },
+ { glk_disp_was, ARRAY_SIZE(glk_disp_was) },
+};
+
+static const struct i915_wa_reg_table cfl_disp_wa_tbl[] = {
+ { gen9_disp_was, ARRAY_SIZE(gen9_disp_was) },
+ { cfl_disp_was, ARRAY_SIZE(cfl_disp_was) },
+};
+
+static const struct i915_wa_reg_table cnl_disp_wa_tbl[] = {
+ { cnl_disp_was, ARRAY_SIZE(cnl_disp_was) },
+};
+
+void intel_display_workarounds_get(struct drm_i915_private *dev_priv,
+ const struct i915_wa_reg_table **wa_table,
+ uint *table_count)
+{
+ *wa_table = NULL;
+ *table_count = 0;
+
+ if (INTEL_GEN(dev_priv) < 8)
+ return;
+ else if (IS_BROADWELL(dev_priv)) {
+ *wa_table = bdw_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(bdw_disp_wa_tbl);
+ } else if (IS_CHERRYVIEW(dev_priv)) {
+ *wa_table = chv_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(chv_disp_wa_tbl);
+ } else if (IS_SKYLAKE(dev_priv)) {
+ *wa_table = skl_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(skl_disp_wa_tbl);
+ } else if (IS_BROXTON(dev_priv)) {
+ *wa_table = bxt_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(bxt_disp_wa_tbl);
+ } else if (IS_KABYLAKE(dev_priv)) {
+ *wa_table = kbl_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(kbl_disp_wa_tbl);
+ } else if (IS_GEMINILAKE(dev_priv)) {
+ *wa_table = glk_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(glk_disp_wa_tbl);
+ } else if (IS_COFFEELAKE(dev_priv)) {
+ *wa_table = cfl_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(cfl_disp_wa_tbl);
+ } else if (IS_CANNONLAKE(dev_priv)) {
+ *wa_table = cnl_disp_wa_tbl;
+ *table_count = ARRAY_SIZE(cnl_disp_wa_tbl);
+ } else {
+ MISSING_CASE(INTEL_GEN(dev_priv));
+ return;
+ }
+}
+
+void intel_display_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+ const struct i915_wa_reg_table *wa_table;
+ uint table_count, total_count;
+
+ intel_display_workarounds_get(dev_priv, &wa_table, &table_count);
+ total_count = mmio_workarounds_apply(dev_priv, wa_table, table_count);
+
+ dev_priv->workarounds.disp_count = total_count;
+ DRM_DEBUG_DRIVER("Number of Display specific w/a: %u\n", total_count);
+}
+
static struct i915_wa_reg gen9_whitelist_was[] = {
{ WA_WHITELIST("WaVFEStateAfterPipeControlwithMediaStateClear"),
ALL_REVS, WHITELIST(GEN9_CTX_PREEMPT_REG) },
@@ -35,6 +35,11 @@ void intel_gt_workarounds_get(struct drm_i915_private *dev_priv,
uint *table_count);
void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
+void intel_display_workarounds_get(struct drm_i915_private *dev_priv,
+ const struct i915_wa_reg_table **wa_table,
+ uint *table_count);
+void intel_display_workarounds_apply(struct drm_i915_private *dev_priv);
+
void intel_whitelist_workarounds_get(struct drm_i915_private *dev_priv,
const struct i915_wa_reg_table **wa_table,
uint *table_count);