summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/modules
diff options
context:
space:
mode:
authorChenyu Chen <chen-yu.chen@amd.com>2026-03-05 20:11:50 +0800
committerAlex Deucher <alexander.deucher@amd.com>2026-07-14 19:12:34 -0400
commit7b0cc308521696107828b0c6c72c5793fa279cbd (patch)
treeb11f5b8073880dfeb5739f40222c8922b6ffa729 /drivers/gpu/drm/amd/display/modules
parent5b69770e945caa1bef6c4848bb279ec09d3e9d4f (diff)
downloadlinux-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')
-rw-r--r--drivers/gpu/drm/amd/display/modules/inc/mod_power.h11
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_abm.c126
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_helpers.h10
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,