@@ -375,6 +375,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
intel_dp_set_idle_link_train(intel_dp);
+ if (channel_eq == false &&
+ intel_dp_is_edp(intel_dp) &&
+ i915->quirks & QUIRK_EDP_CHANNEL_EQ) {
+ DRM_NOTE("Forcing channel_eq success for eDP\n");
+ channel_eq = true;
+ }
+
return channel_eq;
}
@@ -53,6 +53,17 @@ static void quirk_increase_ddi_disabled_time(struct drm_i915_private *i915)
drm_info(&i915->drm, "Applying Increase DDI Disabled quirk\n");
}
+/*
+ * Some machines (Dell Latitude 7200 2-in-1) fail channel equalization
+ * on their eDP when it is actually usable. This lets channel_eq
+ * report success.
+ */
+static void quirk_edp_channel_eq(struct drm_i915_private *i915)
+{
+ i915->quirks |= QUIRK_EDP_CHANNEL_EQ;
+ drm_info(&i915->drm, "applying eDP channel_eq quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -72,6 +83,12 @@ static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
return 1;
}
+static int intel_dmi_edp_channel_eq(const struct dmi_system_id *id)
+{
+ DRM_INFO("eDP channel_eq workaround on %s\n", id->ident);
+ return 1;
+}
+
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
@@ -96,6 +113,19 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
},
.hook = quirk_invert_brightness,
},
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = intel_dmi_edp_channel_eq,
+ .ident = "Dell Latitude 7200 2-in-1",
+ .matches = {DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 7200 2-in-1"),
+ },
+ },
+ { } /* terminating entry */
+ },
+ .hook = quirk_edp_channel_eq,
+ },
};
static struct intel_quirk intel_quirks[] = {
@@ -525,6 +525,7 @@ struct i915_psr {
#define QUIRK_PIN_SWIZZLED_PAGES (1<<5)
#define QUIRK_INCREASE_T12_DELAY (1<<6)
#define QUIRK_INCREASE_DDI_DISABLED_TIME (1<<7)
+#define QUIRK_EDP_CHANNEL_EQ (1<<8)
struct intel_fbdev;
struct intel_fbc_work;
We're seeing channel equalization "fail" consistently coming out of DPMS on the eDP of a Dell Latitude 7200 2-in-1. When the display tries to come out of DPMS, it briefly flashes on before going dark. This repeats once per second, and the system is unusable. ssh-ing into the system, it also seems to be sluggish when in this state. You have to reboot to get the display back. In intel_dp_link_training_channel_equalization, lane 0 can get to state 0x7 by the 3rd pattern, but lane 1 never gets further than 0x1. [drm] ln0_1:0x0 ln2_3:0x0 align:0x0 sink:0x0 adj_req0_1:0x0 adj_req2_3:0x0 [drm] ln0_1:0x11 ln2_3:0x0 align:0x80 sink:0x0 adj_req0_1:0x44 adj_req2_3:0x0 [drm] ln0_1:0x11 ln2_3:0x0 align:0x80 sink:0x0 adj_req0_1:0x88 adj_req2_3:0x0 [drm] ln0_1:0x71 ln2_3:0x0 align:0x80 sink:0x0 adj_req0_1:0x84 adj_req2_3:0x0 [drm] ln0_1:0x71 ln2_3:0x0 align:0x0 sink:0x0 adj_req0_1:0x84 adj_req2_3:0x0 [drm] ln0_1:0x71 ln2_3:0x0 align:0x0 sink:0x0 adj_req0_1:0x84 adj_req2_3:0x0 Narrow fast vs. wide slow is not an option because the max clock is 270000 and the 1920x1280 resolution requires 2x270000. [drm] DP link computation with lane count min/max 1/2 270000/270000 bpp min/max 18/24 pixel clock 164250KHz The display is functional even though lane 1 is in state 0x1, so just return success for channel equalization on eDP. Introduce QUIRK_EDP_CHANNEL_EQ and match the DMI for a Dell Latitude 7200 2-in-1. This quirk allows channel equalization to succeed even though it failed. Workaround for https://gitlab.freedesktop.org/drm/intel/-/issues/1378 Signed-off-by: Jason Andryuk <jandryuk@gmail.com> Cc: <stable@vger.kernel.org> --- .../drm/i915/display/intel_dp_link_training.c | 7 +++++ drivers/gpu/drm/i915/display/intel_quirks.c | 30 +++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + 3 files changed, 38 insertions(+)