aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display
diff options
context:
space:
mode:
authorDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>2019-03-08 20:16:45 -0500
committerAlex Deucher <alexander.deucher@amd.com>2019-03-21 00:39:49 -0400
commit6ffaa6fcd06add240abe681f9b6da7fef742b85d (patch)
treef2f60ace33ed3c21fd1ccd611db17166d97d705b /drivers/gpu/drm/amd/display
parent661a8cd9516b182c80fff1b2fdfb1b1e42e212d1 (diff)
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: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c58
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/resource.h2
2 files changed, 53 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 13f99b11aaa6..3c9df3703e46 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1251,6 +1251,40 @@ bool dc_add_plane_to_context(
1251 return true; 1251 return true;
1252} 1252}
1253 1253
1254struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx)
1255{
1256 struct pipe_ctx *bottom_pipe = pipe_ctx->bottom_pipe;
1257
1258 /* ODM should only be updated once per otg */
1259 if (pipe_ctx->top_pipe)
1260 return NULL;
1261
1262 while (bottom_pipe) {
1263 if (bottom_pipe->stream_res.opp != pipe_ctx->stream_res.opp)
1264 break;
1265 bottom_pipe = bottom_pipe->bottom_pipe;
1266 }
1267
1268 return bottom_pipe;
1269}
1270
1271static bool dc_res_is_odm_bottom_pipe(struct pipe_ctx *pipe_ctx)
1272{
1273 struct pipe_ctx *top_pipe = pipe_ctx->top_pipe;
1274 bool result = false;
1275
1276 if (top_pipe && top_pipe->stream_res.opp == pipe_ctx->stream_res.opp)
1277 return false;
1278
1279 while (top_pipe) {
1280 if (!top_pipe->top_pipe && top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)
1281 result = true;
1282 top_pipe = top_pipe->top_pipe;
1283 }
1284
1285 return result;
1286}
1287
1254bool dc_remove_plane_from_context( 1288bool dc_remove_plane_from_context(
1255 const struct dc *dc, 1289 const struct dc *dc,
1256 struct dc_stream_state *stream, 1290 struct dc_stream_state *stream,
@@ -1274,10 +1308,14 @@ bool dc_remove_plane_from_context(
1274 1308
1275 /* release pipe for plane*/ 1309 /* release pipe for plane*/
1276 for (i = pool->pipe_count - 1; i >= 0; i--) { 1310 for (i = pool->pipe_count - 1; i >= 0; i--) {
1277 struct pipe_ctx *pipe_ctx; 1311 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1278 1312
1279 if (context->res_ctx.pipe_ctx[i].plane_state == plane_state) { 1313 if (pipe_ctx->plane_state == plane_state) {
1280 pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1314 if (dc_res_is_odm_bottom_pipe(pipe_ctx)) {
1315 pipe_ctx->plane_state = NULL;
1316 pipe_ctx->bottom_pipe = NULL;
1317 continue;
1318 }
1281 1319
1282 if (pipe_ctx->top_pipe) 1320 if (pipe_ctx->top_pipe)
1283 pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe; 1321 pipe_ctx->top_pipe->bottom_pipe = pipe_ctx->bottom_pipe;
@@ -1293,11 +1331,10 @@ bool dc_remove_plane_from_context(
1293 * For head pipe detach surfaces from pipe for tail 1331 * For head pipe detach surfaces from pipe for tail
1294 * pipe just zero it out 1332 * pipe just zero it out
1295 */ 1333 */
1296 if (!pipe_ctx->top_pipe || (!pipe_ctx->top_pipe->top_pipe && 1334 if (!pipe_ctx->top_pipe) {
1297 pipe_ctx->top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)) {
1298 pipe_ctx->top_pipe = NULL;
1299 pipe_ctx->plane_state = NULL; 1335 pipe_ctx->plane_state = NULL;
1300 pipe_ctx->bottom_pipe = NULL; 1336 if (!dc_res_get_odm_bottom_pipe(pipe_ctx))
1337 pipe_ctx->bottom_pipe = NULL;
1301 } else { 1338 } else {
1302 memset(pipe_ctx, 0, sizeof(*pipe_ctx)); 1339 memset(pipe_ctx, 0, sizeof(*pipe_ctx));
1303 } 1340 }
@@ -1703,6 +1740,9 @@ enum dc_status dc_remove_stream_from_ctx(
1703 for (i = 0; i < MAX_PIPES; i++) { 1740 for (i = 0; i < MAX_PIPES; i++) {
1704 if (new_ctx->res_ctx.pipe_ctx[i].stream == stream && 1741 if (new_ctx->res_ctx.pipe_ctx[i].stream == stream &&
1705 !new_ctx->res_ctx.pipe_ctx[i].top_pipe) { 1742 !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
1743 struct pipe_ctx *odm_pipe =
1744 dc_res_get_odm_bottom_pipe(&new_ctx->res_ctx.pipe_ctx[i]);
1745
1706 del_pipe = &new_ctx->res_ctx.pipe_ctx[i]; 1746 del_pipe = &new_ctx->res_ctx.pipe_ctx[i];
1707 1747
1708 ASSERT(del_pipe->stream_res.stream_enc); 1748 ASSERT(del_pipe->stream_res.stream_enc);
@@ -1727,6 +1767,10 @@ enum dc_status dc_remove_stream_from_ctx(
1727 dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream); 1767 dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream);
1728 1768
1729 memset(del_pipe, 0, sizeof(*del_pipe)); 1769 memset(del_pipe, 0, sizeof(*del_pipe));
1770 if (odm_pipe)
1771 memset(odm_pipe, 0, sizeof(*odm_pipe));
1772
1773 break;
1730 } 1774 }
1731 } 1775 }
1732 1776
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 0086a2f1d21a..62e00a9f3184 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -172,4 +172,6 @@ void update_audio_usage(
172 172
173unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); 173unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format);
174 174
175struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx);
176
175#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ 177#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */