This series modifies drm dp edp helpers so that drivers can now use them to manipulate brightness using luminance value via the PANEL_TARGET_LUMINANCE_VALUE register. This feature was introduced frin eDP 1.5. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Suraj Kandpal (13): drm/dp: Introduce new member in drm_backlight_info drm/dp: Add argument in drm_edp_backlight_init drm/dp: Add argument for max luminance in drm_edp_backlight_init drm/dp: Move from u16 to u32 for max in drm_edp_backlight_info drm/dp: Change current_level argument type to u32 drm/dp: Modify drm_edp_probe_state drm/dp: Change argument type for drm_edp_backlight_set_level drm/dp: Modify drm_edp_backlight_set_level drm/dp: Change argument type of drm_edp_backlight_enable drm/dp: Enable backlight control using luminance drm/i915/backlight: Use drm helper to initialize edp backlight drm/i915/backlight: Use drm helper to set edp backlight drm/i915/backlight: Use drm_edp_backlight_enable drivers/gpu/drm/display/drm_dp_helper.c | 92 ++++++++---- .../drm/i915/display/intel_dp_aux_backlight.c | 140 ++++++------------ drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +- include/drm/display/drm_dp_helper.h | 10 +- 5 files changed, 127 insertions(+), 124 deletions(-) -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 01/13] drm/dp: Introduce new member in drm_backlight_info
Introduce luminance_set flag which indicates if we can manipulate backlight using luminance value or not which is only possible after eDP v1.5. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 8 ++++++-- include/drm/display/drm_dp_helper.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 385a1bfdb272..e817bed9ffc6 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4277,11 +4277,15 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl bl->aux_set = true; if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) bl->lsb_reg_used = true; + if ((edp_dpcd[0] & DP_EDP_15) && edp_dpcd[3] & + (DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE)) + bl->luminance_set = true; /* Sanity check caps */ - if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) { + if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP) && + !bl->luminance_set) { drm_dbg_kms(aux->drm_dev, - "%s: Panel supports neither AUX or PWM brightness control? Aborting\n", + "%s: Panel does not support AUX, PWM or luminance-based brightness control. Aborting\n", aux->name); return -EINVAL; } diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 3e35a68b2b41..e3b13858c8a9 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -855,6 +855,7 @@ struct drm_edp_backlight_info { bool lsb_reg_used : 1; bool aux_enable : 1; bool aux_set : 1; + bool luminance_set : 1; }; int -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 02/13] drm/dp: Add argument in drm_edp_backlight_init
Add bool argument in drm_edp_backlight init to provide the drivers option to choose if they want to use luminance values to manipulate brightness. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 2 +- drivers/gpu/drm/nouveau/nouveau_backlight.c | 2 +- include/drm/display/drm_dp_helper.h | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index e817bed9ffc6..2a662951f7a8 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4255,6 +4255,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i * @edp_dpcd: A cached copy of the eDP DPCD * @current_level: Where to store the probed brightness level, if any * @current_mode: Where to store the currently set backlight control mode + * @need_luminance: Tells us if a we want to manipulate backlight using luminance values * * Initializes a &drm_edp_backlight_info struct by probing @aux for it's backlight capabilities, * along with also probing the current and maximum supported brightness levels. @@ -4267,7 +4268,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], - u16 *current_level, u8 *current_mode) + u16 *current_level, u8 *current_mode, bool need_luminance) { int ret; @@ -4278,7 +4279,7 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) bl->lsb_reg_used = true; if ((edp_dpcd[0] & DP_EDP_15) && edp_dpcd[3] & - (DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE)) + (DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE) && need_luminance) bl->luminance_set = true; /* Sanity check caps */ @@ -4396,7 +4397,7 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) bl->aux = aux; ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, - ¤t_level, ¤t_mode); + ¤t_level, ¤t_mode, false); if (ret < 0) return ret; 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 271b27c9de51..dc6f6680774f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -600,7 +600,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, } else { ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, - ¤t_level, ¤t_mode); + ¤t_level, ¤t_mode, false); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 9aae26eb7d8f..7d93266bf26a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -262,7 +262,7 @@ nv50_backlight_init(struct nouveau_backlight *bl, nv_conn->base.name); ret = drm_edp_backlight_init(&nv_conn->aux, &bl->edp_info, 0, edp_dpcd, - ¤t_level, ¤t_mode); + ¤t_level, ¤t_mode, false); if (ret < 0) return ret; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index e3b13858c8a9..fcbf447206cf 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -861,7 +861,7 @@ struct drm_edp_backlight_info { int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], - u16 *current_level, u8 *current_mode); + u16 *current_level, u8 *current_mode, bool need_luminance); int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u16 level); int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 03/13] drm/dp: Add argument for max luminance in drm_edp_backlight_init
Add new argument to drm_edp_backlight_init which gives the max_luminance which will be needed to set the max values for backlight. --v2 -Use pass only max luminance instead of luminance_range_info struct [Arun] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 4 +++- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 6 ++++-- drivers/gpu/drm/nouveau/nouveau_backlight.c | 3 ++- include/drm/display/drm_dp_helper.h | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 2a662951f7a8..9df95776d1cb 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4251,6 +4251,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i * interface. * @aux: The DP aux device to use for probing * @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight + * @max_luminance: max luminance when need luminance is set as true * @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz * @edp_dpcd: A cached copy of the eDP DPCD * @current_level: Where to store the probed brightness level, if any @@ -4267,6 +4268,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i */ int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u16 *current_level, u8 *current_mode, bool need_luminance) { @@ -4396,7 +4398,7 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) bl->aux = aux; - ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, + ret = drm_edp_backlight_init(aux, &bl->info, 0, 0, edp_dpcd, ¤t_level, ¤t_mode, false); if (ret < 0) return ret; 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 dc6f6680774f..ab594bf028da 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -599,8 +599,10 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, connector->base.base.id, connector->base.name); } else { ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, - panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, - ¤t_level, ¤t_mode, false); + luminance_range->max_luminance, + panel->vbt.backlight.pwm_freq_hz, + intel_dp->edp_dpcd, ¤t_level, ¤t_mode, + false); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 7d93266bf26a..d45619db02a2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -261,7 +261,8 @@ nv50_backlight_init(struct nouveau_backlight *bl, NV_DEBUG(drm, "DPCD backlight controls supported on %s\n", nv_conn->base.name); - ret = drm_edp_backlight_init(&nv_conn->aux, &bl->edp_info, 0, edp_dpcd, + ret = drm_edp_backlight_init(&nv_conn->aux, &bl->edp_info, + 0, 0, edp_dpcd, ¤t_level, ¤t_mode, false); if (ret < 0) return ret; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index fcbf447206cf..91094a38594c 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -860,6 +860,7 @@ struct drm_edp_backlight_info { int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u16 *current_level, u8 *current_mode, bool need_luminance); int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 04/13] drm/dp: Move from u16 to u32 for max in drm_edp_backlight_info
Use u32 instead of u16 for max variable in drm_edp_backlight_info since it can now hold max luminance range value which is u32. We will set this max with max_luminance value when luminance_set is true. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 10 +++++++--- include/drm/display/drm_dp_helper.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 9df95776d1cb..90b23f78a12d 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4293,9 +4293,13 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl return -EINVAL; } - ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd); - if (ret < 0) - return ret; + if (bl->luminance_set) { + bl->max = max_luminance; + } else { + ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd); + if (ret < 0) + return ret; + } ret = drm_edp_backlight_probe_state(aux, bl, current_mode); if (ret < 0) diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 91094a38594c..6176e0b5ea1a 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -850,7 +850,7 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk) struct drm_edp_backlight_info { u8 pwmgen_bit_count; u8 pwm_freq_pre_divider; - u16 max; + u32 max; bool lsb_reg_used : 1; bool aux_enable : 1; -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 05/13] drm/dp: Change current_level argument type to u32
Change the current_level argument type to u32 from u16 since it can now carry the value which it gets from DP_EDP_PANEL_TARGET_LUMINANCE_VALUE. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 4 ++-- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 2 +- drivers/gpu/drm/nouveau/nouveau_backlight.c | 2 +- include/drm/display/drm_dp_helper.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 90b23f78a12d..daeb3bdc87a3 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4270,7 +4270,7 @@ int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], - u16 *current_level, u8 *current_mode, bool need_luminance) + u32 *current_level, u8 *current_mode, bool need_luminance) { int ret; @@ -4378,7 +4378,7 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) { struct dp_aux_backlight *bl; struct backlight_properties props = { 0 }; - u16 current_level; + u32 current_level; u8 current_mode; u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; int ret; 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 ab594bf028da..800d07c7f041 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -580,7 +580,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, &connector->base.display_info.luminance_range; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_panel *panel = &connector->panel; - u16 current_level; + u32 current_level; u8 current_mode; int ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index d45619db02a2..4a75d146a171 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -245,7 +245,7 @@ nv50_backlight_init(struct nouveau_backlight *bl, if (nv_conn->type == DCB_CONNECTOR_eDP) { int ret; - u16 current_level; + u32 current_level; u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; u8 current_mode; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 6176e0b5ea1a..21984bac0743 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -862,7 +862,7 @@ int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], - u16 *current_level, u8 *current_mode, bool need_luminance); + u32 *current_level, u8 *current_mode, bool need_luminance); int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u16 level); int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, -- 2.34.1
Modify drm_edp_probe_state to read current level from DP_EDP_PANEL_TARGET_LUMINANCE_VALUE. We divide it by 1000 since the value in this register is in millinits. --v2 -Add comment on the unit sent back [Arun] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index daeb3bdc87a3..53f02dc6c3f1 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4209,7 +4209,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i u8 *current_mode) { int ret; - u8 buf[2]; + u8 buf[3]; u8 mode_reg; ret = drm_dp_dpcd_read_byte(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &mode_reg); @@ -4226,17 +4226,37 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i if (*current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { int size = 1 + bl->lsb_reg_used; - ret = drm_dp_dpcd_read_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, size); - if (ret < 0) { - drm_dbg_kms(aux->drm_dev, "%s: Failed to read backlight level: %d\n", - aux->name, ret); - return ret; + if (bl->luminance_set) { + ret = drm_dp_dpcd_read_data(aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, + buf, sizeof(buf)); + if (ret < 0) { + drm_dbg_kms(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return ret; } - if (bl->lsb_reg_used) - return (buf[0] << 8) | buf[1]; - else - return buf[0]; + /* + * Incase luminance is set we want to send the value back in nits but since + * DP_EDP_PANEL_TARGET_LUMINANCE stores values in millinits we need to divide + * by 1000. + */ + return (buf[0] | buf[1] << 8 | buf[2] << 16) / 1000; + } else { + ret = drm_dp_dpcd_read_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, + buf, size); + if (ret < 0) { + drm_dbg_kms(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return ret; + } + + if (bl->lsb_reg_used) + return (buf[0] << 8) | buf[1]; + else + return buf[0]; + } } /* -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 07/13] drm/dp: Change argument type for drm_edp_backlight_set_level
Use u32 for level variable as one may need to pass value for DP_EDP_PANEL_TARGET_LUMINANCE_VALUE. --v2 -Typecase is not needed [Jani] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- include/drm/display/drm_dp_helper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 53f02dc6c3f1..4d8829e00599 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3957,7 +3957,7 @@ EXPORT_SYMBOL(drm_dp_pcon_convert_rgb_to_ycbcr); * Returns: %0 on success, negative error code on failure */ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - u16 level) + u32 level) { int ret; u8 buf[2] = { 0 }; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 21984bac0743..56e34568a16b 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -864,7 +864,7 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u32 *current_level, u8 *current_mode, bool need_luminance); int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - u16 level); + u32 level); int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u16 level); int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 08/13] drm/dp: Modify drm_edp_backlight_set_level
Modify drm_edp_backlight_set_level to be able to set the value for register in DP_EDP_PANEL_TARGET_LUMINANCE_VALUE. We multiply the level with 1000 since we get the value in Nits and the register accepts it in milliNits. --v2 -Add comment regarding the unit [Arun] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 4d8829e00599..c078e444014d 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3960,20 +3960,28 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_bac u32 level) { int ret; - u8 buf[2] = { 0 }; + unsigned int offset = DP_EDP_BACKLIGHT_BRIGHTNESS_MSB; + u8 buf[3] = { 0 }; /* The panel uses the PWM for controlling brightness levels */ - if (!bl->aux_set) + if (!(bl->aux_set || bl->luminance_set)) return 0; - if (bl->lsb_reg_used) { + if (bl->luminance_set) { + level = level * 1000; + level &= 0xffffff; + buf[0] = (level & 0x0000ff); + buf[1] = (level & 0x00ff00) >> 8; + buf[2] = (level & 0xff0000) >> 16; + offset = DP_EDP_PANEL_TARGET_LUMINANCE_VALUE; + } else if (bl->lsb_reg_used) { buf[0] = (level & 0xff00) >> 8; buf[1] = (level & 0x00ff); } else { buf[0] = level; } - ret = drm_dp_dpcd_write_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, sizeof(buf)); + ret = drm_dp_dpcd_write_data(aux, offset, buf, sizeof(buf)); if (ret < 0) { drm_err(aux->drm_dev, "%s: Failed to write aux backlight level: %d\n", -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 09/13] drm/dp: Change argument type of drm_edp_backlight_enable
Change the argument type to u32 for the default level being sent since it has to now account for luminance value which has to be set for DP_EDP_PANEL_LUMINANCE_TARGET_VALUE. --v2 -No need to typecast [Jani] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- include/drm/display/drm_dp_helper.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index c078e444014d..fc1eb8b7bbc1 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4044,7 +4044,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli * Returns: %0 on success, negative error code on failure. */ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - const u16 level) + const u32 level) { int ret; u8 dpcd_buf; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index e5d37eee4301..e97e39abf3a2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1839,7 +1839,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta backlight = nv_connector->backlight; if (backlight && backlight->uses_dpcd) drm_edp_backlight_enable(&nv_connector->aux, &backlight->edp_info, - (u16)backlight->dev->props.brightness); + backlight->dev->props.brightness); #endif break; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 56e34568a16b..774c6d3e2001 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -866,7 +866,7 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u32 level); int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - u16 level); + u32 level); int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); #if IS_ENABLED(CONFIG_DRM_KMS_HELPER) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 10/13] drm/dp: Enable backlight control using luminance
Add flag to enable brightness control via luminance value when enabling edp backlight. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index fc1eb8b7bbc1..db7896c7edb8 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4054,6 +4054,9 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli else dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM; + if (bl->luminance_set) + dpcd_buf |= DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE; + if (bl->pwmgen_bit_count) { ret = drm_dp_dpcd_write_byte(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); if (ret < 0) -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 11/13] drm/i915/backlight: Use drm helper to initialize edp backlight
Now that drm_edp_backlight init has been modified to take into account the setup of lumininace based brightness manipulation we can just use that. --v2 -Fix commit message [Arun] Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> --- .../drm/i915/display/intel_dp_aux_backlight.c | 98 +++++++++---------- 1 file changed, 48 insertions(+), 50 deletions(-) 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 800d07c7f041..117c762fa2fe 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -584,9 +584,37 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, u8 current_mode; int ret; - if (panel->backlight.edp.vesa.luminance_control_support) { + ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, + luminance_range->max_luminance, + panel->vbt.backlight.pwm_freq_hz, + intel_dp->edp_dpcd, ¤t_level, ¤t_mode, + false); + if (ret < 0) + return ret; + + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n", + connector->base.base.id, connector->base.name, + dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable)); + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n", + connector->base.base.id, connector->base.name, + dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set)); + + if (!panel->backlight.edp.vesa.info.aux_set || + !panel->backlight.edp.vesa.info.aux_enable) { + ret = panel->backlight.pwm_funcs->setup(connector, pipe); + if (ret < 0) { + drm_err(display->drm, + "[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n", + connector->base.base.id, connector->base.name, ret); + return ret; + } + } + + if (panel->backlight.edp.vesa.info.luminance_set) { if (luminance_range->max_luminance) { - panel->backlight.max = luminance_range->max_luminance; + panel->backlight.max = panel->backlight.edp.vesa.info.max; panel->backlight.min = luminance_range->min_luminance; } else { panel->backlight.max = 512; @@ -597,56 +625,26 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] AUX VESA Nits backlight level is controlled through DPCD\n", connector->base.base.id, connector->base.name); - } else { - ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, - luminance_range->max_luminance, - panel->vbt.backlight.pwm_freq_hz, - intel_dp->edp_dpcd, ¤t_level, ¤t_mode, - false); - if (ret < 0) - return ret; - - drm_dbg_kms(display->drm, - "[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n", - connector->base.base.id, connector->base.name, - dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable)); - drm_dbg_kms(display->drm, - "[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n", - connector->base.base.id, connector->base.name, - dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set)); - - if (!panel->backlight.edp.vesa.info.aux_set || - !panel->backlight.edp.vesa.info.aux_enable) { - ret = panel->backlight.pwm_funcs->setup(connector, pipe); - if (ret < 0) { - drm_err(display->drm, - "[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n", - connector->base.base.id, connector->base.name, ret); - return ret; - } + } else if (panel->backlight.edp.vesa.info.aux_set) { + panel->backlight.max = panel->backlight.edp.vesa.info.max; + panel->backlight.min = 0; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { + panel->backlight.level = current_level; + panel->backlight.enabled = panel->backlight.level != 0; + } else { + panel->backlight.level = panel->backlight.max; + panel->backlight.enabled = false; } - - if (panel->backlight.edp.vesa.info.aux_set) { - panel->backlight.max = panel->backlight.edp.vesa.info.max; - panel->backlight.min = 0; - if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { - panel->backlight.level = current_level; - panel->backlight.enabled = panel->backlight.level != 0; - } else { - panel->backlight.level = panel->backlight.max; - panel->backlight.enabled = false; - } + } else { + panel->backlight.max = panel->backlight.pwm_level_max; + panel->backlight.min = panel->backlight.pwm_level_min; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) { + panel->backlight.level + panel->backlight.pwm_funcs->get(connector, pipe); + panel->backlight.enabled = panel->backlight.pwm_enabled; } else { - panel->backlight.max = panel->backlight.pwm_level_max; - panel->backlight.min = panel->backlight.pwm_level_min; - if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) { - panel->backlight.level - panel->backlight.pwm_funcs->get(connector, pipe); - panel->backlight.enabled = panel->backlight.pwm_enabled; - } else { - panel->backlight.level = panel->backlight.max; - panel->backlight.enabled = false; - } + panel->backlight.level = panel->backlight.max; + panel->backlight.enabled = false; } } -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 12/13] drm/i915/backlight: Use drm helper to set edp backlight
Now that the drm helper sets the backlight using luminance too we can use that. Remove the obselete function. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- .../drm/i915/display/intel_dp_aux_backlight.c | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) 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 117c762fa2fe..8f33c5b78079 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -475,31 +475,6 @@ static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, en return connector->panel.backlight.level; } -static int -intel_dp_aux_vesa_set_luminance(struct intel_connector *connector, u32 level) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); - u8 buf[3]; - int ret; - - level = level * 1000; - level &= 0xffffff; - buf[0] = (level & 0x0000ff); - buf[1] = (level & 0x00ff00) >> 8; - buf[2] = (level & 0xff0000) >> 16; - - ret = drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, - buf, sizeof(buf)); - if (ret != sizeof(buf)) { - drm_err(intel_dp->aux.drm_dev, - "%s: Failed to set VESA Aux Luminance: %d\n", - intel_dp->aux.name, ret); - return -EINVAL; - } else { - return 0; - } -} - static void intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level) { @@ -507,11 +482,6 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u3 struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); - if (panel->backlight.edp.vesa.luminance_control_support) { - if (!intel_dp_aux_vesa_set_luminance(connector, level)) - return; - } - if (!panel->backlight.edp.vesa.info.aux_set) { const u32 pwm_level = intel_backlight_level_to_pwm(connector, level); @@ -537,7 +507,9 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, if (ret == 1) return; - if (!intel_dp_aux_vesa_set_luminance(connector, level)) + if (!drm_edp_backlight_set_level(&intel_dp->aux, + &panel->backlight.edp.vesa.info, + level)) return; } -- 2.34.1
Suraj Kandpal
2025-Jun-20 06:34 UTC
[PATCH v3 13/13] drm/i915/backlight: Use drm_edp_backlight_enable
Use drm dp helper to enable backlight now that it has been modified to set PANEL_LUMINANCE_CONTROL_ENABLE bit based on if capability supports it and the driver wants it. Remove the dead code. Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy at intel.com> --- .../gpu/drm/i915/display/intel_dp_aux_backlight.c | 14 -------------- 1 file changed, 14 deletions(-) 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 8f33c5b78079..25332a7b7707 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -498,20 +498,6 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); - int ret; - - if (panel->backlight.edp.vesa.luminance_control_support) { - ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, - DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE); - - if (ret == 1) - return; - - if (!drm_edp_backlight_set_level(&intel_dp->aux, - &panel->backlight.edp.vesa.info, - level)) - return; - } if (!panel->backlight.edp.vesa.info.aux_enable) { u32 pwm_level; -- 2.34.1
On Fri, 20 Jun 2025, Suraj Kandpal <suraj.kandpal at intel.com> wrote:> This series modifies drm dp edp helpers so that drivers can now use them > to manipulate brightness using luminance value via the > PANEL_TARGET_LUMINANCE_VALUE register. This feature was > introduced frin eDP 1.5. > > Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com> > > Suraj Kandpal (13): > drm/dp: Introduce new member in drm_backlight_info > drm/dp: Add argument in drm_edp_backlight_init > drm/dp: Add argument for max luminance in drm_edp_backlight_init > drm/dp: Move from u16 to u32 for max in drm_edp_backlight_info > drm/dp: Change current_level argument type to u32 > drm/dp: Modify drm_edp_probe_state > drm/dp: Change argument type for drm_edp_backlight_set_level > drm/dp: Modify drm_edp_backlight_set_level > drm/dp: Change argument type of drm_edp_backlight_enable > drm/dp: Enable backlight control using luminance > drm/i915/backlight: Use drm helper to initialize edp backlight > drm/i915/backlight: Use drm helper to set edp backlight > drm/i915/backlight: Use drm_edp_backlight_enableAcked-by: Jani Nikula <jani.nikula at intel.com> for merging the last three patches via drm-misc. However, would be great to solicit feedback on the series from non-Intel folks too. Cc: Lyude who's worked on DPCD brightness before. BR, Jani.> > drivers/gpu/drm/display/drm_dp_helper.c | 92 ++++++++---- > .../drm/i915/display/intel_dp_aux_backlight.c | 140 ++++++------------ > drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- > drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +- > include/drm/display/drm_dp_helper.h | 10 +- > 5 files changed, 127 insertions(+), 124 deletions(-)-- Jani Nikula, Intel