drm/amd/display: dcn32/321 dsc_pg_control not executed properly
authorHersen Wu <hersenxs.wu@amd.com>
Thu, 9 Feb 2023 23:35:00 +0000 (18:35 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 28 Feb 2023 19:29:36 +0000 (14:29 -0500)
[why]
during boot up or resume from s3, hw default value of
domain_power_forceon is 1. when program domain_power_gate
to 1 to power down hw block, hw will not change to power
off due to domain_power_forceon = 1.

[how]
enable_power_gating_plane(true) should be executed to set
domain_power_forceon to 0 before dsc_pg_control.
dsc_pg_control is already called by dcn3x_init_hw-->
init_pipes--> dsc_pg_control. no need be programmed with
dcn3x_init_hw one more time.
to trigger dchub, dsc block power state change, need
program dc_ip_request_cntl to notify hw block.

Reviewed-by: Nevenko Stupar <Nevenko.Stupar@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c

index b83873a..8b5181f 100644 (file)
@@ -190,10 +190,15 @@ void dcn20_enable_power_gating_plane(
        bool enable)
 {
        bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
 
        if (enable)
                force_on = false;
 
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
        /* DCHUBP0/1/2/3/4/5 */
        REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
        REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
@@ -224,6 +229,10 @@ void dcn20_enable_power_gating_plane(
                REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on);
        if (REG(DOMAIN21_PG_CONFIG))
                REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+
 }
 
 void dcn20_dccg_init(struct dce_hwseq *hws)
index 6ef85e7..1d243c5 100644 (file)
@@ -531,11 +531,6 @@ void dcn30_init_hw(struct dc *dc)
                }
        }
 
-       /* Power gate DSCs */
-       for (i = 0; i < res_pool->res_cap->num_dsc; i++)
-               if (hws->funcs.dsc_pg_control != NULL)
-                       hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
-
        /* we want to turn off all dp displays before doing detection */
        link_blank_all_dp_displays(dc);
 
index 16f8921..f667f2a 100644 (file)
@@ -131,10 +131,15 @@ void dcn32_enable_power_gating_plane(
        bool enable)
 {
        bool force_on = true; /* disable power gating */
+       uint32_t org_ip_request_cntl = 0;
 
        if (enable)
                force_on = false;
 
+       REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+
        /* DCHUBP0/1/2/3 */
        REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
        REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
@@ -146,6 +151,9 @@ void dcn32_enable_power_gating_plane(
        REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
        REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
        REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+
+       if (org_ip_request_cntl == 0)
+               REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
 }
 
 void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
@@ -786,10 +794,11 @@ void dcn32_init_hw(struct dc *dc)
                }
        }
 
-       /* Power gate DSCs */
-       for (i = 0; i < res_pool->res_cap->num_dsc; i++)
-               if (hws->funcs.dsc_pg_control != NULL)
-                       hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
+       /* enable_power_gating_plane before dsc_pg_control because
+        * FORCEON = 1 with hw default value on bootup, resume from s3
+        */
+       if (hws->funcs.enable_power_gating_plane)
+               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
 
        /* we want to turn off all dp displays before doing detection */
        link_blank_all_dp_displays(dc);
@@ -886,8 +895,6 @@ void dcn32_init_hw(struct dc *dc)
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
-       if (hws->funcs.enable_power_gating_plane)
-               hws->funcs.enable_power_gating_plane(dc->hwseq, true);
 
        if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
                dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);