[RFC PATCH 07/20] drm/i915: Create a new category of display WAs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

Actually populating this is left for future patches: we have to
start moving WAs from init_clock_gating into either GT or
Display functions, and this requires a good deal of careful code
reviewing.

v2: Rebased to carry the init_early nomenclature over (Chris)

v3: Static tables version (Joonas)

Suggested-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>
Signed-off-by: Oscar Mateo <oscar.mateo@xxxxxxxxx>
Reviewed-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> (v2)
Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx>
Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx>
---
 drivers/gpu/drm/i915/i915_drv.h          |   1 +
 drivers/gpu/drm/i915/intel_pm.c          |   2 +
 drivers/gpu/drm/i915/intel_workarounds.c | 124 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_workarounds.h |   5 ++
 4 files changed, 132 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6a62a7b..f781d1c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -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];
 };
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index acd0cbb..0d0e84b 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>
@@ -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)
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index 849e70a..5a532a0 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -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) },
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h
index f60913f..c73dc66 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -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);
-- 
1.9.1

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




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux