From: Iswara Nagulendran <[email protected]> [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 <[email protected]> Reviewed-by: Dillon Varone <[email protected]> Signed-off-by: Iswara Nagulendran <[email protected]> Signed-off-by: George Zhang <[email protected]> --- .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 41 ++++++++++++++++++- .../amd/display/dc/hwss/dcn42/dcn42_hwseq.c | 2 + .../link/protocols/link_edp_panel_control.c | 13 +++--- .../drm/amd/display/modules/power/power_abm.c | 10 ++++- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index e72e10c276de..b6f3c0480ab6 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -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; } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c index f415473517d4..cc8e96ffe7d1 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c @@ -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 &= diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index baf57692bbb5..16951a9550f2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -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; } diff --git a/drivers/gpu/drm/amd/display/modules/power/power_abm.c b/drivers/gpu/drm/amd/display/modules/power/power_abm.c index 5b972f04bf7a..b26ceaba940d 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_abm.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_abm.c @@ -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); } -- 2.55.0
