summarylogtreecommitdiffstats
path: root/0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch
diff options
context:
space:
mode:
Diffstat (limited to '0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch')
-rw-r--r--0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch582
1 files changed, 0 insertions, 582 deletions
diff --git a/0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch b/0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch
deleted file mode 100644
index 897574812eef..000000000000
--- a/0002-WIP-drm-i915-Enable-Intel-s-HDR-backlight-interface-.patch
+++ /dev/null
@@ -1,582 +0,0 @@
-From 773c5f1b32519fca04ad446f1cf02e717fb2a7d9 Mon Sep 17 00:00:00 2001
-From: Lyude Paul <lyude@redhat.com>
-Date: Mon, 29 Jun 2020 15:01:49 -0400
-Subject: [PATCH 2/2] WIP: drm/i915: Enable Intel's HDR backlight interface
- (only SDR for now)
-
-So-recently a bunch of laptops on the market have started using DPCD
-backlight controls instead of the traditional DDI backlight controls.
-Originally we thought we had this handled by adding VESA backlight
-control support to i915, but the story ended up being a lot more
-complicated then that.
-
-Simply put-there's two main backlight interfaces Intel can see in the
-wild. Intel's proprietary HDR backlight interface, and the standard VESA
-backlight interface. Note that many panels have been observed to report
-support for both backlight interfaces, but testing has shown far more
-panels work with the Intel HDR backlight interface at the moment.
-Additionally, the VBT appears to be capable of reporting support for the
-VESA backlight interface but not the Intel HDR interface which needs to
-be probed by setting the right magic OUI.
-
-For the time being we've been using EDIDs to maintain a list of quirks
-for panels that safely do support the VESA backlight interface. Adding
-support for Intel's HDR backlight interface in addition however, should
-finally allow us to auto-detect eDP backlight controls properly so long
-as we probe like so:
-
-* If the panel's VBT reports VESA backlight support, assume it really
- does support it
-* If the panel's VBT reports DDI backlight controls:
- * First probe for Intel's HDR backlight interface
- * If that fails, probe for VESA's backlight interface
- * If that fails, assume no DPCD backlight control
-* If the panel's VBT reports any other backlight type: just assume it
- doesn't have DPCD backlight controls
-
-Note as well that in order for us to make Intel's HDR backlight
-interface appear, we need to start programming the appropriate source
-OUI on the eDP panel as early as possible in the probing process. Note
-that this technically could be done at any time before setting up
-backlight controls, but this way allows us to avoid re-writing it
-multiple times in case we need to use other source-OUI enabled features
-in the future.
-
-Finally, we also make sure to document the registers for this backlight
-interface since eventually, we want to actually implement the full
-interface instead of keeping it in SDR mode.
-
-Signed-off-by: Lyude Paul <lyude@redhat.com>
----
- .../drm/i915/display/intel_display_types.h | 9 +-
- drivers/gpu/drm/i915/display/intel_dp.c | 14 +
- .../drm/i915/display/intel_dp_aux_backlight.c | 332 +++++++++++++++---
- drivers/gpu/drm/i915/i915_params.c | 2 +-
- 4 files changed, 307 insertions(+), 50 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
-index e8f809161c75..a2f54d308187 100644
---- a/drivers/gpu/drm/i915/display/intel_display_types.h
-+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
-@@ -225,7 +225,14 @@ struct intel_panel {
- struct pwm_device *pwm;
-
- /* DPCD backlight */
-- u8 pwmgen_bit_count;
-+ union {
-+ struct {
-+ u8 pwmgen_bit_count;
-+ } vesa;
-+ struct {
-+
-+ } intel;
-+ } edp;
-
- struct backlight_device *device;
-
-diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
-index 39667264c27d..47f04cbbeb0f 100644
---- a/drivers/gpu/drm/i915/display/intel_dp.c
-+++ b/drivers/gpu/drm/i915/display/intel_dp.c
-@@ -3396,7 +3396,9 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
- void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
- {
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
- int ret, i;
-+ u8 edp_oui[] = { 0x00, 0xaa, 0x01 };
-
- /* Should have a valid DPCD by this point */
- if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
-@@ -3411,6 +3413,16 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
- } else {
- struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
-
-+ /* Write the source OUI as early as possible */
-+ if (intel_dp_is_edp(intel_dp)) {
-+ ret = drm_dp_dpcd_write(&intel_dp->aux,
-+ DP_SOURCE_OUI, edp_oui,
-+ sizeof(edp_oui));
-+ if (ret < 0)
-+ drm_err(&i915->drm,
-+ "Failed to write eDP source OUI\n");
-+ }
-+
- /*
- * When turning on, we need to retry for 1ms to give the sink
- * time to wake up.
-@@ -4554,6 +4566,8 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
- }
- }
-
-+
-+
- static void
- intel_edp_init_source_oui(struct intel_dp *intel_dp)
- {
-diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
-index acbd7eb66cbe..1b114ee930d9 100644
---- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
-+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
-@@ -22,10 +22,196 @@
- *
- */
-
-+/* XXX: maybe make this kernel docs */
-+/*
-+ * Laptops with Intel GPUs which have panels that support controlling the
-+ * backlight through DP AUX can actually use two different interfaces: Intel's
-+ * proprietary DP AUX backlight interface, and the standard VESA backlight
-+ * interface. Unfortunately, at the time of writing this a lot of laptops will
-+ * advertise support for the standard VESA backlight interface when they
-+ * don't properly support it. However, on these systems the Intel backlight
-+ * interface generally does work properly. Additionally, these systems will
-+ * usually just indicate that they use PWM backlight controls in their VBIOS
-+ * for some reason.
-+ */
-+
- #include "intel_display_types.h"
- #include "intel_dp_aux_backlight.h"
-
--static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
-+/*
-+ * DP AUX registers for Intel's proprietary HDR backlight interface. We define
-+ * them here since we'll likely be the only driver to ever use these.
-+ */
-+#define INTEL_EDP_HDR_TCON_CAP0 0x340
-+
-+#define INTEL_EDP_HDR_TCON_CAP1 0x341
-+# define INTEL_EDP_HDR_TCON_2084_DECODE_CAP BIT(0)
-+# define INTEL_EDP_HDR_TCON_2020_GAMUT_CAP BIT(1)
-+# define INTEL_EDP_HDR_TCON_TONE_MAPPING_CAP BIT(2)
-+# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_CAP BIT(3)
-+# define INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP BIT(4)
-+# define INTEL_EDP_HDR_TCON_OPTIMIZATION_CAP BIT(5)
-+# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_CAP BIT(6)
-+# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_CONVERSION_CAP BIT(7)
-+
-+#define INTEL_EDP_HDR_TCON_CAP2 0x342
-+# define INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP BIT(0)
-+
-+#define INTEL_EDP_HDR_TCON_CAP3 0x343
-+
-+#define INTEL_EDP_HDR_GETSET_CTRL_PARAMS 0x344
-+# define INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE BIT(0)
-+# define INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE BIT(1)
-+# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE BIT(2) /* Pre-TGL+ */
-+# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE BIT(3)
-+# define INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE BIT(4)
-+# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_ENABLE BIT(5)
-+/* Bit 6 is reserved */
-+# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_ENABLE BIT(7)
-+
-+#define INTEL_EDP_HDR_CONTENT_LUMINANCE 0x346 /* Pre-TGL+ */
-+#define INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE 0x34A
-+#define INTEL_EDP_SDR_LUMINANCE_LEVEL 0x352
-+#define INTEL_EDP_BRIGHTNESS_NITS_LSB 0x354
-+#define INTEL_EDP_BRIGHTNESS_NITS_MSB 0x355
-+#define INTEL_EDP_BRIGHTNESS_DELAY_FRAMES 0x356
-+#define INTEL_EDP_BRIGHTNESS_PER_FRAME_STEPS 0x357
-+
-+#define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_0 0x358
-+# define INTEL_EDP_TCON_USAGE_MASK GENMASK(0, 3)
-+# define INTEL_EDP_TCON_USAGE_UNKNOWN 0x0
-+# define INTEL_EDP_TCON_USAGE_DESKTOP 0x1
-+# define INTEL_EDP_TCON_USAGE_FULL_SCREEN_MEDIA 0x2
-+# define INTEL_EDP_TCON_USAGE_FULL_SCREEN_GAMING 0x3
-+# define INTEL_EDP_TCON_POWER_MASK BIT(4)
-+# define INTEL_EDP_TCON_POWER_DC (0 << 4)
-+# define INTEL_EDP_TCON_POWER_AC (1 << 4)
-+# define INTEL_EDP_TCON_OPTIMIZATION_STRENGTH_MASK GENMASK(5, 7)
-+
-+#define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_1 0x359
-+
-+/* Intel EDP backlight callbacks */
-+static bool
-+intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
-+{
-+ struct drm_device *dev = connector->base.dev;
-+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
-+ struct drm_dp_aux *aux = &intel_dp->aux;
-+ int ret;
-+ u8 tcon_cap[4];
-+
-+ ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0,
-+ tcon_cap, sizeof(tcon_cap));
-+ if (ret < 0)
-+ return false;
-+
-+ if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
-+ return false;
-+
-+ /* TODO: Add support for AUX backlight controls in HDR mode */
-+ if (!(tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP)) {
-+ DRM_DEV_DEBUG_KMS(dev->dev,
-+ "Panel only supports AUX backlight controls for HDR mode, this isn't implemented yet\n");
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static u32
-+intel_dp_aux_hdr_get_backlight(struct intel_connector *connector)
-+{
-+ struct drm_device *dev = connector->base.dev;
-+ struct intel_panel *panel = &connector->panel;
-+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
-+ u8 tmp;
-+ u8 buf[2] = { 0 };
-+
-+ if (drm_dp_dpcd_readb(&intel_dp->aux,
-+ INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp) < 0)
-+ DRM_DEV_DEBUG_KMS(dev->dev,
-+ "Failed to read current backlight mode from DPCD\n");
-+
-+ /* Assume 100% brightness if backlight controls aren't enabled over
-+ * AUX yet
-+ */
-+ if (!(tmp & INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE))
-+ return panel->backlight.max;
-+
-+ if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB,
-+ buf, sizeof(buf)) < 0) {
-+ DRM_DEV_DEBUG_KMS(dev->dev,
-+ "Failed to read brightness from DPCD\n");
-+ return 0;
-+ }
-+
-+ return (buf[1] << 8 | buf[0]);
-+}
-+
-+static void
-+intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state,
-+ u32 level)
-+{
-+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
-+ struct drm_device *dev = connector->base.dev;
-+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
-+ uint8_t buf[4] = { 0 };
-+
-+ buf[0] = level & 0xFF;
-+ buf[1] = (level & 0xFF00) >> 8;
-+
-+ if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB,
-+ buf, 4) < 0)
-+ DRM_DEV_DEBUG_KMS(dev->dev,
-+ "Failed to write brightness level to DPCD\n");
-+}
-+
-+static void
-+intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
-+ const struct drm_connector_state *conn_state)
-+{
-+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
-+ struct intel_panel *panel = &connector->panel;
-+ struct drm_device *dev = connector->base.dev;
-+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
-+
-+ /* FIXME: figure out if we really need to clear the register
-+ * beforehand, ideally we want to avoid turning the backlight off when
-+ * it's not needed
-+ */
-+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
-+ INTEL_EDP_HDR_GETSET_CTRL_PARAMS,
-+ INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE) < 0)
-+ drm_err(dev, "Failed to enable AUX brightness control\n");
-+
-+ intel_dp_aux_hdr_set_backlight(conn_state, panel->backlight.level);
-+ /* FIXME: do we need to write the brightness level before or after we
-+ * enable the relevant brightness modes?
-+ */
-+}
-+
-+static void
-+intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *old_conn_state)
-+{
-+ /* no-op */
-+}
-+
-+static int
-+intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector,
-+ enum pipe pipe)
-+{
-+ struct intel_panel *panel = &connector->panel;
-+
-+ panel->backlight.max = 512;
-+ panel->backlight.min = 0;
-+ panel->backlight.level = intel_dp_aux_hdr_get_backlight(connector);
-+ panel->backlight.enabled = panel->backlight.level != 0;
-+
-+ return 0;
-+}
-+
-+/* VESA backlight callbacks */
-+static void set_vesa_backlight_enable(struct intel_dp *intel_dp, bool enable)
- {
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 reg_val = 0;
-@@ -56,7 +242,7 @@ static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
- * Read the current backlight value from DPCD register(s) based
- * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported
- */
--static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
-+static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector)
- {
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-@@ -99,7 +285,7 @@ static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
- * 8-bit or 16 bit value (MSB and LSB)
- */
- static void
--intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 level)
-+intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level)
- {
- struct intel_connector *connector = to_intel_connector(conn_state->connector);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
-@@ -129,11 +315,11 @@ intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 lev
- * - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
- * EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
- */
--static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
-+static bool intel_dp_aux_vesa_set_pwm_freq(struct intel_connector *connector)
- {
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
-- const u8 pn = connector->panel.backlight.pwmgen_bit_count;
-+ const u8 pn = connector->panel.backlight.edp.vesa.pwmgen_bit_count;
- int freq, fxp, f, fxp_actual, fxp_min, fxp_max;
-
- freq = dev_priv->vbt.backlight.pwm_freq_hz;
-@@ -165,14 +351,15 @@ static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
- return true;
- }
-
--static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_state,
-- const struct drm_connector_state *conn_state)
-+static void intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
-+ const struct drm_connector_state *conn_state)
- {
- struct intel_connector *connector = to_intel_connector(conn_state->connector);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- struct intel_panel *panel = &connector->panel;
- u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode;
-+ u8 pwmgen_bit_count = panel->backlight.edp.vesa.pwmgen_bit_count;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf) != 1) {
-@@ -193,7 +380,7 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
-
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_PWMGEN_BIT_COUNT,
-- panel->backlight.pwmgen_bit_count) < 0)
-+ pwmgen_bit_count) < 0)
- drm_dbg_kms(&i915->drm,
- "Failed to write aux pwmgen bit count\n");
-
-@@ -206,7 +393,7 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
- }
-
- if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
-- if (intel_dp_aux_set_pwm_freq(connector))
-+ if (intel_dp_aux_vesa_set_pwm_freq(connector))
- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
-
- if (new_dpcd_buf != dpcd_buf) {
-@@ -217,18 +404,18 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
- }
- }
-
-- intel_dp_aux_set_backlight(conn_state,
-- connector->panel.backlight.level);
-- set_aux_backlight_enable(intel_dp, true);
-+ intel_dp_aux_vesa_set_backlight(conn_state,
-+ connector->panel.backlight.level);
-+ set_vesa_backlight_enable(intel_dp, true);
- }
-
--static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old_conn_state)
-+static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state *old_conn_state)
- {
-- set_aux_backlight_enable(enc_to_intel_dp(to_intel_encoder(old_conn_state->best_encoder)),
-- false);
-+ set_vesa_backlight_enable(enc_to_intel_dp(to_intel_encoder(old_conn_state->best_encoder)),
-+ false);
- }
-
--static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
-+static u32 intel_dp_aux_vesa_calc_max_backlight(struct intel_connector *connector)
- {
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
-@@ -301,31 +488,31 @@ static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
- "Failed to write aux pwmgen bit count\n");
- return max_backlight;
- }
-- panel->backlight.pwmgen_bit_count = pn;
-+ panel->backlight.edp.vesa.pwmgen_bit_count = pn;
-
- max_backlight = (1 << pn) - 1;
-
- return max_backlight;
- }
-
--static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
-- enum pipe pipe)
-+static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
-+ enum pipe pipe)
- {
- struct intel_panel *panel = &connector->panel;
-
-- panel->backlight.max = intel_dp_aux_calc_max_backlight(connector);
-+ panel->backlight.max = intel_dp_aux_vesa_calc_max_backlight(connector);
- if (!panel->backlight.max)
- return -ENODEV;
-
- panel->backlight.min = 0;
-- panel->backlight.level = intel_dp_aux_get_backlight(connector);
-+ panel->backlight.level = intel_dp_aux_vesa_get_backlight(connector);
- panel->backlight.enabled = panel->backlight.level != 0;
-
- return 0;
- }
-
- static bool
--intel_dp_aux_display_control_capable(struct intel_connector *connector)
-+intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
- {
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-@@ -342,40 +529,89 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector)
- return false;
- }
-
--int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
-+enum intel_dp_aux_backlight_modparam {
-+ INTEL_DP_AUX_BACKLIGHT_AUTO = -1,
-+ INTEL_DP_AUX_BACKLIGHT_OFF = 0,
-+ INTEL_DP_AUX_BACKLIGHT_ON = 1,
-+ INTEL_DP_AUX_BACKLIGHT_FORCE_VESA = 2,
-+ INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL = 3,
-+};
-+
-+int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
- {
-- struct intel_panel *panel = &intel_connector->panel;
-- struct intel_dp *intel_dp = enc_to_intel_dp(intel_connector->encoder);
-+ struct drm_device *dev = connector->base.dev;
-+ struct intel_panel *panel = &connector->panel;
-+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-+ bool try_intel_interface = false, try_vesa_interface = false;
-
-- if (i915->params.enable_dpcd_backlight == 0 ||
-- !intel_dp_aux_display_control_capable(intel_connector))
-+ /* Check the VBT and user's module parameters to figure out which
-+ * interfaces to probe
-+ */
-+ switch (i915_modparams.enable_dpcd_backlight) {
-+ case INTEL_DP_AUX_BACKLIGHT_OFF:
- return -ENODEV;
-+ case INTEL_DP_AUX_BACKLIGHT_AUTO:
-+ switch (i915->vbt.backlight.type) {
-+ case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
-+ try_vesa_interface = true;
-+ break;
-+ case INTEL_BACKLIGHT_DISPLAY_DDI:
-+ try_intel_interface = true;
-+ try_vesa_interface = true;
-+ break;
-+ default:
-+ return -ENODEV;
-+ }
-+ break;
-+ case INTEL_DP_AUX_BACKLIGHT_ON:
-+ if (i915->vbt.backlight.type !=
-+ INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
-+ try_intel_interface = true;
-+
-+ try_vesa_interface = true;
-+ break;
-+ case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA:
-+ try_vesa_interface = true;
-+ break;
-+ case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL:
-+ try_intel_interface = true;
-+ break;
-+ }
-
- /*
-- * There are a lot of machines that don't advertise the backlight
-- * control interface to use properly in their VBIOS, :\
-+ * A lot of eDP panels in the wild will report supporting both the
-+ * Intel proprietary backlight control interface, and the VESA
-+ * backlight control interface. Many of these panels are liars though,
-+ * and will only work with the Intel interface. So, always probe for
-+ * that first.
- */
-- if (i915->vbt.backlight.type !=
-- INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE &&
-- i915->params.enable_dpcd_backlight != 1 &&
-- !drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks,
-- DP_QUIRK_FORCE_DPCD_BACKLIGHT)) {
-- drm_info(&i915->drm,
-- "Panel advertises DPCD backlight support, but "
-- "VBT disagrees. If your backlight controls "
-- "don't work try booting with "
-- "i915.enable_dpcd_backlight=1. If your machine "
-- "needs this, please file a _new_ bug report on "
-- "drm/i915, see " FDO_BUG_URL " for details.\n");
-- return -ENODEV;
-+ if (try_intel_interface &&
-+ intel_dp_aux_supports_hdr_backlight(connector)) {
-+ DRM_DEV_DEBUG_DRIVER(dev->dev,
-+ "Using Intel proprietary eDP backlight controls\n");
-+
-+ panel->backlight.setup = intel_dp_aux_hdr_setup_backlight;
-+ panel->backlight.enable = intel_dp_aux_hdr_enable_backlight;
-+ panel->backlight.disable = intel_dp_aux_hdr_disable_backlight;
-+ panel->backlight.set = intel_dp_aux_hdr_set_backlight;
-+ panel->backlight.get = intel_dp_aux_hdr_get_backlight;
-+
-+ return 0;
- }
-
-- panel->backlight.setup = intel_dp_aux_setup_backlight;
-- panel->backlight.enable = intel_dp_aux_enable_backlight;
-- panel->backlight.disable = intel_dp_aux_disable_backlight;
-- panel->backlight.set = intel_dp_aux_set_backlight;
-- panel->backlight.get = intel_dp_aux_get_backlight;
-+ if (try_vesa_interface &&
-+ intel_dp_aux_supports_vesa_backlight(connector)) {
-+ DRM_DEV_DEBUG_DRIVER(dev->dev,
-+ "Using VESA eDP backlight controls\n");
-+ panel->backlight.setup = intel_dp_aux_vesa_setup_backlight;
-+ panel->backlight.enable = intel_dp_aux_vesa_enable_backlight;
-+ panel->backlight.disable = intel_dp_aux_vesa_disable_backlight;
-+ panel->backlight.set = intel_dp_aux_vesa_set_backlight;
-+ panel->backlight.get = intel_dp_aux_vesa_get_backlight;
-
-- return 0;
-+ return 0;
-+ }
-+
-+ return -ENODEV;
- }
-diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
-index 8d8db9ff0a48..4420c86bc228 100644
---- a/drivers/gpu/drm/i915/i915_params.c
-+++ b/drivers/gpu/drm/i915/i915_params.c
-@@ -180,7 +180,7 @@ i915_param_named_unsafe(inject_probe_failure, uint, 0400,
-
- i915_param_named(enable_dpcd_backlight, int, 0400,
- "Enable support for DPCD backlight control"
-- "(-1=use per-VBT LFP backlight type setting [default], 0=disabled, 1=enabled)");
-+ "(-1=use per-VBT LFP backlight type setting [default], 0=disabled, 1=enable, 2=force VESA interface, 3=force Intel interface)");
-
- #if IS_ENABLED(CONFIG_DRM_I915_GVT)
- i915_param_named(enable_gvt, bool, 0400,
---
-2.28.0
-