drm/amd/display: Retain phantom plane/stream if validation fails
authorjsg <jsg@openbsd.org>
Thu, 17 Aug 2023 04:11:04 +0000 (04:11 +0000)
committerjsg <jsg@openbsd.org>
Thu, 17 Aug 2023 04:11:04 +0000 (04:11 +0000)
From Alvin Lee
647e12741e6d16eccb679d2fefa7ec71496b6337 in linux-6.1.y/6.1.46
9b216b7e38f5381bcc3ad21c5ac614aa577ab8f2 in mainline linux

sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c
sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c
sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h
sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c
sys/dev/pci/drm/amd/display/dc/inc/core_types.h

index f16a9e4..674ab6d 100644 (file)
@@ -3149,6 +3149,19 @@ static bool update_planes_and_stream_state(struct dc *dc,
 
        if (update_type == UPDATE_TYPE_FULL) {
                if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
+                       /* For phantom pipes we remove and create a new set of phantom pipes
+                        * for each full update (because we don't know if we'll need phantom
+                        * pipes until after the first round of validation). However, if validation
+                        * fails we need to keep the existing phantom pipes (because we don't update
+                        * the dc->current_state).
+                        *
+                        * The phantom stream/plane refcount is decremented for validation because
+                        * we assume it'll be removed (the free comes when the dc_state is freed),
+                        * but if validation fails we have to increment back the refcount so it's
+                        * consistent.
+                        */
+                       if (dc->res_pool->funcs->retain_phantom_pipes)
+                               dc->res_pool->funcs->retain_phantom_pipes(dc, dc->current_state);
                        BREAK_TO_DEBUGGER();
                        goto fail;
                }
index 814620e..2b8700b 100644 (file)
@@ -1719,6 +1719,27 @@ static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
        return phantom_stream;
 }
 
+void dcn32_retain_phantom_pipes(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       struct dc_plane_state *phantom_plane = NULL;
+       struct dc_stream_state *phantom_stream = NULL;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe->top_pipe && !pipe->prev_odm_pipe &&
+                               pipe->plane_state && pipe->stream &&
+                               pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       phantom_plane = pipe->plane_state;
+                       phantom_stream = pipe->stream;
+
+                       dc_plane_state_retain(phantom_plane);
+                       dc_stream_retain(phantom_stream);
+               }
+       }
+}
+
 // return true if removed piped from ctx, false otherwise
 bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
 {
@@ -2035,6 +2056,7 @@ static struct resource_funcs dcn32_res_pool_funcs = {
        .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
        .add_phantom_pipes = dcn32_add_phantom_pipes,
        .remove_phantom_pipes = dcn32_remove_phantom_pipes,
+       .retain_phantom_pipes = dcn32_retain_phantom_pipes,
 };
 
 static uint32_t read_pipe_fuses(struct dc_context *ctx)
index 615244a..026cf13 100644 (file)
@@ -83,6 +83,9 @@ bool dcn32_release_post_bldn_3dlut(
 bool dcn32_remove_phantom_pipes(struct dc *dc,
                struct dc_state *context);
 
+void dcn32_retain_phantom_pipes(struct dc *dc,
+               struct dc_state *context);
+
 void dcn32_add_phantom_pipes(struct dc *dc,
                struct dc_state *context,
                display_e2e_pipe_params_st *pipes,
index 213ff36..aed92ce 100644 (file)
@@ -1619,6 +1619,7 @@ static struct resource_funcs dcn321_res_pool_funcs = {
        .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
        .add_phantom_pipes = dcn32_add_phantom_pipes,
        .remove_phantom_pipes = dcn32_remove_phantom_pipes,
+       .retain_phantom_pipes = dcn32_retain_phantom_pipes,
 };
 
 static uint32_t read_pipe_fuses(struct dc_context *ctx)
index c8d8a1d..4a968de 100644 (file)
@@ -234,6 +234,7 @@ struct resource_funcs {
             unsigned int index);
 
        bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context);
+       void (*retain_phantom_pipes)(struct dc *dc, struct dc_state *context);
        void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
 };