Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2015 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0021  * IN THE SOFTWARE.
0022  *
0023  */
0024 
0025 /*
0026  * Laptops with Intel GPUs which have panels that support controlling the
0027  * backlight through DP AUX can actually use two different interfaces: Intel's
0028  * proprietary DP AUX backlight interface, and the standard VESA backlight
0029  * interface. Unfortunately, at the time of writing this a lot of laptops will
0030  * advertise support for the standard VESA backlight interface when they
0031  * don't properly support it. However, on these systems the Intel backlight
0032  * interface generally does work properly. Additionally, these systems will
0033  * usually just indicate that they use PWM backlight controls in their VBIOS
0034  * for some reason.
0035  */
0036 
0037 #include "i915_drv.h"
0038 #include "intel_backlight.h"
0039 #include "intel_display_types.h"
0040 #include "intel_dp.h"
0041 #include "intel_dp_aux_backlight.h"
0042 
0043 /* TODO:
0044  * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
0045  * can make people's backlights work in the mean time
0046  */
0047 
0048 /*
0049  * DP AUX registers for Intel's proprietary HDR backlight interface. We define
0050  * them here since we'll likely be the only driver to ever use these.
0051  */
0052 #define INTEL_EDP_HDR_TCON_CAP0                                        0x340
0053 
0054 #define INTEL_EDP_HDR_TCON_CAP1                                        0x341
0055 # define INTEL_EDP_HDR_TCON_2084_DECODE_CAP                           BIT(0)
0056 # define INTEL_EDP_HDR_TCON_2020_GAMUT_CAP                            BIT(1)
0057 # define INTEL_EDP_HDR_TCON_TONE_MAPPING_CAP                          BIT(2)
0058 # define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_CAP                   BIT(3)
0059 # define INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP                       BIT(4)
0060 # define INTEL_EDP_HDR_TCON_OPTIMIZATION_CAP                          BIT(5)
0061 # define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_CAP                       BIT(6)
0062 # define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_CONVERSION_CAP        BIT(7)
0063 
0064 #define INTEL_EDP_HDR_TCON_CAP2                                        0x342
0065 # define INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP                        BIT(0)
0066 
0067 #define INTEL_EDP_HDR_TCON_CAP3                                        0x343
0068 
0069 #define INTEL_EDP_HDR_GETSET_CTRL_PARAMS                               0x344
0070 # define INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE                        BIT(0)
0071 # define INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE                         BIT(1)
0072 # define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE                       BIT(2) /* Pre-TGL+ */
0073 # define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE                BIT(3)
0074 # define INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE                     BIT(4)
0075 # define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_ENABLE                BIT(5)
0076 /* Bit 6 is reserved */
0077 # define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_ENABLE                    BIT(7)
0078 
0079 #define INTEL_EDP_HDR_CONTENT_LUMINANCE                                0x346 /* Pre-TGL+ */
0080 #define INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE                         0x34A
0081 #define INTEL_EDP_SDR_LUMINANCE_LEVEL                                  0x352
0082 #define INTEL_EDP_BRIGHTNESS_NITS_LSB                                  0x354
0083 #define INTEL_EDP_BRIGHTNESS_NITS_MSB                                  0x355
0084 #define INTEL_EDP_BRIGHTNESS_DELAY_FRAMES                              0x356
0085 #define INTEL_EDP_BRIGHTNESS_PER_FRAME_STEPS                           0x357
0086 
0087 #define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_0                            0x358
0088 # define INTEL_EDP_TCON_USAGE_MASK                             GENMASK(0, 3)
0089 # define INTEL_EDP_TCON_USAGE_UNKNOWN                                    0x0
0090 # define INTEL_EDP_TCON_USAGE_DESKTOP                                    0x1
0091 # define INTEL_EDP_TCON_USAGE_FULL_SCREEN_MEDIA                          0x2
0092 # define INTEL_EDP_TCON_USAGE_FULL_SCREEN_GAMING                         0x3
0093 # define INTEL_EDP_TCON_POWER_MASK                                    BIT(4)
0094 # define INTEL_EDP_TCON_POWER_DC                                    (0 << 4)
0095 # define INTEL_EDP_TCON_POWER_AC                                    (1 << 4)
0096 # define INTEL_EDP_TCON_OPTIMIZATION_STRENGTH_MASK             GENMASK(5, 7)
0097 
0098 #define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_1                            0x359
0099 
0100 enum intel_dp_aux_backlight_modparam {
0101     INTEL_DP_AUX_BACKLIGHT_AUTO = -1,
0102     INTEL_DP_AUX_BACKLIGHT_OFF = 0,
0103     INTEL_DP_AUX_BACKLIGHT_ON = 1,
0104     INTEL_DP_AUX_BACKLIGHT_FORCE_VESA = 2,
0105     INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL = 3,
0106 };
0107 
0108 /* Intel EDP backlight callbacks */
0109 static bool
0110 intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
0111 {
0112     struct drm_i915_private *i915 = to_i915(connector->base.dev);
0113     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0114     struct drm_dp_aux *aux = &intel_dp->aux;
0115     struct intel_panel *panel = &connector->panel;
0116     int ret;
0117     u8 tcon_cap[4];
0118 
0119     intel_dp_wait_source_oui(intel_dp);
0120 
0121     ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
0122     if (ret != sizeof(tcon_cap))
0123         return false;
0124 
0125     if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
0126         return false;
0127 
0128     if (tcon_cap[0] >= 1) {
0129         drm_dbg_kms(&i915->drm, "Detected Intel HDR backlight interface version %d\n",
0130                 tcon_cap[0]);
0131     } else {
0132         drm_dbg_kms(&i915->drm, "Detected unsupported HDR backlight interface version %d\n",
0133                 tcon_cap[0]);
0134         return false;
0135     }
0136 
0137     /*
0138      * If we don't have HDR static metadata there is no way to
0139      * runtime detect used range for nits based control. For now
0140      * do not use Intel proprietary eDP backlight control if we
0141      * don't have this data in panel EDID. In case we find panel
0142      * which supports only nits based control, but doesn't provide
0143      * HDR static metadata we need to start maintaining table of
0144      * ranges for such panels.
0145      */
0146     if (i915->params.enable_dpcd_backlight != INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL &&
0147         !(connector->base.hdr_sink_metadata.hdmi_type1.metadata_type &
0148           BIT(HDMI_STATIC_METADATA_TYPE1))) {
0149         drm_info(&i915->drm,
0150              "Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d. needs this, please file a _new_ bug report on drm/i915, see " FDO_BUG_URL " for details.\n",
0151              INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL);
0152         return false;
0153     }
0154 
0155     panel->backlight.edp.intel.sdr_uses_aux =
0156         tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP;
0157 
0158     return true;
0159 }
0160 
0161 static u32
0162 intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe)
0163 {
0164     struct drm_i915_private *i915 = to_i915(connector->base.dev);
0165     struct intel_panel *panel = &connector->panel;
0166     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0167     u8 tmp;
0168     u8 buf[2] = { 0 };
0169 
0170     if (drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp) != 1) {
0171         drm_err(&i915->drm, "Failed to read current backlight mode from DPCD\n");
0172         return 0;
0173     }
0174 
0175     if (!(tmp & INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE)) {
0176         if (!panel->backlight.edp.intel.sdr_uses_aux) {
0177             u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe);
0178 
0179             return intel_backlight_level_from_pwm(connector, pwm_level);
0180         }
0181 
0182         /* Assume 100% brightness if backlight controls aren't enabled yet */
0183         return panel->backlight.max;
0184     }
0185 
0186     if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
0187                  sizeof(buf)) != sizeof(buf)) {
0188         drm_err(&i915->drm, "Failed to read brightness from DPCD\n");
0189         return 0;
0190     }
0191 
0192     return (buf[1] << 8 | buf[0]);
0193 }
0194 
0195 static void
0196 intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state, u32 level)
0197 {
0198     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0199     struct drm_device *dev = connector->base.dev;
0200     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0201     u8 buf[4] = { 0 };
0202 
0203     buf[0] = level & 0xFF;
0204     buf[1] = (level & 0xFF00) >> 8;
0205 
0206     if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
0207                   sizeof(buf)) != sizeof(buf))
0208         drm_err(dev, "Failed to write brightness level to DPCD\n");
0209 }
0210 
0211 static void
0212 intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 level)
0213 {
0214     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0215     struct intel_panel *panel = &connector->panel;
0216 
0217     if (panel->backlight.edp.intel.sdr_uses_aux) {
0218         intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
0219     } else {
0220         const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
0221 
0222         intel_backlight_set_pwm_level(conn_state, pwm_level);
0223     }
0224 }
0225 
0226 static void
0227 intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
0228                   const struct drm_connector_state *conn_state, u32 level)
0229 {
0230     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0231     struct intel_panel *panel = &connector->panel;
0232     struct drm_i915_private *i915 = to_i915(connector->base.dev);
0233     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0234     int ret;
0235     u8 old_ctrl, ctrl;
0236 
0237     intel_dp_wait_source_oui(intel_dp);
0238 
0239     ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
0240     if (ret != 1) {
0241         drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret);
0242         return;
0243     }
0244 
0245     ctrl = old_ctrl;
0246     if (panel->backlight.edp.intel.sdr_uses_aux) {
0247         ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
0248         intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
0249     } else {
0250         u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
0251 
0252         panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
0253 
0254         ctrl &= ~INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
0255     }
0256 
0257     if (ctrl != old_ctrl)
0258         if (drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) != 1)
0259             drm_err(&i915->drm, "Failed to configure DPCD brightness controls\n");
0260 }
0261 
0262 static void
0263 intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
0264 {
0265     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0266     struct intel_panel *panel = &connector->panel;
0267 
0268     /* Nothing to do for AUX based backlight controls */
0269     if (panel->backlight.edp.intel.sdr_uses_aux)
0270         return;
0271 
0272     /* Note we want the actual pwm_level to be 0, regardless of pwm_min */
0273     panel->backlight.pwm_funcs->disable(conn_state, intel_backlight_invert_pwm_level(connector, 0));
0274 }
0275 
0276 static int
0277 intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pipe)
0278 {
0279     struct drm_i915_private *i915 = to_i915(connector->base.dev);
0280     struct intel_panel *panel = &connector->panel;
0281     int ret;
0282 
0283     if (panel->backlight.edp.intel.sdr_uses_aux) {
0284         drm_dbg_kms(&i915->drm, "SDR backlight is controlled through DPCD\n");
0285     } else {
0286         drm_dbg_kms(&i915->drm, "SDR backlight is controlled through PWM\n");
0287 
0288         ret = panel->backlight.pwm_funcs->setup(connector, pipe);
0289         if (ret < 0) {
0290             drm_err(&i915->drm,
0291                 "Failed to setup SDR backlight controls through PWM: %d\n", ret);
0292             return ret;
0293         }
0294     }
0295 
0296     panel->backlight.max = 512;
0297     panel->backlight.min = 0;
0298     panel->backlight.level = intel_dp_aux_hdr_get_backlight(connector, pipe);
0299     panel->backlight.enabled = panel->backlight.level != 0;
0300 
0301     return 0;
0302 }
0303 
0304 /* VESA backlight callbacks */
0305 static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, enum pipe unused)
0306 {
0307     return connector->panel.backlight.level;
0308 }
0309 
0310 static void
0311 intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level)
0312 {
0313     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0314     struct intel_panel *panel = &connector->panel;
0315     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0316 
0317     if (!panel->backlight.edp.vesa.info.aux_set) {
0318         const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
0319 
0320         intel_backlight_set_pwm_level(conn_state, pwm_level);
0321     }
0322 
0323     drm_edp_backlight_set_level(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
0324 }
0325 
0326 static void
0327 intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
0328                    const struct drm_connector_state *conn_state, u32 level)
0329 {
0330     struct intel_connector *connector = to_intel_connector(conn_state->connector);
0331     struct intel_panel *panel = &connector->panel;
0332     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0333 
0334     if (!panel->backlight.edp.vesa.info.aux_enable) {
0335         u32 pwm_level;
0336 
0337         if (!panel->backlight.edp.vesa.info.aux_set)
0338             pwm_level = intel_backlight_level_to_pwm(connector, level);
0339         else
0340             pwm_level = intel_backlight_invert_pwm_level(connector,
0341                                      panel->backlight.pwm_level_max);
0342 
0343         panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
0344     }
0345 
0346     drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
0347 }
0348 
0349 static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state *old_conn_state,
0350                         u32 level)
0351 {
0352     struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
0353     struct intel_panel *panel = &connector->panel;
0354     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0355 
0356     drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
0357 
0358     if (!panel->backlight.edp.vesa.info.aux_enable)
0359         panel->backlight.pwm_funcs->disable(old_conn_state,
0360                             intel_backlight_invert_pwm_level(connector, 0));
0361 }
0362 
0363 static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
0364 {
0365     struct intel_dp *intel_dp = intel_attached_dp(connector);
0366     struct intel_panel *panel = &connector->panel;
0367     struct drm_i915_private *i915 = dp_to_i915(intel_dp);
0368     u16 current_level;
0369     u8 current_mode;
0370     int ret;
0371 
0372     ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
0373                      panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
0374                      &current_level, &current_mode);
0375     if (ret < 0)
0376         return ret;
0377 
0378     if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) {
0379         ret = panel->backlight.pwm_funcs->setup(connector, pipe);
0380         if (ret < 0) {
0381             drm_err(&i915->drm,
0382                 "Failed to setup PWM backlight controls for eDP backlight: %d\n",
0383                 ret);
0384             return ret;
0385         }
0386     }
0387 
0388     if (panel->backlight.edp.vesa.info.aux_set) {
0389         panel->backlight.max = panel->backlight.edp.vesa.info.max;
0390         panel->backlight.min = 0;
0391         if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
0392             panel->backlight.level = current_level;
0393             panel->backlight.enabled = panel->backlight.level != 0;
0394         } else {
0395             panel->backlight.level = panel->backlight.max;
0396             panel->backlight.enabled = false;
0397         }
0398     } else {
0399         panel->backlight.max = panel->backlight.pwm_level_max;
0400         panel->backlight.min = panel->backlight.pwm_level_min;
0401         if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) {
0402             panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe);
0403             panel->backlight.enabled = panel->backlight.pwm_enabled;
0404         } else {
0405             panel->backlight.level = panel->backlight.max;
0406             panel->backlight.enabled = false;
0407         }
0408     }
0409 
0410     return 0;
0411 }
0412 
0413 static bool
0414 intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
0415 {
0416     struct intel_dp *intel_dp = intel_attached_dp(connector);
0417     struct drm_i915_private *i915 = dp_to_i915(intel_dp);
0418 
0419     if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
0420         drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
0421         return true;
0422     }
0423     return false;
0424 }
0425 
0426 static const struct intel_panel_bl_funcs intel_dp_hdr_bl_funcs = {
0427     .setup = intel_dp_aux_hdr_setup_backlight,
0428     .enable = intel_dp_aux_hdr_enable_backlight,
0429     .disable = intel_dp_aux_hdr_disable_backlight,
0430     .set = intel_dp_aux_hdr_set_backlight,
0431     .get = intel_dp_aux_hdr_get_backlight,
0432 };
0433 
0434 static const struct intel_panel_bl_funcs intel_dp_vesa_bl_funcs = {
0435     .setup = intel_dp_aux_vesa_setup_backlight,
0436     .enable = intel_dp_aux_vesa_enable_backlight,
0437     .disable = intel_dp_aux_vesa_disable_backlight,
0438     .set = intel_dp_aux_vesa_set_backlight,
0439     .get = intel_dp_aux_vesa_get_backlight,
0440 };
0441 
0442 int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
0443 {
0444     struct drm_device *dev = connector->base.dev;
0445     struct intel_panel *panel = &connector->panel;
0446     struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
0447     struct drm_i915_private *i915 = dp_to_i915(intel_dp);
0448     bool try_intel_interface = false, try_vesa_interface = false;
0449 
0450     /* Check the VBT and user's module parameters to figure out which
0451      * interfaces to probe
0452      */
0453     switch (i915->params.enable_dpcd_backlight) {
0454     case INTEL_DP_AUX_BACKLIGHT_OFF:
0455         return -ENODEV;
0456     case INTEL_DP_AUX_BACKLIGHT_AUTO:
0457         switch (panel->vbt.backlight.type) {
0458         case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
0459             try_vesa_interface = true;
0460             break;
0461         case INTEL_BACKLIGHT_DISPLAY_DDI:
0462             try_intel_interface = true;
0463             break;
0464         default:
0465             return -ENODEV;
0466         }
0467         break;
0468     case INTEL_DP_AUX_BACKLIGHT_ON:
0469         if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
0470             try_intel_interface = true;
0471 
0472         try_vesa_interface = true;
0473         break;
0474     case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA:
0475         try_vesa_interface = true;
0476         break;
0477     case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL:
0478         try_intel_interface = true;
0479         break;
0480     }
0481 
0482     /*
0483      * Since Intel has their own backlight control interface, the majority of machines out there
0484      * using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
0485      * the VESA interface. However, other GPUs (such as Nvidia's) will always use the VESA
0486      * interface. This means that there's quite a number of panels out there that will advertise
0487      * support for both interfaces, primarily systems with Intel/Nvidia hybrid GPU setups.
0488      *
0489      * There's a catch to this though: on many panels that advertise support for both
0490      * interfaces, the VESA backlight interface will stop working once we've programmed the
0491      * panel with Intel's OUI - which is also required for us to be able to detect Intel's
0492      * backlight interface at all. This means that the only sensible way for us to detect both
0493      * interfaces is to probe for Intel's first, and VESA's second.
0494      */
0495     if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector)) {
0496         drm_dbg_kms(dev, "Using Intel proprietary eDP backlight controls\n");
0497         panel->backlight.funcs = &intel_dp_hdr_bl_funcs;
0498         return 0;
0499     }
0500 
0501     if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) {
0502         drm_dbg_kms(dev, "Using VESA eDP backlight controls\n");
0503         panel->backlight.funcs = &intel_dp_vesa_bl_funcs;
0504         return 0;
0505     }
0506 
0507     return -ENODEV;
0508 }