@@ -3290,6 +3290,10 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_bac
32903290 int ret ;
32913291 u8 buf [2 ] = { 0 };
32923292
3293+ /* The panel uses the PWM for controlling brightness levels */
3294+ if (!bl -> aux_set )
3295+ return 0 ;
3296+
32933297 if (bl -> lsb_reg_used ) {
32943298 buf [0 ] = (level & 0xff00 ) >> 8 ;
32953299 buf [1 ] = (level & 0x00ff );
@@ -3316,7 +3320,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
33163320 int ret ;
33173321 u8 buf ;
33183322
3319- /* The panel uses something other then DPCD for enabling its backlight */
3323+ /* This panel uses the EDP_BL_PWR GPIO for enablement */
33203324 if (!bl -> aux_enable )
33213325 return 0 ;
33223326
@@ -3351,19 +3355,24 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
33513355 * restoring any important backlight state such as the given backlight level, the brightness byte
33523356 * count, backlight frequency, etc.
33533357 *
3354- * Note that certain panels, while supporting brightness level controls over DPCD, may not support
3355- * having their backlights enabled via the standard %DP_EDP_DISPLAY_CONTROL_REGISTER. On such panels
3356- * &drm_edp_backlight_info.aux_enable will be set to %false, this function will skip the step of
3357- * programming the %DP_EDP_DISPLAY_CONTROL_REGISTER , and the driver must perform the required
3358- * implementation specific step for enabling the backlight after calling this function .
3358+ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require
3359+ * that the driver handle enabling/disabling the panel through implementation-specific means using
3360+ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false,
3361+ * this function becomes a no-op , and the driver is expected to handle powering the panel on using
3362+ * the EDP_BL_PWR GPIO .
33593363 *
33603364 * Returns: %0 on success, negative error code on failure.
33613365 */
33623366int drm_edp_backlight_enable (struct drm_dp_aux * aux , const struct drm_edp_backlight_info * bl ,
33633367 const u16 level )
33643368{
33653369 int ret ;
3366- u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD ;
3370+ u8 dpcd_buf ;
3371+
3372+ if (bl -> aux_set )
3373+ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD ;
3374+ else
3375+ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM ;
33673376
33683377 if (bl -> pwmgen_bit_count ) {
33693378 ret = drm_dp_dpcd_writeb (aux , DP_EDP_PWMGEN_BIT_COUNT , bl -> pwmgen_bit_count );
@@ -3405,12 +3414,13 @@ EXPORT_SYMBOL(drm_edp_backlight_enable);
34053414 * @aux: The DP AUX channel to use
34063415 * @bl: Backlight capability info from drm_edp_backlight_init()
34073416 *
3408- * This function handles disabling DPCD backlight controls on a panel over AUX. Note that some
3409- * panels have backlights that are enabled/disabled by other means, despite having their brightness
3410- * values controlled through DPCD. On such panels &drm_edp_backlight_info.aux_enable will be set to
3411- * %false, this function will become a no-op (and we will skip updating
3412- * %DP_EDP_DISPLAY_CONTROL_REGISTER), and the driver must take care to perform it's own
3413- * implementation specific step for disabling the backlight.
3417+ * This function handles disabling DPCD backlight controls on a panel over AUX.
3418+ *
3419+ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require
3420+ * that the driver handle enabling/disabling the panel through implementation-specific means using
3421+ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false,
3422+ * this function becomes a no-op, and the driver is expected to handle powering the panel off using
3423+ * the EDP_BL_PWR GPIO.
34143424 *
34153425 * Returns: %0 on success or no-op, negative error code on failure.
34163426 */
@@ -3434,6 +3444,9 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf
34343444 int ret ;
34353445 u8 pn , pn_min , pn_max ;
34363446
3447+ if (!bl -> aux_set )
3448+ return 0 ;
3449+
34373450 ret = drm_dp_dpcd_readb (aux , DP_EDP_PWMGEN_BIT_COUNT , & pn );
34383451 if (ret != 1 ) {
34393452 drm_dbg_kms (aux -> drm_dev , "%s: Failed to read pwmgen bit count cap: %d\n" ,
@@ -3519,7 +3532,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf
35193532}
35203533
35213534static inline int
3522- drm_edp_backlight_probe_level (struct drm_dp_aux * aux , struct drm_edp_backlight_info * bl ,
3535+ drm_edp_backlight_probe_state (struct drm_dp_aux * aux , struct drm_edp_backlight_info * bl ,
35233536 u8 * current_mode )
35243537{
35253538 int ret ;
@@ -3534,6 +3547,9 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
35343547 }
35353548
35363549 * current_mode = (mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK );
3550+ if (!bl -> aux_set )
3551+ return 0 ;
3552+
35373553 if (* current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD ) {
35383554 int size = 1 + bl -> lsb_reg_used ;
35393555
@@ -3564,7 +3580,7 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
35643580 * @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight
35653581 * @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz
35663582 * @edp_dpcd: A cached copy of the eDP DPCD
3567- * @current_level: Where to store the probed brightness level
3583+ * @current_level: Where to store the probed brightness level, if any
35683584 * @current_mode: Where to store the currently set backlight control mode
35693585 *
35703586 * Initializes a &drm_edp_backlight_info struct by probing @aux for it's backlight capabilities,
@@ -3584,24 +3600,38 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl
35843600
35853601 if (edp_dpcd [1 ] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP )
35863602 bl -> aux_enable = true;
3603+ if (edp_dpcd [2 ] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP )
3604+ bl -> aux_set = true;
35873605 if (edp_dpcd [2 ] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT )
35883606 bl -> lsb_reg_used = true;
35893607
3608+ /* Sanity check caps */
3609+ if (!bl -> aux_set && !(edp_dpcd [2 ] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP )) {
3610+ drm_dbg_kms (aux -> drm_dev ,
3611+ "%s: Panel supports neither AUX or PWM brightness control? Aborting\n" ,
3612+ aux -> name );
3613+ return - EINVAL ;
3614+ }
3615+
35903616 ret = drm_edp_backlight_probe_max (aux , bl , driver_pwm_freq_hz , edp_dpcd );
35913617 if (ret < 0 )
35923618 return ret ;
35933619
3594- ret = drm_edp_backlight_probe_level (aux , bl , current_mode );
3620+ ret = drm_edp_backlight_probe_state (aux , bl , current_mode );
35953621 if (ret < 0 )
35963622 return ret ;
35973623 * current_level = ret ;
35983624
35993625 drm_dbg_kms (aux -> drm_dev ,
3600- "%s: Found backlight level=%d/%d pwm_freq_pre_divider=%d mode=%x\n" ,
3601- aux -> name , * current_level , bl -> max , bl -> pwm_freq_pre_divider , * current_mode );
3602- drm_dbg_kms (aux -> drm_dev ,
3603- "%s: Backlight caps: pwmgen_bit_count=%d lsb_reg_used=%d aux_enable=%d\n" ,
3604- aux -> name , bl -> pwmgen_bit_count , bl -> lsb_reg_used , bl -> aux_enable );
3626+ "%s: Found backlight: aux_set=%d aux_enable=%d mode=%d\n" ,
3627+ aux -> name , bl -> aux_set , bl -> aux_enable , * current_mode );
3628+ if (bl -> aux_set ) {
3629+ drm_dbg_kms (aux -> drm_dev ,
3630+ "%s: Backlight caps: level=%d/%d pwm_freq_pre_divider=%d lsb_reg_used=%d\n" ,
3631+ aux -> name , * current_level , bl -> max , bl -> pwm_freq_pre_divider ,
3632+ bl -> lsb_reg_used );
3633+ }
3634+
36053635 return 0 ;
36063636}
36073637EXPORT_SYMBOL (drm_edp_backlight_init );
0 commit comments