diff mbox series

[SRU,N,1/8] UBUNTU: SAUCE: drm/i915/display/psr: add a psr2 disable quirk table

Message ID 20240814091643.42397-2-en-wei.wu@canonical.com
State New
Headers show
Series Add some PSR2 quirks to avoid panel flickering issues | expand

Commit Message

En-Wei Wu Aug. 14, 2024, 9:16 a.m. UTC
BugLink: https://bugs.launchpad.net/bugs/2069993

This design refers to the Kai-Heng's work:
https://lists.ubuntu.com/archives/kernel-team/2023-February/137349.html

Signed-off-by: En-Wei Wu <en-wei.wu@canonical.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c  | 11 +++++++
 drivers/gpu/drm/i915/display/intel_dp.h  |  2 ++
 drivers/gpu/drm/i915/display/intel_psr.c | 40 ++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 94d2a15d8444..b6f950e097c6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5498,6 +5498,17 @@  intel_dp_get_edid(struct intel_dp *intel_dp)
 	return drm_edid_read_ddc(&connector->base, &intel_dp->aux.ddc);
 }
 
+const struct edid *
+intel_dp_fetch_edid(struct intel_dp *intel_dp)
+{
+	const struct drm_edid * d_edid;
+	d_edid = intel_dp_get_edid(intel_dp);
+	if (d_edid)
+		return drm_edid_raw(d_edid);
+
+	return NULL;
+}
+
 static void
 intel_dp_update_dfp(struct intel_dp *intel_dp,
 		    const struct drm_edid *drm_edid)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 375d0677cd8c..e2f51483b33d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -187,4 +187,6 @@  intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
 
 void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);
 
+const struct edid *intel_dp_fetch_edid(struct intel_dp *intel_dp);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 4faaf4b3fc53..13b0631d4911 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -24,6 +24,7 @@ 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_damage_helper.h>
 #include <drm/drm_debugfs.h>
+#include <drm/drm_edid.h>
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -1013,11 +1014,50 @@  tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
 	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
 }
 
+struct edid_mfgid_prodcode {
+	u8 mfg_id0;
+	u8 mfg_id1;
+	u8 prod_code0;
+	u8 prod_code1;
+};
+
+#define PSR2_DISABLE_QUIRK_ENTRY(id0, id1, code0, code1) \
+	{ .mfg_id0 = (id0), .mfg_id1 = (id1), .prod_code0 = (code0), .prod_code1 = (code1) }
+
+static struct edid_mfgid_prodcode psr2_disable_quirk_tbl[] = {
+	{ }
+};
+
+static bool is_edid_in_psr2_disable_quirk_tbl(struct intel_dp *intel_dp)
+{
+	const struct edid *p_edid;
+	int i;
+
+	p_edid = intel_dp_fetch_edid(intel_dp);
+	if (p_edid) {
+		for (i = 0; i < ARRAY_SIZE(psr2_disable_quirk_tbl); i ++) {
+			if (p_edid->mfg_id[0] == psr2_disable_quirk_tbl[i].mfg_id0 &&
+			    p_edid->mfg_id[1] == psr2_disable_quirk_tbl[i].mfg_id1 &&
+			    p_edid->prod_code[0] == psr2_disable_quirk_tbl[i].prod_code0 &&
+			    p_edid->prod_code[1] == psr2_disable_quirk_tbl[i].prod_code1)
+				return true;
+		}
+	}
+
+	return false;
+}
+
 static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
 					      struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
+	if (is_edid_in_psr2_disable_quirk_tbl(intel_dp)) {
+		drm_info_once(&dev_priv->drm,
+			      "PSR2 sel fetch disabled by the edid quirk table\n");
+		return false;
+	}
+
 	if (!dev_priv->display.params.enable_psr2_sel_fetch &&
 	    intel_dp->psr.debug != I915_PSR_DEBUG_ENABLE_SEL_FETCH) {
 		drm_dbg_kms(&dev_priv->drm,