drm/amd/display: Fix VABC Init and OLED Support

[Why]
TCONs supporting VESA AUX Backlight does not always
support VESA Smooth Brightness. Driver software
needs to implement smooth brightness by periodically
updating the brightness by small steps. Driver
implementation is completed and verified on LCD
panels but solution is missing for OLED panels.

[How]
Updated driver to include smooth brightness for
OLED panels using VESA Aux Backlight.
Revert original workaround for VABC on oled issue,
as it is no longer needed.
Add VABC backlight Initialization sequence from
driver side.
Add fix to remove conflict between FW and driver
backlight programming for future ASIC.
Enable VABC for all future asic revisions.

Reviewed-by: Anthony Koo <anthony.koo@amd.com>
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Iswara Nagulendran <Iswara.Nagulendran@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Iswara Nagulendran 2026-06-16 15:31:03 -04:00 committed by Alex Deucher
parent 4133f1caf3
commit 1d8327353d
4 changed files with 56 additions and 10 deletions

View File

@ -719,6 +719,34 @@ static void dmub_abm_set_backlight(struct dc_context *dc,
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
static bool dmub_cacp_set_backlight(struct dc_context *dc,
struct set_backlight_level_params *backlight_level_params,
unsigned int panel_inst)
{
union dmub_rb_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.cacp_set_backlight.header.type = DMUB_CMD__CACP;
cmd.cacp_set_backlight.header.sub_type = DMUB_CMD__CACP_SET_BACKLIGHT;
cmd.cacp_set_backlight.cacp_set_backlight_data.aux_inst = backlight_level_params->aux_inst;
cmd.cacp_set_backlight.cacp_set_backlight_data.frame_ramp = backlight_level_params->frame_ramp;
cmd.cacp_set_backlight.cacp_set_backlight_data.backlight_user_level =
backlight_level_params->backlight_pwm_u16_16;
cmd.cacp_set_backlight.cacp_set_backlight_data.backlight_control_type =
(enum dmub_backlight_control_type)backlight_level_params->control_type;
cmd.cacp_set_backlight.cacp_set_backlight_data.min_luminance = backlight_level_params->min_luminance;
cmd.cacp_set_backlight.cacp_set_backlight_data.max_luminance = backlight_level_params->max_luminance;
cmd.cacp_set_backlight.cacp_set_backlight_data.min_backlight_pwm = backlight_level_params->min_backlight_pwm;
cmd.cacp_set_backlight.cacp_set_backlight_data.max_backlight_pwm = backlight_level_params->max_backlight_pwm;
cmd.cacp_set_backlight.cacp_set_backlight_data.version = DMUB_CMD_CACP_CONTROL_VERSION_1;
cmd.cacp_set_backlight.cacp_set_backlight_data.panel_mask = (0x01 << panel_inst);
cmd.cacp_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_backlight_data);
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
return true;
}
bool dcn31_set_backlight_level(struct pipe_ctx *pipe_ctx,
struct set_backlight_level_params *backlight_level_params)
{
@ -746,8 +774,19 @@ bool dcn31_set_backlight_level(struct pipe_ctx *pipe_ctx,
panel_cntl->inst,
panel_cntl->pwrseq_inst);
if (backlight_level_params->control_type != BACKLIGHT_CONTROL_AMD_AUX)
if (link && link->panel_type == PANEL_TYPE_OLED) {
/* For OLED panel with AMD AUX, skip set backlight call */
if (backlight_level_params->control_type == BACKLIGHT_CONTROL_VESA_AUX)
dmub_cacp_set_backlight(dc, backlight_level_params, panel_cntl->inst);
} else if (link && link->panel_type == PANEL_TYPE_MINILED) {
/* For MiniLED panel we need to check if CACP or ABM is being used */
if (link->panel_config.cacp.cacp_supported)
dmub_cacp_set_backlight(dc, backlight_level_params, panel_cntl->inst);
else
dmub_abm_set_backlight(dc, backlight_level_params, panel_cntl->inst);
} else {
dmub_abm_set_backlight(dc, backlight_level_params, panel_cntl->inst);
}
return true;
}

View File

@ -281,6 +281,8 @@ void dcn42_init_hw(struct dc *dc)
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0;
dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
dc->caps.dmub_caps.aux_backlight_support =
dc->ctx->dmub_srv->dmub->feature_caps.abm_aux_backlight_support;
/* sw and fw FAMS versions must match for support */
dc->debug.fams2_config.bits.enable &=

View File

@ -161,9 +161,7 @@ bool edp_set_backlight_level_nits(struct dc_link *link,
if (link->is_dds && !link->dpcd_caps.panel_luminance_control)
return true;
// use internal backlight control if dmub capabilities are not present
if (link->backlight_control_type == BACKLIGHT_CONTROL_VESA_AUX &&
!link->dc->caps.dmub_caps.aux_backlight_support) {
if (link->backlight_control_type == BACKLIGHT_CONTROL_VESA_AUX) {
uint8_t backlight_enable = 0;
struct target_luminance_value *target_luminance = NULL;
@ -273,10 +271,11 @@ bool edp_backlight_enable_aux(struct dc_link *link, bool enable)
if (link->is_dds)
return true;
if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
&backlight_enable, 1) != DC_OK)
return false;
if (!link->dpcd_caps.panel_luminance_control) {
if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
&backlight_enable, 1) != DC_OK)
return false;
}
return true;
}

View File

@ -716,8 +716,9 @@ void mod_power_update_backlight_on_mode_change(
{
struct set_backlight_level_params backlight_level_params = { 0 };
if (link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
if ((link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) &&
link->backlight_control_type == BACKLIGHT_CONTROL_AMD_AUX)
dc_link_set_backlight_level_nits(link, core_power->bl_state[panel_inst].isHDR,
core_power->bl_state[panel_inst].backlight_millinit, 0);
@ -746,6 +747,11 @@ static bool set_backlight_millinits_aux(struct core_power *core_power,
link = dc_stream_get_link(stream);
// only use internal backlight control if dmub capabilities are not present
if (link->backlight_control_type == BACKLIGHT_CONTROL_VESA_AUX &&
link->dc->caps.dmub_caps.aux_backlight_support)
return true;
return dc_link_set_backlight_level_nits(link, core_power->bl_state[inst].isHDR,
backlight_millinits, transition_time_millisec);
}