diff mbox

[OEM-5.17,1/1] drm/i915/display: Re-add check for low voltage sku for max dp source rate

Message ID 20220704051554.80033-2-aaron.ma@canonical.com
State New
Headers show

Commit Message

Aaron Ma July 4, 2022, 5:15 a.m. UTC
From: "Jason A. Donenfeld" <Jason@zx2c4.com>

BugLink: https://bugs.launchpad.net/bugs/1980621

This reverts commit 73867c8709b5 ("drm/i915/display: Remove check for
low voltage sku for max dp source rate"), which, on an i7-11850H iGPU
with a Thinkpad X1 Extreme Gen 4, attached to a LG LP160UQ1-SPB1
embedded panel, causes wild flickering glitching technicolor
pyrotechnics on resumption from suspend. The display shows strobing
colors in an utter disaster explosion of pantone, as though bombs were
dropped on the leprechauns at the base of the rainbow.

Rebooting the machine fixes the issue, presumably because the display is
initialized by firmware rather than by i915. Otherwise, the GPU appears
to work fine.

Bisection traced it back to this commit, which makes sense given the
issues.

Note: This re-opens, and puts back to the drawing board,
https://gitlab.freedesktop.org/drm/intel/-/issues/5272 which was fixed
by the regressing commit.

Fixes: 73867c8709b5 ("drm/i915/display: Remove check for low voltage sku for max dp source rate")
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6205
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Jani Saarinen <jani.saarinen@intel.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220613102241.9236-1-Jason@zx2c4.com
(cherry picked from commit d5929835080a60f9119d024fa42f315913942f76)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit c7b28f52f406bc89d15ca0ccbc47994f979f2fcd)
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 32 ++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a438e508a6910..62e763faf0aa5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -387,13 +387,23 @@  static int dg2_max_source_rate(struct intel_dp *intel_dp)
 	return intel_dp_is_edp(intel_dp) ? 810000 : 1350000;
 }
 
+static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
+{
+	u32 voltage;
+
+	voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & VOLTAGE_INFO_MASK;
+
+	return voltage == VOLTAGE_INFO_0_85V;
+}
+
 static int icl_max_source_rate(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
-	if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
+	if (intel_phy_is_combo(dev_priv, phy) &&
+	    (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
 		return 540000;
 
 	return 810000;
@@ -401,7 +411,23 @@  static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-	if (intel_dp_is_edp(intel_dp))
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+	enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
+
+	if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
+		return 540000;
+
+	return 810000;
+}
+
+static int dg1_max_source_rate(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+	enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
+
+	if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
 		return 540000;
 
 	return 810000;
@@ -444,7 +470,7 @@  intel_dp_set_source_rates(struct intel_dp *intel_dp)
 			max_rate = dg2_max_source_rate(intel_dp);
 		else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
 			 IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
-			max_rate = 810000;
+			max_rate = dg1_max_source_rate(intel_dp);
 		else if (IS_JSL_EHL(dev_priv))
 			max_rate = ehl_max_source_rate(intel_dp);
 		else