drm/amd/display: Add sequential ONO sequencing for DCN35
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Thu, 23 May 2024 15:53:27 +0000 (11:53 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 14 Jun 2024 20:17:14 +0000 (16:17 -0400)
[Why]
Adds support for performing the sequential ONO changes from DCN351
into DCN35 ASIC based on revision.

[How]
Check the revision and run the DCN351 sequences on applicable revisions.

Reviewed-by: Sung joon Kim <sungjoon.kim@amd.com>
Acked-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@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/dc.h
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c

index c78296b06b79cb7b60276a1e0f24e7d06a934b81..1008cab97c76737f53ac57e8cbad9379bca2ad0c 100644 (file)
@@ -291,6 +291,7 @@ struct dc_caps {
        uint8_t subvp_drr_vblank_start_margin_us;
        bool cursor_not_scaled;
        bool dcmode_power_limits_present;
+       bool sequential_ono;
 };
 
 struct dc_bug_wa {
index 2b3ba5971c6924064cdb17fe1ecc1c316bad3e32..4f87316e1318bbf9406dd594f829401ea13c6838 100644 (file)
@@ -1078,6 +1078,19 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
                update_state->pg_pipe_res_update[PG_OPTC][0] = false;
        }
 
+       if (dc->caps.sequential_ono) {
+               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+                       if (!update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                           !update_state->pg_pipe_res_update[PG_DPP][i]) {
+                               for (j = i - 1; j >= 0; j--) {
+                                       update_state->pg_pipe_res_update[PG_HUBP][j] = false;
+                                       update_state->pg_pipe_res_update[PG_DPP][j] = false;
+                               }
+
+                               break;
+                       }
+               }
+       }
 }
 
 void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
@@ -1177,6 +1190,19 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
        if (hpo_frl_stream_enc_acquired)
                update_state->pg_pipe_res_update[PG_HDMISTREAM][0] = true;
 
+       if (dc->caps.sequential_ono) {
+               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+                       if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                           update_state->pg_pipe_res_update[PG_DPP][i]) {
+                               for (j = i - 1; j >= 0; j--) {
+                                       update_state->pg_pipe_res_update[PG_HUBP][j] = true;
+                                       update_state->pg_pipe_res_update[PG_DPP][j] = true;
+                               }
+
+                               break;
+                       }
+               }
+       }
 }
 
 /**
@@ -1197,6 +1223,8 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
  *     ONO Region 2, DCPG 24: mpc opp optc dwb
  *     ONO Region 0, DCPG 22: dccg dio dcio - SKIPPED. will be pwr dwn after lono timer is armed
  *
+ * If sequential ONO is specified the order is modified from ONO Region 11 -> ONO Region 0 descending.
+ *
  * @dc: Current DC state
  * @update_state: update PG sequence states for HW block
  */
@@ -1216,19 +1244,35 @@ void dcn35_hw_block_power_down(struct dc *dc,
                        pg_cntl->funcs->hpo_pg_control(pg_cntl, false);
        }
 
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
-                       update_state->pg_pipe_res_update[PG_DPP][i]) {
-                       if (pg_cntl->funcs->hubp_dpp_pg_control)
-                               pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, false);
+       if (!dc->caps.sequential_ono) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                           update_state->pg_pipe_res_update[PG_DPP][i]) {
+                               if (pg_cntl->funcs->hubp_dpp_pg_control)
+                                       pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, false);
+                       }
                }
-       }
-       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++)
-               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
-                       if (pg_cntl->funcs->dsc_pg_control)
-                               pg_cntl->funcs->dsc_pg_control(pg_cntl, i, false);
+
+               for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+                       if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                               if (pg_cntl->funcs->dsc_pg_control)
+                                       pg_cntl->funcs->dsc_pg_control(pg_cntl, i, false);
+                       }
                }
+       } else {
+               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+                       if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                               if (pg_cntl->funcs->dsc_pg_control)
+                                       pg_cntl->funcs->dsc_pg_control(pg_cntl, i, false);
+                       }
 
+                       if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
+                           update_state->pg_pipe_res_update[PG_DPP][i]) {
+                               if (pg_cntl->funcs->hubp_dpp_pg_control)
+                                       pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, false);
+                       }
+               }
+       }
 
        /*this will need all the clients to unregister optc interruts let dmubfw handle this*/
        if (pg_cntl->funcs->plane_otg_pg_control)
@@ -1256,6 +1300,8 @@ void dcn35_hw_block_power_down(struct dc *dc,
  *     ONO Region 10, DCPG 3: dchubp3, dpp3
  *     ONO Region 3, DCPG 25: hpo - SKIPPED
  *
+ * If sequential ONO is specified the order is modified from ONO Region 0 -> ONO Region 11 ascending.
+ *
  * @dc: Current DC state
  * @update_state: update PG sequence states for HW block
  */
@@ -1274,11 +1320,13 @@ void dcn35_hw_block_power_up(struct dc *dc,
        if (pg_cntl->funcs->plane_otg_pg_control)
                pg_cntl->funcs->plane_otg_pg_control(pg_cntl, true);
 
-       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++)
-               if (update_state->pg_pipe_res_update[PG_DSC][i]) {
-                       if (pg_cntl->funcs->dsc_pg_control)
-                               pg_cntl->funcs->dsc_pg_control(pg_cntl, i, true);
-               }
+       if (!dc->caps.sequential_ono) {
+               for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++)
+                       if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                               if (pg_cntl->funcs->dsc_pg_control)
+                                       pg_cntl->funcs->dsc_pg_control(pg_cntl, i, true);
+                       }
+       }
 
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                if (update_state->pg_pipe_res_update[PG_HUBP][i] &&
@@ -1286,6 +1334,13 @@ void dcn35_hw_block_power_up(struct dc *dc,
                        if (pg_cntl->funcs->hubp_dpp_pg_control)
                                pg_cntl->funcs->hubp_dpp_pg_control(pg_cntl, i, true);
                }
+
+               if (dc->caps.sequential_ono) {
+                       if (update_state->pg_pipe_res_update[PG_DSC][i]) {
+                               if (pg_cntl->funcs->dsc_pg_control)
+                                       pg_cntl->funcs->dsc_pg_control(pg_cntl, i, true);
+                       }
+               }
        }
        if (update_state->pg_res_update[PG_HPO]) {
                if (pg_cntl->funcs->hpo_pg_control)
index 28c4599076989a4b09d8f2b5faa948b01323c29f..391f9f69a92384ee1059f964faada7f65fb937d1 100644 (file)
@@ -1891,6 +1891,10 @@ static bool dcn35_resource_construct(
         */
        dc->caps.max_disp_clock_khz_at_vmin = 650000;
 
+       /* Sequential ONO is based on ASIC. */
+       if (dc->ctx->asic_id.hw_internal_rev > 0x10)
+               dc->caps.sequential_ono = true;
+
        /* Use pipe context based otg sync logic */
        dc->config.use_pipe_ctx_sync_logic = true;