71893eb
From 0fdb20f83f9962a3501e9cbdbfcc37ed5e721ab8 Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:31 -0400
71893eb
Subject: [PATCH 1/7] drm/i915: Fix eDP DPCD aux max backlight calculations
71893eb
71893eb
Max backlight value for the panel was being calculated using byte
71893eb
count i.e. 0xffff if 2 bytes are supported for backlight brightness
71893eb
and 0xff if 1 byte is supported. However, EDP_PWMGEN_BIT_COUNT
71893eb
determines the number of active control bits used for the brightness
71893eb
setting. Thus, even if the panel uses 2 byte setting, it might not use
71893eb
all the control bits. Thus, max backlight should be set based on the
71893eb
value of EDP_PWMGEN_BIT_COUNT instead of assuming 65535 or 255.
71893eb
71893eb
Additionally, EDP_PWMGEN_BIT_COUNT was being updated based on the VBT
71893eb
frequency which results in a different max backlight value. Thus,
71893eb
setting of EDP_PWMGEN_BIT_COUNT is moved to setup phase instead of
71893eb
enable so that max backlight can be calculated correctly. Only the
71893eb
frequency divider is set during the enable phase using the value of
71893eb
EDP_PWMGEN_BIT_COUNT.
71893eb
71893eb
This is based off the original patch series from Furquan Shaikh
71893eb
<furquan@google.com>:
71893eb
71893eb
https://patchwork.freedesktop.org/patch/317255/?series=62326&rev=3
71893eb
71893eb
Changes since original patch:
71893eb
* Remove unused intel_dp variable in intel_dp_aux_setup_backlight()
71893eb
* Fix checkpatch issues
71893eb
* Make sure that we rewrite the pwmgen bit count whenever we bring the
71893eb
  panel out of D3 mode
71893eb
71893eb
v2 by Jani:
71893eb
* rebase
71893eb
* fix readb return value check
71893eb
71893eb
Cc: Furquan Shaikh <furquan@google.com>
71893eb
Tested-by: AceLan Kao <acelan.kao@canonical.com>
71893eb
Tested-by: Perry Yuan <pyuan@redhat.com>
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
71893eb
Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-2-lyude@redhat.com
71893eb
---
71893eb
 .../drm/i915/display/intel_display_types.h    |   3 +
71893eb
 .../drm/i915/display/intel_dp_aux_backlight.c | 139 ++++++++++++------
71893eb
 2 files changed, 95 insertions(+), 47 deletions(-)
71893eb
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
index 888ea8a170d1..778bd30743e5 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
@@ -214,6 +214,9 @@ struct intel_panel {
71893eb
 		u8 controller;		/* bxt+ only */
71893eb
 		struct pwm_device *pwm;
71893eb
 
71893eb
+		/* DPCD backlight */
71893eb
+		u8 pwmgen_bit_count;
71893eb
+
71893eb
 		struct backlight_device *device;
71893eb
 
71893eb
 		/* Connector and platform specific backlight functions */
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
index 7c653f8c307f..345eed641455 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
@@ -111,61 +111,28 @@ static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
71893eb
 {
71893eb
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
71893eb
 	struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
71893eb
-	int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
71893eb
-	u8 pn, pn_min, pn_max;
71893eb
+	const u8 pn = connector->panel.backlight.pwmgen_bit_count;
71893eb
+	int freq, fxp, f, fxp_actual, fxp_min, fxp_max;
71893eb
 
71893eb
-	/* Find desired value of (F x P)
71893eb
-	 * Note that, if F x P is out of supported range, the maximum value or
71893eb
-	 * minimum value will applied automatically. So no need to check that.
71893eb
-	 */
71893eb
 	freq = dev_priv->vbt.backlight.pwm_freq_hz;
71893eb
-	DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
71893eb
 	if (!freq) {
71893eb
 		DRM_DEBUG_KMS("Use panel default backlight frequency\n");
71893eb
 		return false;
71893eb
 	}
71893eb
 
71893eb
 	fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
71893eb
+	f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
71893eb
+	fxp_actual = f << pn;
71893eb
 
71893eb
-	/* Use highest possible value of Pn for more granularity of brightness
71893eb
-	 * adjustment while satifying the conditions below.
71893eb
-	 * - Pn is in the range of Pn_min and Pn_max
71893eb
-	 * - F is in the range of 1 and 255
71893eb
-	 * - FxP is within 25% of desired value.
71893eb
-	 *   Note: 25% is arbitrary value and may need some tweak.
71893eb
-	 */
71893eb
-	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
-			       DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
71893eb
-		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
71893eb
-		return false;
71893eb
-	}
71893eb
-	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
-			       DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
71893eb
-		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
71893eb
-		return false;
71893eb
-	}
71893eb
-	pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
71893eb
-	pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
71893eb
-
71893eb
+	/* Ensure frequency is within 25% of desired value */
71893eb
 	fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
71893eb
 	fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
71893eb
-	if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
71893eb
-		DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
71893eb
-		return false;
71893eb
-	}
71893eb
 
71893eb
-	for (pn = pn_max; pn >= pn_min; pn--) {
71893eb
-		f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
71893eb
-		fxp_actual = f << pn;
71893eb
-		if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
71893eb
-			break;
71893eb
-	}
71893eb
-
71893eb
-	if (drm_dp_dpcd_writeb(&intel_dp->aux,
71893eb
-			       DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
71893eb
-		DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
71893eb
+	if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
71893eb
+		DRM_DEBUG_KMS("Actual frequency out of range\n");
71893eb
 		return false;
71893eb
 	}
71893eb
+
71893eb
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
71893eb
 			       DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
71893eb
 		DRM_DEBUG_KMS("Failed to write aux backlight freq\n");
71893eb
@@ -179,6 +146,7 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
71893eb
 {
71893eb
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
71893eb
 	struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
71893eb
+	struct intel_panel *panel = &connector->panel;
71893eb
 	u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode;
71893eb
 
71893eb
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
@@ -197,6 +165,12 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
71893eb
 	case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT:
71893eb
 		new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
71893eb
 		new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
71893eb
+
71893eb
+		if (drm_dp_dpcd_writeb(&intel_dp->aux,
71893eb
+				       DP_EDP_PWMGEN_BIT_COUNT,
71893eb
+				       panel->backlight.pwmgen_bit_count) < 0)
71893eb
+			DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
71893eb
+
71893eb
 		break;
71893eb
 
71893eb
 	/* Do nothing when it is already DPCD mode */
71893eb
@@ -226,20 +200,91 @@ static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old
71893eb
 				 false);
71893eb
 }
71893eb
 
71893eb
+static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
71893eb
+{
71893eb
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
71893eb
+	struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
71893eb
+	struct intel_panel *panel = &connector->panel;
71893eb
+	u32 max_backlight = 0;
71893eb
+	int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
71893eb
+	u8 pn, pn_min, pn_max;
71893eb
+
71893eb
+	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT, &pn) == 1) {
71893eb
+		pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
71893eb
+		max_backlight = (1 << pn) - 1;
71893eb
+	}
71893eb
+
71893eb
+	/* Find desired value of (F x P)
71893eb
+	 * Note that, if F x P is out of supported range, the maximum value or
71893eb
+	 * minimum value will applied automatically. So no need to check that.
71893eb
+	 */
71893eb
+	freq = i915->vbt.backlight.pwm_freq_hz;
71893eb
+	DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
71893eb
+	if (!freq) {
71893eb
+		DRM_DEBUG_KMS("Use panel default backlight frequency\n");
71893eb
+		return max_backlight;
71893eb
+	}
71893eb
+
71893eb
+	fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
71893eb
+
71893eb
+	/* Use highest possible value of Pn for more granularity of brightness
71893eb
+	 * adjustment while satifying the conditions below.
71893eb
+	 * - Pn is in the range of Pn_min and Pn_max
71893eb
+	 * - F is in the range of 1 and 255
71893eb
+	 * - FxP is within 25% of desired value.
71893eb
+	 *   Note: 25% is arbitrary value and may need some tweak.
71893eb
+	 */
71893eb
+	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
+			      DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
71893eb
+		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
71893eb
+		return max_backlight;
71893eb
+	}
71893eb
+	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
+			      DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
71893eb
+		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
71893eb
+		return max_backlight;
71893eb
+	}
71893eb
+	pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
71893eb
+	pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
71893eb
+
71893eb
+	fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
71893eb
+	fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
71893eb
+	if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
71893eb
+		DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
71893eb
+		return max_backlight;
71893eb
+	}
71893eb
+
71893eb
+	for (pn = pn_max; pn >= pn_min; pn--) {
71893eb
+		f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
71893eb
+		fxp_actual = f << pn;
71893eb
+		if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
71893eb
+			break;
71893eb
+	}
71893eb
+
71893eb
+	DRM_DEBUG_KMS("Using eDP pwmgen bit count of %d\n", pn);
71893eb
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
71893eb
+			       DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
71893eb
+		DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
71893eb
+		return max_backlight;
71893eb
+	}
71893eb
+	panel->backlight.pwmgen_bit_count = pn;
71893eb
+
71893eb
+	max_backlight = (1 << pn) - 1;
71893eb
+
71893eb
+	return max_backlight;
71893eb
+}
71893eb
+
71893eb
 static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
71893eb
 					enum pipe pipe)
71893eb
 {
71893eb
-	struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
71893eb
 	struct intel_panel *panel = &connector->panel;
71893eb
 
71893eb
-	if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
71893eb
-		panel->backlight.max = 0xFFFF;
71893eb
-	else
71893eb
-		panel->backlight.max = 0xFF;
71893eb
+	panel->backlight.max = intel_dp_aux_calc_max_backlight(connector);
71893eb
+	if (!panel->backlight.max)
71893eb
+		return -ENODEV;
71893eb
 
71893eb
 	panel->backlight.min = 0;
71893eb
 	panel->backlight.level = intel_dp_aux_get_backlight(connector);
71893eb
-
71893eb
 	panel->backlight.enabled = panel->backlight.level != 0;
71893eb
 
71893eb
 	return 0;
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From 7dbe3f659d364de34b210baf0598913dc8c3cabd Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:32 -0400
71893eb
Subject: [PATCH 2/7] drm/i915: Assume 100% brightness when not in DPCD control
71893eb
 mode
71893eb
71893eb
Currently we always determine the initial panel brightness level by
71893eb
simply reading the value from DP_EDP_BACKLIGHT_BRIGHTNESS_MSB/LSB. This
71893eb
seems wrong though, because if the panel is not currently in DPCD
71893eb
control mode there's not really any reason why there would be any
71893eb
brightness value programmed in the first place.
71893eb
71893eb
This appears to be the case on the Lenovo ThinkPad X1 Extreme 2nd
71893eb
Generation, where the default value in these registers is always 0 on
71893eb
boot despite the fact the panel runs at max brightness by default.
71893eb
Getting the initial brightness value correct here is important as well,
71893eb
since the panel on this laptop doesn't behave well if it's ever put into
71893eb
DPCD control mode while the brightness level is programmed to 0.
71893eb
71893eb
So, let's fix this by checking what the current backlight control mode
71893eb
is before reading the brightness level. If it's in DPCD control mode, we
71893eb
return the programmed brightness level. Otherwise we assume 100%
71893eb
brightness and return the highest possible brightness level. This also
71893eb
prevents us from accidentally programming a brightness level of 0.
71893eb
71893eb
This is one of the many fixes that gets backlight controls working on
71893eb
the ThinkPad X1 Extreme 2nd Generation with optional 4K AMOLED screen.
71893eb
71893eb
Changes since v1:
71893eb
* s/DP_EDP_DISPLAY_CONTROL_REGISTER/DP_EDP_BACKLIGHT_MODE_SET_REGISTER/
71893eb
  - Jani
71893eb
71893eb
Tested-by: AceLan Kao <acelan.kao@canonical.com>
71893eb
Tested-by: Perry Yuan <pyuan@redhat.com>
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
71893eb
Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-3-lyude@redhat.com
71893eb
---
71893eb
 .../drm/i915/display/intel_dp_aux_backlight.c   | 17 +++++++++++++++++
71893eb
 1 file changed, 17 insertions(+)
71893eb
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
index 345eed641455..5d4db5f8a165 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
@@ -59,8 +59,25 @@ static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
71893eb
 {
71893eb
 	struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
71893eb
 	u8 read_val[2] = { 0x0 };
71893eb
+	u8 mode_reg;
71893eb
 	u16 level = 0;
71893eb
 
71893eb
+	if (drm_dp_dpcd_readb(&intel_dp->aux,
71893eb
+			      DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
71893eb
+			      &mode_reg) != 1) {
71893eb
+		DRM_DEBUG_KMS("Failed to read the DPCD register 0x%x\n",
71893eb
+			      DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
71893eb
+		return 0;
71893eb
+	}
71893eb
+
71893eb
+	/*
71893eb
+	 * If we're not in DPCD control mode yet, the programmed brightness
71893eb
+	 * value is meaningless and we should assume max brightness
71893eb
+	 */
71893eb
+	if ((mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) !=
71893eb
+	    DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD)
71893eb
+		return connector->panel.backlight.max;
71893eb
+
71893eb
 	if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
71893eb
 			     &read_val, sizeof(read_val)) < 0) {
71893eb
 		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From b2a29a70e386c2fbd92e1b7980091e7980495211 Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:33 -0400
71893eb
Subject: [PATCH 3/7] drm/i915: Fix DPCD register order in
71893eb
 intel_dp_aux_enable_backlight()
71893eb
71893eb
For eDP panels, it appears it's expected that so long as the panel is in
71893eb
DPCD control mode that the brightness value is never set to 0. Instead,
71893eb
if the desired effect is to set the panel's backlight to 0 we're
71893eb
expected to simply turn off the backlight through the
71893eb
DP_EDP_DISPLAY_CONTROL_REGISTER.
71893eb
71893eb
We already do the latter correctly in intel_dp_aux_disable_backlight().
71893eb
But, we make the mistake of writing the DPCD registers in the wrong
71893eb
order when enabling the backlight in intel_dp_aux_enable_backlight()
71893eb
since we currently enable the backlight through
71893eb
DP_EDP_DISPLAY_CONTROL_REGISTER before writing the brightness level. On
71893eb
the X1 Extreme 2nd Generation, this appears to have the potential of
71893eb
confusing the panel in such a way that further attempts to set the
71893eb
brightness don't actually change the backlight as expected and leave it
71893eb
off. Presumably, this happens because the incorrect register writing
71893eb
order briefly leaves the panel with DPCD mode enabled and a 0 brightness
71893eb
level set.
71893eb
71893eb
So, reverse the order we write the DPCD registers when enabling the
71893eb
panel backlight so that we write the brightness value first, and enable
71893eb
the backlight second. This fix appears to be the final bit needed to get
71893eb
the backlight on the ThinkPad X1 Extreme 2nd Generation's AMOLED screen
71893eb
working.
71893eb
71893eb
Tested-by: AceLan Kao <acelan.kao@canonical.com>
71893eb
Tested-by: Perry Yuan <pyuan@redhat.com>
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
71893eb
Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-4-lyude@redhat.com
71893eb
---
71893eb
 drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 3 ++-
71893eb
 1 file changed, 2 insertions(+), 1 deletion(-)
71893eb
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
index 5d4db5f8a165..77a759361c5c 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
@@ -207,8 +207,9 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
71893eb
 		}
71893eb
 	}
71893eb
 
71893eb
+	intel_dp_aux_set_backlight(conn_state,
71893eb
+				   connector->panel.backlight.level);
71893eb
 	set_aux_backlight_enable(intel_dp, true);
71893eb
-	intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level);
71893eb
 }
71893eb
 
71893eb
 static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old_conn_state)
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From 8b2e6f450c1f8d34632d4789369030008e874a75 Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:34 -0400
71893eb
Subject: [PATCH 4/7] drm/i915: Auto detect DPCD backlight support by default
71893eb
71893eb
Turns out we actually already have some companies, such as Lenovo,
71893eb
shipping machines with AMOLED screens that don't allow controlling the
71893eb
backlight through the usual PWM interface and only allow controlling it
71893eb
through the standard EDP DPCD interface. One example of one of these
71893eb
laptops is the X1 Extreme 2nd Generation.
71893eb
71893eb
Since we've got systems that need this turned on by default now to have
71893eb
backlight controls working out of the box, let's start auto-detecting it
71893eb
for systems by default based on what the VBT tells us. We do this by
71893eb
changing the default value for the enable_dpcd_backlight module param
71893eb
from 0 to -1.
71893eb
71893eb
Tested-by: AceLan Kao <acelan.kao@canonical.com>
71893eb
Tested-by: Perry Yuan <pyuan@redhat.com>
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
71893eb
Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-6-lyude@redhat.com
71893eb
---
71893eb
 drivers/gpu/drm/i915/i915_params.c | 2 +-
71893eb
 drivers/gpu/drm/i915/i915_params.h | 2 +-
71893eb
 2 files changed, 2 insertions(+), 2 deletions(-)
71893eb
71893eb
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
71893eb
index 1dd1f3652795..31eed60c167e 100644
71893eb
--- a/drivers/gpu/drm/i915/i915_params.c
71893eb
+++ b/drivers/gpu/drm/i915/i915_params.c
71893eb
@@ -172,7 +172,7 @@ i915_param_named_unsafe(inject_probe_failure, uint, 0400,
71893eb
 
71893eb
 i915_param_named(enable_dpcd_backlight, int, 0600,
71893eb
 	"Enable support for DPCD backlight control"
71893eb
-	"(-1=use per-VBT LFP backlight type setting, 0=disabled [default], 1=enabled)");
71893eb
+	"(-1=use per-VBT LFP backlight type setting [default], 0=disabled, 1=enabled)");
71893eb
 
71893eb
 #if IS_ENABLED(CONFIG_DRM_I915_GVT)
71893eb
 i915_param_named(enable_gvt, bool, 0400,
71893eb
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
71893eb
index 31b88f297fbc..a79d0867f77a 100644
71893eb
--- a/drivers/gpu/drm/i915/i915_params.h
71893eb
+++ b/drivers/gpu/drm/i915/i915_params.h
71893eb
@@ -64,7 +64,7 @@ struct drm_printer;
71893eb
 	param(int, reset, 3) \
71893eb
 	param(unsigned int, inject_probe_failure, 0) \
71893eb
 	param(int, fastboot, -1) \
71893eb
-	param(int, enable_dpcd_backlight, 0) \
71893eb
+	param(int, enable_dpcd_backlight, -1) \
71893eb
 	param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE) \
71893eb
 	param(unsigned long, fake_lmem_start, 0) \
71893eb
 	/* leave bools at the end to not create holes */ \
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From c10b0dfaac8385f9b712a552c9a5eed9976aacf2 Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:35 -0400
71893eb
Subject: [PATCH 5/7] drm/dp: Introduce EDID-based quirks
71893eb
71893eb
The whole point of using OUIs is so that we can recognize certain
71893eb
devices and potentially apply quirks for them. Normally this should work
71893eb
quite well, but there appears to be quite a number of laptop panels out
71893eb
there that will fill the OUI but not the device ID. As such, for devices
71893eb
like this I can't imagine it's a very good idea to try relying on OUIs
71893eb
for applying quirks. As well, some laptop vendors have confirmed to us
71893eb
that their panels have this exact issue.
71893eb
71893eb
So, let's introduce the ability to apply DP quirks based on EDID
71893eb
identification. We reuse the same quirk bits for OUI-based quirks, so
71893eb
that callers can simply check all possible quirks using
71893eb
drm_dp_has_quirk().
71893eb
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Reviewed-by: Adam Jackson <ajax@redhat.com>
71893eb
Cc: Jani Nikula <jani.nikula@intel.com>
71893eb
---
71893eb
 drivers/gpu/drm/drm_dp_helper.c               | 61 +++++++++++++++++++
71893eb
 drivers/gpu/drm/drm_dp_mst_topology.c         |  3 +-
71893eb
 .../drm/i915/display/intel_display_types.h    |  1 +
71893eb
 drivers/gpu/drm/i915/display/intel_dp.c       | 11 ++--
71893eb
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  2 +-
71893eb
 drivers/gpu/drm/i915/display/intel_psr.c      |  2 +-
71893eb
 include/drm/drm_dp_helper.h                   | 11 +++-
71893eb
 7 files changed, 81 insertions(+), 10 deletions(-)
71893eb
71893eb
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
71893eb
index a5364b5192b8..9b2ea2ae0204 100644
71893eb
--- a/drivers/gpu/drm/drm_dp_helper.c
71893eb
+++ b/drivers/gpu/drm/drm_dp_helper.c
71893eb
@@ -1222,6 +1222,67 @@ drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch)
71893eb
 #undef DEVICE_ID_ANY
71893eb
 #undef DEVICE_ID
71893eb
 
71893eb
+struct edid_quirk {
71893eb
+	u8 mfg_id[2];
71893eb
+	u8 prod_id[2];
71893eb
+	u32 quirks;
71893eb
+};
71893eb
+
71893eb
+#define MFG(first, second) { (first), (second) }
71893eb
+#define PROD_ID(first, second) { (first), (second) }
71893eb
+
71893eb
+/*
71893eb
+ * Some devices have unreliable OUIDs where they don't set the device ID
71893eb
+ * correctly, and as a result we need to use the EDID for finding additional
71893eb
+ * DP quirks in such cases.
71893eb
+ */
71893eb
+static const struct edid_quirk edid_quirk_list[] = {
71893eb
+};
71893eb
+
71893eb
+#undef MFG
71893eb
+#undef PROD_ID
71893eb
+
71893eb
+/**
71893eb
+ * drm_dp_get_edid_quirks() - Check the EDID of a DP device to find additional
71893eb
+ * DP-specific quirks
71893eb
+ * @edid: The EDID to check
71893eb
+ *
71893eb
+ * While OUIDs are meant to be used to recognize a DisplayPort device, a lot
71893eb
+ * of manufacturers don't seem to like following standards and neglect to fill
71893eb
+ * the dev-ID in, making it impossible to only use OUIDs for determining
71893eb
+ * quirks in some cases. This function can be used to check the EDID and look
71893eb
+ * up any additional DP quirks. The bits returned by this function correspond
71893eb
+ * to the quirk bits in &drm_dp_quirk.
71893eb
+ *
71893eb
+ * Returns: a bitmask of quirks, if any. The driver can check this using
71893eb
+ * drm_dp_has_quirk().
71893eb
+ */
71893eb
+u32 drm_dp_get_edid_quirks(const struct edid *edid)
71893eb
+{
71893eb
+	const struct edid_quirk *quirk;
71893eb
+	u32 quirks = 0;
71893eb
+	int i;
71893eb
+
71893eb
+	if (!edid)
71893eb
+		return 0;
71893eb
+
71893eb
+	for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
71893eb
+		quirk = &edid_quirk_list[i];
71893eb
+		if (memcmp(quirk->mfg_id, edid->mfg_id,
71893eb
+			   sizeof(edid->mfg_id)) == 0 &&
71893eb
+		    memcmp(quirk->prod_id, edid->prod_code,
71893eb
+			   sizeof(edid->prod_code)) == 0)
71893eb
+			quirks |= quirk->quirks;
71893eb
+	}
71893eb
+
71893eb
+	DRM_DEBUG_KMS("DP sink: EDID mfg %*phD prod-ID %*phD quirks: 0x%04x\n",
71893eb
+		      (int)sizeof(edid->mfg_id), edid->mfg_id,
71893eb
+		      (int)sizeof(edid->prod_code), edid->prod_code, quirks);
71893eb
+
71893eb
+	return quirks;
71893eb
+}
71893eb
+EXPORT_SYMBOL(drm_dp_get_edid_quirks);
71893eb
+
71893eb
 /**
71893eb
  * drm_dp_read_desc - read sink/branch descriptor from DPCD
71893eb
  * @aux: DisplayPort AUX channel
71893eb
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
71893eb
index cce0b1bba591..685c35e67144 100644
71893eb
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
71893eb
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
71893eb
@@ -5461,7 +5461,8 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
71893eb
 	if (drm_dp_read_desc(port->mgr->aux, &desc, true))
71893eb
 		return NULL;
71893eb
 
71893eb
-	if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
71893eb
+	if (drm_dp_has_quirk(&desc, 0,
71893eb
+			     DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
71893eb
 	    port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
71893eb
 	    port->parent == port->mgr->mst_primary) {
71893eb
 		u8 downstreamport;
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
index 778bd30743e5..8e3c5569603b 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
71893eb
@@ -1253,6 +1253,7 @@ struct intel_dp {
71893eb
 	int max_link_rate;
71893eb
 	/* sink or branch descriptor */
71893eb
 	struct drm_dp_desc desc;
71893eb
+	u32 edid_quirks;
71893eb
 	struct drm_dp_aux aux;
71893eb
 	u32 aux_busy_last_status;
71893eb
 	u8 train_set[4];
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
71893eb
index c7424e2a04a3..e20b85ff937d 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
71893eb
@@ -2373,7 +2373,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
71893eb
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
71893eb
 	struct intel_digital_connector_state *intel_conn_state =
71893eb
 		to_intel_digital_connector_state(conn_state);
71893eb
-	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
71893eb
+	bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 0,
71893eb
 					   DP_DPCD_QUIRK_CONSTANT_N);
71893eb
 	int ret = 0, output_bpp;
71893eb
 
71893eb
@@ -4466,7 +4466,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
71893eb
 	 * it don't care about read it here and in intel_edp_init_dpcd().
71893eb
 	 */
71893eb
 	if (!intel_dp_is_edp(intel_dp) &&
71893eb
-	    !drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_SINK_COUNT)) {
71893eb
+	    !drm_dp_has_quirk(&intel_dp->desc, 0,
71893eb
+			      DP_DPCD_QUIRK_NO_SINK_COUNT)) {
71893eb
 		u8 count;
71893eb
 		ssize_t r;
71893eb
 
71893eb
@@ -5631,6 +5632,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
71893eb
 
71893eb
 	intel_dp->has_audio = drm_detect_monitor_audio(edid);
71893eb
 	drm_dp_cec_set_edid(&intel_dp->aux, edid);
71893eb
+	intel_dp->edid_quirks = drm_dp_get_edid_quirks(edid);
71893eb
 }
71893eb
 
71893eb
 static void
71893eb
@@ -5643,6 +5645,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
71893eb
 	intel_connector->detect_edid = NULL;
71893eb
 
71893eb
 	intel_dp->has_audio = false;
71893eb
+	intel_dp->edid_quirks = 0;
71893eb
 }
71893eb
 
71893eb
 static int
71893eb
@@ -7356,8 +7359,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
71893eb
 	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
71893eb
 	if (edid) {
71893eb
 		if (drm_add_edid_modes(connector, edid)) {
71893eb
-			drm_connector_update_edid_property(connector,
71893eb
-								edid);
71893eb
+			drm_connector_update_edid_property(connector, edid);
71893eb
+			intel_dp->edid_quirks = drm_dp_get_edid_quirks(edid);
71893eb
 		} else {
71893eb
 			kfree(edid);
71893eb
 			edid = ERR_PTR(-EINVAL);
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
71893eb
index cba68c5a80fa..4a1a2f868423 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
71893eb
@@ -50,7 +50,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
71893eb
 	const struct drm_display_mode *adjusted_mode =
71893eb
 		&crtc_state->hw.adjusted_mode;
71893eb
 	void *port = connector->port;
71893eb
-	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
71893eb
+	bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 0,
71893eb
 					   DP_DPCD_QUIRK_CONSTANT_N);
71893eb
 	int bpp, slots = -EINVAL;
71893eb
 
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
71893eb
index 83025052c965..82ba5624d14f 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_psr.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
71893eb
@@ -282,7 +282,7 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
71893eb
 	DRM_DEBUG_KMS("eDP panel supports PSR version %x\n",
71893eb
 		      intel_dp->psr_dpcd[0]);
71893eb
 
71893eb
-	if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
71893eb
+	if (drm_dp_has_quirk(&intel_dp->desc, 0, DP_DPCD_QUIRK_NO_PSR)) {
71893eb
 		DRM_DEBUG_KMS("PSR support not currently available for this panel\n");
71893eb
 		return;
71893eb
 	}
71893eb
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
71893eb
index bc04467f7c3a..1fe49e202dfb 100644
71893eb
--- a/include/drm/drm_dp_helper.h
71893eb
+++ b/include/drm/drm_dp_helper.h
71893eb
@@ -1493,13 +1493,16 @@ struct drm_dp_desc {
71893eb
 
71893eb
 int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
71893eb
 		     bool is_branch);
71893eb
+u32 drm_dp_get_edid_quirks(const struct edid *edid);
71893eb
 
71893eb
 /**
71893eb
  * enum drm_dp_quirk - Display Port sink/branch device specific quirks
71893eb
  *
71893eb
  * Display Port sink and branch devices in the wild have a variety of bugs, try
71893eb
  * to collect them here. The quirks are shared, but it's up to the drivers to
71893eb
- * implement workarounds for them.
71893eb
+ * implement workarounds for them. Note that because some devices have
71893eb
+ * unreliable OUIDs, the EDID of sinks should also be checked for quirks using
71893eb
+ * drm_dp_get_edid_quirks().
71893eb
  */
71893eb
 enum drm_dp_quirk {
71893eb
 	/**
71893eb
@@ -1535,14 +1538,16 @@ enum drm_dp_quirk {
71893eb
 /**
71893eb
  * drm_dp_has_quirk() - does the DP device have a specific quirk
71893eb
  * @desc: Device decriptor filled by drm_dp_read_desc()
71893eb
+ * @edid_quirks: Optional quirk bitmask filled by drm_dp_get_edid_quirks()
71893eb
  * @quirk: Quirk to query for
71893eb
  *
71893eb
  * Return true if DP device identified by @desc has @quirk.
71893eb
  */
71893eb
 static inline bool
71893eb
-drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)
71893eb
+drm_dp_has_quirk(const struct drm_dp_desc *desc, u32 edid_quirks,
71893eb
+		 enum drm_dp_quirk quirk)
71893eb
 {
71893eb
-	return desc->quirks & BIT(quirk);
71893eb
+	return (desc->quirks | edid_quirks) & BIT(quirk);
71893eb
 }
71893eb
 
71893eb
 #ifdef CONFIG_DRM_DP_CEC
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From a21ec8aec8452de788d6b1fc175dc8281a57d5de Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:36 -0400
71893eb
Subject: [PATCH 6/7] drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen
71893eb
 4K AMOLED panel
71893eb
71893eb
The X1 Extreme is one of the systems that lies about which backlight
71893eb
interface that it uses in its VBIOS as PWM backlight controls don't work
71893eb
at all on this machine. It's possible that this panel could be one of
71893eb
the infamous ones that can switch between PWM mode and DPCD backlight
71893eb
control mode, but we haven't gotten any more details on this from Lenovo
71893eb
just yet. For the time being though, making sure the backlight 'just
71893eb
works' is a bit more important.
71893eb
71893eb
So, add a quirk to force DPCD backlight controls on for these systems
71893eb
based on EDID (since this panel doesn't appear to fill in the device ID).
71893eb
Hopefully in the future we'll figure out a better way of probing this.
71893eb
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Reviewed-by: Adam Jackson <ajax@redhat.com>
71893eb
Cc: Jani Nikula <jani.nikula@intel.com>
71893eb
71893eb
Changes since v2:
71893eb
* The bugzilla URL is deprecated, bug reporting happens on gitlab now.
71893eb
  Update the messages we print to reflect this
71893eb
* Also, take the opportunity to move FDO_BUG_URL out of i915_utils.c and
71893eb
  into i915_utils.h so that other places which print things that aren't
71893eb
  traditional errors but are worth filing bugs about, can actually use
71893eb
  it.
71893eb
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
---
71893eb
 drivers/gpu/drm/drm_dp_helper.c               |  4 ++++
71893eb
 .../drm/i915/display/intel_dp_aux_backlight.c | 24 +++++++++++++++----
71893eb
 drivers/gpu/drm/i915/i915_utils.c             |  1 -
71893eb
 drivers/gpu/drm/i915/i915_utils.h             |  2 ++
71893eb
 include/drm/drm_dp_helper.h                   | 10 ++++++++
71893eb
 5 files changed, 36 insertions(+), 5 deletions(-)
71893eb
71893eb
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
71893eb
index 9b2ea2ae0204..026f701eac69 100644
71893eb
--- a/drivers/gpu/drm/drm_dp_helper.c
71893eb
+++ b/drivers/gpu/drm/drm_dp_helper.c
71893eb
@@ -1237,6 +1237,10 @@ struct edid_quirk {
71893eb
  * DP quirks in such cases.
71893eb
  */
71893eb
 static const struct edid_quirk edid_quirk_list[] = {
71893eb
+	/* Optional 4K AMOLED panel in the ThinkPad X1 Extreme 2nd Generation
71893eb
+	 * only supports DPCD backlight controls
71893eb
+	 */
71893eb
+	{ MFG(0x4c, 0x83), PROD_ID(0x41, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
 };
71893eb
 
71893eb
 #undef MFG
71893eb
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
index 77a759361c5c..a7c94c201b38 100644
71893eb
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
71893eb
@@ -328,15 +328,31 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector)
71893eb
 int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
71893eb
 {
71893eb
 	struct intel_panel *panel = &intel_connector->panel;
71893eb
-	struct drm_i915_private *dev_priv = to_i915(intel_connector->base.dev);
71893eb
+	struct intel_dp *intel_dp = enc_to_intel_dp(intel_connector->encoder);
71893eb
+	struct drm_device *dev = intel_connector->base.dev;
71893eb
+	struct drm_i915_private *dev_priv = to_i915(dev);
71893eb
 
71893eb
 	if (i915_modparams.enable_dpcd_backlight == 0 ||
71893eb
-	    (i915_modparams.enable_dpcd_backlight == -1 &&
71893eb
-	    dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE))
71893eb
+	    !intel_dp_aux_display_control_capable(intel_connector))
71893eb
 		return -ENODEV;
71893eb
 
71893eb
-	if (!intel_dp_aux_display_control_capable(intel_connector))
71893eb
+	/*
71893eb
+	 * There are a lot of machines that don't advertise the backlight
71893eb
+	 * control interface to use properly in their VBIOS, :\
71893eb
+	 */
71893eb
+	if (dev_priv->vbt.backlight.type !=
71893eb
+	    INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE &&
71893eb
+	    !drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks,
71893eb
+			      DP_QUIRK_FORCE_DPCD_BACKLIGHT)) {
71893eb
+		DRM_DEV_INFO(dev->dev,
71893eb
+			     "Panel advertises DPCD backlight support, but "
71893eb
+			     "VBT disagrees. If your backlight controls "
71893eb
+			     "don't work try booting with "
71893eb
+			     "i915.enable_dpcd_backlight=1. If your machine "
71893eb
+			     "needs this, please file a _new_ bug report on "
71893eb
+			     "drm/i915, see " FDO_BUG_URL " for details.\n");
71893eb
 		return -ENODEV;
71893eb
+	}
71893eb
 
71893eb
 	panel->backlight.setup = intel_dp_aux_setup_backlight;
71893eb
 	panel->backlight.enable = intel_dp_aux_enable_backlight;
71893eb
diff --git a/drivers/gpu/drm/i915/i915_utils.c b/drivers/gpu/drm/i915/i915_utils.c
71893eb
index 632d6953c78d..029854ae65fc 100644
71893eb
--- a/drivers/gpu/drm/i915/i915_utils.c
71893eb
+++ b/drivers/gpu/drm/i915/i915_utils.c
71893eb
@@ -8,7 +8,6 @@
71893eb
 #include "i915_drv.h"
71893eb
 #include "i915_utils.h"
71893eb
 
71893eb
-#define FDO_BUG_URL "https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs"
71893eb
 #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details."
71893eb
 
71893eb
 void
71893eb
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
71893eb
index b0ade76bec90..cae0ae520398 100644
71893eb
--- a/drivers/gpu/drm/i915/i915_utils.h
71893eb
+++ b/drivers/gpu/drm/i915/i915_utils.h
71893eb
@@ -34,6 +34,8 @@
71893eb
 struct drm_i915_private;
71893eb
 struct timer_list;
71893eb
 
71893eb
+#define FDO_BUG_URL "https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs"
71893eb
+
71893eb
 #undef WARN_ON
71893eb
 /* Many gcc seem to no see through this and fall over :( */
71893eb
 #if 0
71893eb
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
71893eb
index 1fe49e202dfb..eff5a69051d6 100644
71893eb
--- a/include/drm/drm_dp_helper.h
71893eb
+++ b/include/drm/drm_dp_helper.h
71893eb
@@ -1533,6 +1533,16 @@ enum drm_dp_quirk {
71893eb
 	 * The DSC caps can be read from the physical aux instead.
71893eb
 	 */
71893eb
 	DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD,
71893eb
+	/**
71893eb
+	 * @DP_QUIRK_FORCE_DPCD_BACKLIGHT:
71893eb
+	 *
71893eb
+	 * The device is telling the truth when it says that it uses DPCD
71893eb
+	 * backlight controls, even if the system's firmware disagrees. This
71893eb
+	 * quirk should be checked against both the ident and panel EDID.
71893eb
+	 * When present, the driver should honor the DPCD backlight
71893eb
+	 * capabilities advertised.
71893eb
+	 */
71893eb
+	DP_QUIRK_FORCE_DPCD_BACKLIGHT,
71893eb
 };
71893eb
 
71893eb
 /**
71893eb
-- 
71893eb
2.25.1
71893eb
71893eb
From 057e7f8db05c2382b666270b1fbf986fdd172769 Mon Sep 17 00:00:00 2001
71893eb
From: Lyude Paul <lyude@redhat.com>
71893eb
Date: Tue, 10 Mar 2020 14:07:37 -0400
71893eb
Subject: [PATCH 7/7] drm/i915: Force DPCD backlight mode for some Dell CML
71893eb
 2020 panels
71893eb
71893eb
According to Dell, trying to match their panels via OUI is not reliable
71893eb
enough and we've been told that we should check against the EDID
71893eb
instead. As well, Dell seems to have some panels that are actually
71893eb
intended to switch between using PWM for backlight controls and DPCD for
71893eb
backlight controls depending on whether or not the panel is in HDR or
71893eb
SDR mode. Yikes.
71893eb
71893eb
Regardless, we need to add quirks for these so that DPCD backlight
71893eb
controls get enabled by default, since without additional driver support
71893eb
that's the only form of brightness control that will work. Hopefully in
71893eb
the future we can remove these quirks once we have a better way of
71893eb
probing for this.
71893eb
71893eb
Changes since v1:
71893eb
* Add one more EDID per Dell's request
71893eb
* Remove model number (which is possibly wrong) and replace with Dell
71893eb
  CML 2020 systems
71893eb
71893eb
Signed-off-by: Lyude Paul <lyude@redhat.com>
71893eb
Reviewed-by: Adam Jackson <ajax@redhat.com>
71893eb
Cc: Jani Nikula <jani.nikula@intel.com>
71893eb
---
71893eb
 drivers/gpu/drm/drm_dp_helper.c | 14 ++++++++++++++
71893eb
 1 file changed, 14 insertions(+)
71893eb
71893eb
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
71893eb
index 026f701eac69..d3a636a925d4 100644
71893eb
--- a/drivers/gpu/drm/drm_dp_helper.c
71893eb
+++ b/drivers/gpu/drm/drm_dp_helper.c
71893eb
@@ -1241,6 +1241,20 @@ static const struct edid_quirk edid_quirk_list[] = {
71893eb
 	 * only supports DPCD backlight controls
71893eb
 	 */
71893eb
 	{ MFG(0x4c, 0x83), PROD_ID(0x41, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
+	/*
71893eb
+	 * Some Dell CML 2020 systems have panels support both AUX and PWM
71893eb
+	 * backlight control, and some only support AUX backlight control. All
71893eb
+	 * said panels start up in AUX mode by default, and we don't have any
71893eb
+	 * support for disabling HDR mode on these panels which would be
71893eb
+	 * required to switch to PWM backlight control mode (plus, I'm not
71893eb
+	 * even sure we want PWM backlight controls over DPCD backlight
71893eb
+	 * controls anyway...). Until we have a better way of detecting these,
71893eb
+	 * force DPCD backlight mode on all of them.
71893eb
+	 */
71893eb
+	{ MFG(0x06, 0xaf), PROD_ID(0x9b, 0x32), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
+	{ MFG(0x06, 0xaf), PROD_ID(0xeb, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
+	{ MFG(0x4d, 0x10), PROD_ID(0xc7, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
+	{ MFG(0x4d, 0x10), PROD_ID(0xe6, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
71893eb
 };
71893eb
 
71893eb
 #undef MFG
71893eb
-- 
71893eb
2.25.1
71893eb