@@ -3290,6 +3290,10 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_bac
3290
3290
int ret ;
3291
3291
u8 buf [2 ] = { 0 };
3292
3292
3293
+ /* The panel uses the PWM for controlling brightness levels */
3294
+ if (!bl -> aux_set )
3295
+ return 0 ;
3296
+
3293
3297
if (bl -> lsb_reg_used ) {
3294
3298
buf [0 ] = (level & 0xff00 ) >> 8 ;
3295
3299
buf [1 ] = (level & 0x00ff );
@@ -3316,7 +3320,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
3316
3320
int ret ;
3317
3321
u8 buf ;
3318
3322
3319
- /* The panel uses something other then DPCD for enabling its backlight */
3323
+ /* This panel uses the EDP_BL_PWR GPIO for enablement */
3320
3324
if (!bl -> aux_enable )
3321
3325
return 0 ;
3322
3326
@@ -3351,19 +3355,24 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
3351
3355
* restoring any important backlight state such as the given backlight level, the brightness byte
3352
3356
* count, backlight frequency, etc.
3353
3357
*
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 .
3359
3363
*
3360
3364
* Returns: %0 on success, negative error code on failure.
3361
3365
*/
3362
3366
int drm_edp_backlight_enable (struct drm_dp_aux * aux , const struct drm_edp_backlight_info * bl ,
3363
3367
const u16 level )
3364
3368
{
3365
3369
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 ;
3367
3376
3368
3377
if (bl -> pwmgen_bit_count ) {
3369
3378
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);
3405
3414
* @aux: The DP AUX channel to use
3406
3415
* @bl: Backlight capability info from drm_edp_backlight_init()
3407
3416
*
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.
3414
3424
*
3415
3425
* Returns: %0 on success or no-op, negative error code on failure.
3416
3426
*/
@@ -3434,6 +3444,9 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf
3434
3444
int ret ;
3435
3445
u8 pn , pn_min , pn_max ;
3436
3446
3447
+ if (!bl -> aux_set )
3448
+ return 0 ;
3449
+
3437
3450
ret = drm_dp_dpcd_readb (aux , DP_EDP_PWMGEN_BIT_COUNT , & pn );
3438
3451
if (ret != 1 ) {
3439
3452
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
3519
3532
}
3520
3533
3521
3534
static 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 ,
3523
3536
u8 * current_mode )
3524
3537
{
3525
3538
int ret ;
@@ -3534,6 +3547,9 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
3534
3547
}
3535
3548
3536
3549
* current_mode = (mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK );
3550
+ if (!bl -> aux_set )
3551
+ return 0 ;
3552
+
3537
3553
if (* current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD ) {
3538
3554
int size = 1 + bl -> lsb_reg_used ;
3539
3555
@@ -3564,7 +3580,7 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
3564
3580
* @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight
3565
3581
* @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz
3566
3582
* @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
3568
3584
* @current_mode: Where to store the currently set backlight control mode
3569
3585
*
3570
3586
* 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
3584
3600
3585
3601
if (edp_dpcd [1 ] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP )
3586
3602
bl -> aux_enable = true;
3603
+ if (edp_dpcd [2 ] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP )
3604
+ bl -> aux_set = true;
3587
3605
if (edp_dpcd [2 ] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT )
3588
3606
bl -> lsb_reg_used = true;
3589
3607
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
+
3590
3616
ret = drm_edp_backlight_probe_max (aux , bl , driver_pwm_freq_hz , edp_dpcd );
3591
3617
if (ret < 0 )
3592
3618
return ret ;
3593
3619
3594
- ret = drm_edp_backlight_probe_level (aux , bl , current_mode );
3620
+ ret = drm_edp_backlight_probe_state (aux , bl , current_mode );
3595
3621
if (ret < 0 )
3596
3622
return ret ;
3597
3623
* current_level = ret ;
3598
3624
3599
3625
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
+
3605
3635
return 0 ;
3606
3636
}
3607
3637
EXPORT_SYMBOL (drm_edp_backlight_init );
0 commit comments