diff options
| author | Chenyu Chen <chen-yu.chen@amd.com> | 2026-03-05 20:11:50 +0800 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-07-14 19:12:34 -0400 |
| commit | 7b0cc308521696107828b0c6c72c5793fa279cbd (patch) | |
| tree | b11f5b8073880dfeb5739f40222c8922b6ffa729 /drivers/gpu/drm/amd/display/modules | |
| parent | 5b69770e945caa1bef6c4848bb279ec09d3e9d4f (diff) | |
| download | linux-next-7b0cc308521696107828b0c6c72c5793fa279cbd.tar.gz linux-next-7b0cc308521696107828b0c6c72c5793fa279cbd.zip | |
drm/amd/display: Enable CACP on Linux
[Why]
Enable OLED panels to save more power on the Linux platform by
enabling CACP support on Linux.
[How]
Update abm_feature_support() to return ABM_CACP_SUPPORT for OLED
panels. Enable ABM property for all eDP panels including OLED to
support CACP via set_abm_level.
Reviewed-by: Sun peng (Leo) Li <sunpeng.li@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules')
3 files changed, 147 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h index f9814cf7bbdb..02bee3b1956d 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h @@ -328,6 +328,17 @@ bool mod_power_is_abm_active(struct mod_power *mod_power, const struct dc_link *link, unsigned int inst); +bool mod_power_is_abm_supported(struct mod_power *mod_power, + unsigned int inst); + +bool mod_power_abm_set_event(struct mod_power *mod_power, + unsigned int full_screen, unsigned int trans_info, + unsigned int hdr_mode, unsigned int scaling_enable, + unsigned int scaling_strength_map, unsigned int inst); + +bool mod_power_abm_set_strength(struct mod_power *mod_power, + unsigned int strength, + unsigned int inst); bool mod_power_set_psr_event(struct mod_power *mod_power, struct dc_stream_state *stream, bool set_event, 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 b9447cb7485b..5b972f04bf7a 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_abm.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_abm.c @@ -1453,6 +1453,76 @@ bool mod_power_is_abm_active(struct mod_power *mod_power, return is_active; } +bool mod_power_is_abm_supported(struct mod_power *mod_power, + unsigned int inst) +{ + struct core_power *core_power = NULL; + struct dc *dc = NULL; + + if (mod_power == NULL) + return false; + + core_power = MOD_POWER_TO_CORE(mod_power); + dc = core_power->dc; + + // It's only implemented on dmcub. + if (dc->ctx->dmub_srv) { + if (!dmub_is_abm_supported(dc->res_pool, inst)) + return false; + } else + return false; + + return true; +} + +bool mod_power_abm_set_event(struct mod_power *mod_power, + unsigned int full_screen, unsigned int trans_info, + unsigned int hdr_mode, unsigned int scaling_enable, + unsigned int scaling_strength_map, unsigned int inst) +{ + struct core_power *core_power = NULL; + struct dc *dc = NULL; + + if (mod_power == NULL) + return false; + + core_power = MOD_POWER_TO_CORE(mod_power); + dc = core_power->dc; + + // It's only implemented on dmcub. + if (dc->ctx->dmub_srv) { + if (!dmub_set_abm_event(dc->res_pool, full_screen, trans_info, + hdr_mode, scaling_enable, scaling_strength_map, inst)) + return false; + } else + return false; + + return true; +} + +bool mod_power_abm_set_strength(struct mod_power *mod_power, + unsigned int strength, + unsigned int inst) +{ + struct core_power *core_power = NULL; + struct dc *dc = NULL; + + if (mod_power == NULL) + return false; + + core_power = MOD_POWER_TO_CORE(mod_power); + dc = core_power->dc; + + // It's only implemented on dmcub. + if (dc->ctx->dmub_srv) { + if (!dmub_set_abm_strength(dc->res_pool, strength, inst)) + return false; + } else + return false; + + return true; +} + static void fill_backlight_transform_table(struct dmcu_iram_parameters params, struct iram_table_v_2 *table) { @@ -1990,6 +2060,62 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, return result; } +bool dmub_is_abm_supported(struct resource_pool *res_pool, unsigned int inst) +{ + + if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL) + return false; + + return true; +} + +bool dmub_set_abm_event(struct resource_pool *res_pool, + unsigned int full_screen, unsigned int trans_info, + unsigned int hdr_mode, unsigned int scaling_enable, unsigned int scaling_strength_map, + unsigned int inst) +{ + bool result = false; + + if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL) + return false; + + if (res_pool->multiple_abms[inst]) { + if (res_pool->multiple_abms[inst]->funcs->set_abm_event) + result = res_pool->multiple_abms[inst]->funcs->set_abm_event( + res_pool->multiple_abms[inst], full_screen, trans_info, + hdr_mode, scaling_enable, scaling_strength_map, inst); + } else { + if (res_pool->abm->funcs->set_abm_event) + result = res_pool->abm->funcs->set_abm_event( + res_pool->abm, full_screen, trans_info, + hdr_mode, scaling_enable, scaling_strength_map, inst); + } + + return result; +} + +bool dmub_set_abm_strength(struct resource_pool *res_pool, + unsigned int strength, + unsigned int inst) +{ + bool result = false; + + if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL) + return false; + + if (res_pool->multiple_abms[inst]) { + if (res_pool->multiple_abms[inst]->funcs->set_abm_level) + result = res_pool->multiple_abms[inst]->funcs->set_abm_level( + res_pool->multiple_abms[inst], strength); + } else { + if (res_pool->abm->funcs->set_abm_level) + result = res_pool->abm->funcs->set_abm_level( + res_pool->abm, strength); + } + + return result; +} + bool dmcu_load_iram(struct dmcu *dmcu, struct dmcu_iram_parameters params) { diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h index 600da3e33126..548c8ff6ddb4 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -146,6 +146,16 @@ bool dmub_init_abm_config(struct resource_pool *res_pool, struct dmcu_iram_parameters params, unsigned int inst); +bool dmub_is_abm_supported(struct resource_pool *res_pool, + unsigned int inst); +bool dmub_set_abm_event(struct resource_pool *res_pool, + unsigned int full_screen, unsigned int trans_info, + unsigned int hdr_mode, unsigned int scaling_enable, + unsigned int scaling_strength_map, unsigned int inst); +bool dmub_set_abm_strength(struct resource_pool *res_pool, + unsigned int strength, + unsigned int inst); + void init_replay_config(struct dc_link *link, struct replay_config *pr_config); void set_replay_coasting_vtotal(struct dc_link *link, enum replay_coasting_vtotal_type type, |
