diff options
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-.patch | 582 |
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 - |