drm/amd/display: Add more checks for DSC / HUBP ONO guarantees
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Wed, 21 May 2025 20:40:25 +0000 (16:40 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Jun 2025 17:05:12 +0000 (13:05 -0400)
[WHY]
For non-zero DSC instances it's possible that the HUBP domain required
to drive it for sequential ONO ASICs isn't met, potentially causing
the logic to the tile to enter an undefined state leading to a system
hang.

[HOW]
Add more checks to ensure that the HUBP domain matching the DSC instance
is appropriately powered.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Duncan Ma <duncan.ma@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit da63df07112e5a9857a8d2aaa04255c4206754ec)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c

index c814d957305adae7e20db81d37b2b8df068f0f98..a267f574b61937cbc8ce67169c76ea199c86137e 100644 (file)
@@ -1047,6 +1047,15 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
                        if (dc->caps.sequential_ono) {
                                update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->stream_res.dsc->inst] = false;
                                update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->stream_res.dsc->inst] = false;
+
+                               /* All HUBP/DPP instances must be powered if the DSC inst != HUBP inst */
+                               if (!pipe_ctx->top_pipe && pipe_ctx->plane_res.hubp &&
+                                   pipe_ctx->plane_res.hubp->inst != pipe_ctx->stream_res.dsc->inst) {
+                                       for (j = 0; j < dc->res_pool->pipe_count; ++j) {
+                                               update_state->pg_pipe_res_update[PG_HUBP][j] = false;
+                                               update_state->pg_pipe_res_update[PG_DPP][j] = false;
+                                       }
+                               }
                        }
                }
 
@@ -1193,6 +1202,25 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
                update_state->pg_pipe_res_update[PG_HDMISTREAM][0] = true;
 
        if (dc->caps.sequential_ono) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
+
+                       if (new_pipe->stream_res.dsc && !new_pipe->top_pipe &&
+                           update_state->pg_pipe_res_update[PG_DSC][new_pipe->stream_res.dsc->inst]) {
+                               update_state->pg_pipe_res_update[PG_HUBP][new_pipe->stream_res.dsc->inst] = true;
+                               update_state->pg_pipe_res_update[PG_DPP][new_pipe->stream_res.dsc->inst] = true;
+
+                               /* All HUBP/DPP instances must be powered if the DSC inst != HUBP inst */
+                               if (new_pipe->plane_res.hubp &&
+                                   new_pipe->plane_res.hubp->inst != new_pipe->stream_res.dsc->inst) {
+                                       for (j = 0; j < dc->res_pool->pipe_count; ++j) {
+                                               update_state->pg_pipe_res_update[PG_HUBP][j] = true;
+                                               update_state->pg_pipe_res_update[PG_DPP][j] = true;
+                                       }
+                               }
+                       }
+               }
+
                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]) {