| From da5e14909776edea4462672fb4a3007802d262e7 Mon Sep 17 00:00:00 2001 |
| From: Aurabindo Pillai <aurabindo.pillai@amd.com> |
| Date: Fri, 24 Mar 2023 10:42:37 -0400 |
| Subject: drm/amd/display: Fix hang when skipping modeset |
| |
| From: Aurabindo Pillai <aurabindo.pillai@amd.com> |
| |
| commit da5e14909776edea4462672fb4a3007802d262e7 upstream. |
| |
| [Why&How] |
| |
| When skipping full modeset since the only state change was a front porch |
| change, the DC commit sequence requires extra checks to handle non |
| existant plane states being asked to be removed from context. |
| |
| Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com> |
| Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com> |
| Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> |
| Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- |
| drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ |
| 2 files changed, 7 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |
| +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |
| @@ -9020,6 +9020,8 @@ static void amdgpu_dm_commit_planes(stru |
| continue; |
| |
| dc_plane = dm_new_plane_state->dc_state; |
| + if (!dc_plane) |
| + continue; |
| |
| bundle->surface_updates[planes_count].surface = dc_plane; |
| if (new_pcrtc_state->color_mgmt_changed) { |
| @@ -10550,8 +10552,9 @@ static int dm_update_plane_state(struct |
| return -EINVAL; |
| } |
| |
| + if (dm_old_plane_state->dc_state) |
| + dc_plane_state_release(dm_old_plane_state->dc_state); |
| |
| - dc_plane_state_release(dm_old_plane_state->dc_state); |
| dm_new_plane_state->dc_state = NULL; |
| |
| *lock_and_validation_needed = true; |
| --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c |
| +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c |
| @@ -1434,6 +1434,9 @@ bool dc_remove_plane_from_context( |
| struct dc_stream_status *stream_status = NULL; |
| struct resource_pool *pool = dc->res_pool; |
| |
| + if (!plane_state) |
| + return true; |
| + |
| for (i = 0; i < context->stream_count; i++) |
| if (context->streams[i] == stream) { |
| stream_status = &context->stream_status[i]; |