summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Chen <leo.chen@amd.com>2026-06-11 13:28:59 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-07-01 11:17:51 -0400
commit19e01bbaa1e58ccc88acd45858ef4f70d21fa41f (patch)
tree1bd5d72dcbbb1697ffe3c8674b45caef6cc0bdb7
parent8b6ab8bdf835efb91c1d782b7c2cf32dad39238f (diff)
downloadlinux-stable-19e01bbaa1e58ccc88acd45858ef4f70d21fa41f.tar.gz
linux-stable-19e01bbaa1e58ccc88acd45858ef4f70d21fa41f.zip
drm/amd/display: Refactor Driver PG's skip PG logic
[Why & How] When driver allows idle optimization, no HW state should be modified further by DC. Refactor the skip PG logic in pg_cntl in DCN42. Reviewed-by: Ovidiu (Ovi) Bunea <ovidiu.bunea@amd.com> Signed-off-by: Leo Chen <leo.chen@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c150
1 files changed, 60 insertions, 90 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c b/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
index 2fc17dc510df..78b33b2dbae8 100644
--- a/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
@@ -61,6 +61,21 @@ static void pg_cntl42_restore_global_fgcg_rep(struct pg_cntl *pg_cntl,
REG_UPDATE(AZ_CLOCK_CNTL, AZ_GLOBAL_FGCG_REP_DIS, state->az_rep_fgcg);
}
+static bool should_skip_pg_control(bool dc_in_idle_opt, bool power_on, bool block_enabled)
+{
+ if (dc_in_idle_opt)
+ return true;
+
+ if (power_on && block_enabled)
+ return true;
+
+ if (!power_on && !block_enabled)
+ return true;
+
+ return false;
+}
+
+
static bool pg_cntl42_dsc_pg_status(struct pg_cntl *pg_cntl, unsigned int dsc_inst)
{
struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl);
@@ -94,23 +109,14 @@ void pg_cntl42_dsc_pg_control(struct pg_cntl *pg_cntl, unsigned int dsc_inst, bo
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl = 0;
struct dcn42_global_fgcg_rep_state fgcg_rep_state = {0};
- bool block_enabled;
-
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->debug.disable_dsc_power_gate ||
- pg_cntl->ctx->dc->idle_optimizations_allowed;
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg || pg_cntl->ctx->dc->debug.disable_dsc_power_gate;
- if (skip_pg && !power_on)
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_dsc_pg_status(pg_cntl, dsc_inst);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
+ bool block_enabled = pg_cntl42_dsc_pg_status(pg_cntl, dsc_inst);
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
if (org_ip_request_cntl == 0)
@@ -201,23 +207,16 @@ void pg_cntl42_hubp_dpp_pg_control(struct pg_cntl *pg_cntl, unsigned int hubp_dp
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl;
struct dcn42_global_fgcg_rep_state fgcg_rep_state = {0};
- bool block_enabled;
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->debug.disable_hubp_power_gate ||
- pg_cntl->ctx->dc->debug.disable_dpp_power_gate ||
- pg_cntl->ctx->dc->idle_optimizations_allowed;
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
+ pg_cntl->ctx->dc->debug.disable_hubp_power_gate ||
+ pg_cntl->ctx->dc->debug.disable_dpp_power_gate;
- if (skip_pg && !power_on)
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
+ bool block_enabled = pg_cntl42_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst);
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
if (org_ip_request_cntl == 0)
@@ -283,22 +282,17 @@ void pg_cntl42_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on)
uint32_t org_ip_request_cntl;
uint32_t power_forceon;
struct dcn42_global_fgcg_rep_state fgcg_rep_state = {0};
- bool block_enabled;
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->debug.disable_hpo_power_gate ||
- pg_cntl->ctx->dc->idle_optimizations_allowed;
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
+ pg_cntl->ctx->dc->debug.disable_hpo_power_gate;
- if (skip_pg && !power_on)
+ if (block_pg_disabled && !power_on)
+ return;
+
+ bool block_enabled = pg_cntl42_hpo_pg_status(pg_cntl);
+
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
return;
- block_enabled = pg_cntl42_hpo_pg_status(pg_cntl);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
REG_GET(DOMAIN25_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon);
if (power_forceon)
@@ -337,23 +331,17 @@ void pg_cntl42_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on)
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl;
uint32_t power_forceon;
- bool block_enabled;
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->idle_optimizations_allowed ||
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
pg_cntl->ctx->dc->debug.disable_io_clk_power_gate;
- if (skip_pg && !power_on)
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_io_clk_status(pg_cntl);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
+ bool block_enabled = pg_cntl42_io_clk_status(pg_cntl);
+
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
REG_GET(DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon);
if (power_forceon)
@@ -435,24 +423,16 @@ void pg_cntl42_mem_pg_control(struct pg_cntl *pg_cntl, bool power_on)
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl;
uint32_t power_forceon;
- bool block_enabled;
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->idle_optimizations_allowed ||
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
pg_cntl->ctx->dc->debug.disable_mem_power_gate;
- if (skip_pg && !power_on)
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_mem_status(pg_cntl);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
-
+ bool block_enabled = pg_cntl42_mem_status(pg_cntl);
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
REG_GET(DOMAIN23_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon);
if (power_forceon)
return;
@@ -490,22 +470,16 @@ void pg_cntl42_dio_pg_control(struct pg_cntl *pg_cntl, bool power_on)
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl;
struct dcn42_global_fgcg_rep_state fgcg_rep_state = {0};
- bool block_enabled;
- bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->idle_optimizations_allowed ||
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
pg_cntl->ctx->dc->debug.disable_dio_power_gate;
- if (skip_pg && !power_on)
+
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_dio_pg_status(pg_cntl);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
+ bool block_enabled = pg_cntl42_dio_pg_status(pg_cntl);
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
if (org_ip_request_cntl == 0)
@@ -531,23 +505,19 @@ void pg_cntl42_plane_otg_pg_control(struct pg_cntl *pg_cntl, bool power_on)
uint32_t pwr_status = power_on ? 0 : 2;
uint32_t org_ip_request_cntl;
unsigned int i;
- bool block_enabled;
bool all_mpcc_disabled = true, all_opp_disabled = true;
bool all_optc_disabled = true, all_stream_disabled = true;
- if (pg_cntl->ctx->dc->debug.ignore_pg ||
- pg_cntl->ctx->dc->debug.disable_optc_power_gate ||
- pg_cntl->ctx->dc->idle_optimizations_allowed)
+ bool block_pg_disabled = pg_cntl->ctx->dc->debug.ignore_pg ||
+ pg_cntl->ctx->dc->debug.disable_optc_power_gate;
+
+ if (block_pg_disabled && !power_on)
return;
- block_enabled = pg_cntl42_plane_otg_status(pg_cntl);
- if (power_on) {
- if (block_enabled)
- return;
- } else {
- if (!block_enabled)
- return;
- }
+ bool block_enabled = pg_cntl42_plane_otg_status(pg_cntl);
+
+ if (should_skip_pg_control(pg_cntl->ctx->dc->idle_optimizations_allowed, power_on, block_enabled))
+ return;
for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &pg_cntl->ctx->dc->current_state->res_ctx.pipe_ctx[i];