Commit 6ffaa6fc authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher

drm/amd/display: fix odm pipe management

There are issues removing surfaces/streams when odm is active.
This is a step to fix that
Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 661a8cd9
...@@ -1251,6 +1251,40 @@ bool dc_add_plane_to_context( ...@@ -1251,6 +1251,40 @@ bool dc_add_plane_to_context(
return true; return true;
} }
struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx)
{
struct pipe_ctx *bottom_pipe = pipe_ctx->bottom_pipe;
/* ODM should only be updated once per otg */
if (pipe_ctx->top_pipe)
return NULL;
while (bottom_pipe) {
if (bottom_pipe->stream_res.opp != pipe_ctx->stream_res.opp)
break;
bottom_pipe = bottom_pipe->bottom_pipe;
}
return bottom_pipe;
}
static bool dc_res_is_odm_bottom_pipe(struct pipe_ctx *pipe_ctx)
{
struct pipe_ctx *top_pipe = pipe_ctx->top_pipe;
bool result = false;
if (top_pipe && top_pipe->stream_res.opp == pipe_ctx->stream_res.opp)
return false;
while (top_pipe) {
if (!top_pipe->top_pipe && top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)
result = true;
top_pipe = top_pipe->top_pipe;
}
return result;
}
bool dc_remove_plane_from_context( bool dc_remove_plane_from_context(
const struct dc *dc, const struct dc *dc,
struct dc_stream_state *stream, struct dc_stream_state *stream,
...@@ -1274,10 +1308,14 @@ bool dc_remove_plane_from_context( ...@@ -1274,10 +1308,14 @@ bool dc_remove_plane_from_context(
/* release pipe for plane*/ /* release pipe for plane*/
for (i = pool->pipe_count - 1; i >= 0; i--) { for (i = pool->pipe_count - 1; i >= 0; i--) {
struct pipe_ctx *pipe_ctx; struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) { if (pipe_ctx->plane_state == plane_state) {
pipe_ctx = &context->res_ctx.pipe_ctx[i]; if (dc_res_is_odm_bottom_pipe(pipe_ctx)) {
pipe_ctx->plane_state = NULL;
pipe_ctx->bottom_pipe = NULL;
continue;
}
if (pipe_ctx->top_pipe) if (pipe_ctx->top_pipe)
pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe; pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe;
...@@ -1293,11 +1331,10 @@ bool dc_remove_plane_from_context( ...@@ -1293,11 +1331,10 @@ bool dc_remove_plane_from_context(
* For head pipe detach surfaces from pipe for tail * For head pipe detach surfaces from pipe for tail
* pipe just zero it out * pipe just zero it out
*/ */
if (!pipe_ctx->top_pipe || (!pipe_ctx->top_pipe->top_pipe && if (!pipe_ctx->top_pipe) {
pipe_ctx->top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)) {
pipe_ctx->top_pipe = NULL;
pipe_ctx->plane_state = NULL; pipe_ctx->plane_state = NULL;
pipe_ctx->bottom_pipe = NULL; if (!dc_res_get_odm_bottom_pipe(pipe_ctx))
pipe_ctx->bottom_pipe = NULL;
} else { } else {
memset(pipe_ctx, 0, sizeof(*pipe_ctx)); memset(pipe_ctx, 0, sizeof(*pipe_ctx));
} }
...@@ -1703,6 +1740,9 @@ enum dc_status dc_remove_stream_from_ctx( ...@@ -1703,6 +1740,9 @@ enum dc_status dc_remove_stream_from_ctx(
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
if (new_ctx->res_ctx.pipe_ctx[i].stream == stream && if (new_ctx->res_ctx.pipe_ctx[i].stream == stream &&
!new_ctx->res_ctx.pipe_ctx[i].top_pipe) { !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
struct pipe_ctx *odm_pipe =
dc_res_get_odm_bottom_pipe(&new_ctx->res_ctx.pipe_ctx[i]);
del_pipe = &new_ctx->res_ctx.pipe_ctx[i]; del_pipe = &new_ctx->res_ctx.pipe_ctx[i];
ASSERT(del_pipe->stream_res.stream_enc); ASSERT(del_pipe->stream_res.stream_enc);
...@@ -1727,6 +1767,10 @@ enum dc_status dc_remove_stream_from_ctx( ...@@ -1727,6 +1767,10 @@ enum dc_status dc_remove_stream_from_ctx(
dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream); dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream);
memset(del_pipe, 0, sizeof(*del_pipe)); memset(del_pipe, 0, sizeof(*del_pipe));
if (odm_pipe)
memset(odm_pipe, 0, sizeof(*odm_pipe));
break;
} }
} }
......
...@@ -172,4 +172,6 @@ void update_audio_usage( ...@@ -172,4 +172,6 @@ void update_audio_usage(
unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format);
struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment