mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
drm/amd/display: Retain phantom plane/stream if validation fails
commit 9b216b7e38 upstream
[Description]
- If we fail validation, we should retain the phantom
stream/planes
- Full updates assume that phantom pipes will be fully
removed, but if validation fails we keep the phantom
pipes
- Therefore we have to retain the plane/stream if validation
fails (since the refcount is decremented before validation,
and the expectation is that it's fully freed when the old
dc_state is released)
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Brian Chang <Brian.Chang@amd.com>
Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e61f0ad736
commit
647e12741e
@@ -3149,6 +3149,19 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
|||||||
|
|
||||||
if (update_type == UPDATE_TYPE_FULL) {
|
if (update_type == UPDATE_TYPE_FULL) {
|
||||||
if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
|
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();
|
BREAK_TO_DEBUGGER();
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1719,6 +1719,27 @@ static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
|
|||||||
return phantom_stream;
|
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
|
// return true if removed piped from ctx, false otherwise
|
||||||
bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
|
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,
|
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
|
||||||
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
||||||
.remove_phantom_pipes = dcn32_remove_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)
|
static uint32_t read_pipe_fuses(struct dc_context *ctx)
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ bool dcn32_release_post_bldn_3dlut(
|
|||||||
bool dcn32_remove_phantom_pipes(struct dc *dc,
|
bool dcn32_remove_phantom_pipes(struct dc *dc,
|
||||||
struct dc_state *context);
|
struct dc_state *context);
|
||||||
|
|
||||||
|
void dcn32_retain_phantom_pipes(struct dc *dc,
|
||||||
|
struct dc_state *context);
|
||||||
|
|
||||||
void dcn32_add_phantom_pipes(struct dc *dc,
|
void dcn32_add_phantom_pipes(struct dc *dc,
|
||||||
struct dc_state *context,
|
struct dc_state *context,
|
||||||
display_e2e_pipe_params_st *pipes,
|
display_e2e_pipe_params_st *pipes,
|
||||||
|
|||||||
@@ -1619,6 +1619,7 @@ static struct resource_funcs dcn321_res_pool_funcs = {
|
|||||||
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
|
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
|
||||||
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
||||||
.remove_phantom_pipes = dcn32_remove_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)
|
static uint32_t read_pipe_fuses(struct dc_context *ctx)
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ struct resource_funcs {
|
|||||||
unsigned int index);
|
unsigned int index);
|
||||||
|
|
||||||
bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context);
|
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);
|
void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user