diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4ebf899e4c40..75a5ace58b80 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5508,6 +5508,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 0ab4e70462ea..eb5522146a23 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" @@ -1015,11 +1016,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,