From: Yongqiang Sun Date: Tue, 10 Oct 2017 14:01:33 -0400 Subject: drm/amd/display: WA for 3 display play video hot plug. Git-commit: 62c933f9c6bf287b5b911a1eb838bc942eaa7202 Patch-mainline: v4.15-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 Three monitor connected and playing a video will occupy all 4 pipes, if hot plug forth display, commit streams will be failed due to no free pipe can be found. Work around: When forth monitor connected, mark video plane as a fake plane, remove it in dc, keep it in dm and report address to OS, until OS turn off MPO. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher Acked-by: Petr Tesarik --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++----- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 14 ++++++++------ drivers/gpu/drm/amd/display/dc/dc.h | 6 +++--- drivers/gpu/drm/amd/display/dc/inc/core_status.h | 15 ++++++++------- 5 files changed, 26 insertions(+), 23 deletions(-) --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2794,7 +2794,7 @@ int amdgpu_dm_connector_mode_valid(struc stream->src.height = mode->vdisplay; stream->dst = stream->src; - if (dc_validate_stream(adev->dm.dc, stream)) + if (dc_validate_stream(adev->dm.dc, stream) == DC_OK) result = MODE_OK; dc_stream_release(stream); @@ -2839,7 +2839,7 @@ static int dm_crtc_helper_atomic_check(s if (!dm_crtc_state->stream) return 0; - if (dc_validate_stream(dc, dm_crtc_state->stream)) + if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) return 0; return ret; @@ -3034,7 +3034,7 @@ static int dm_plane_atomic_check(struct if (!dm_plane_state->dc_state) return 0; - if (dc_validate_plane(dc, dm_plane_state->dc_state)) + if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) return 0; return -EINVAL; @@ -4464,10 +4464,10 @@ static int dm_update_crtcs_state(struct crtc->base.id); /* i.e. reset mode */ - if (!dc_remove_stream_from_ctx( + if (dc_remove_stream_from_ctx( dc, dm_state->context, - dm_old_crtc_state->stream)) { + dm_old_crtc_state->stream) != DC_OK) { ret = -EINVAL; goto fail; } --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -793,7 +793,7 @@ bool dc_enable_stereo( * Applies given context to HW and copy it into current context. * It's up to the user to release the src context afterwards. */ -static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) +static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context) { struct dc_bios *dcb = dc->ctx->dc_bios; enum dc_status result = DC_ERROR_UNEXPECTED; @@ -869,7 +869,7 @@ static bool dc_commit_state_no_check(str dc->hwss.optimize_shared_resources(dc); - return (result == DC_OK); + return result; } bool dc_commit_state(struct dc *dc, struct dc_state *context) --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1503,7 +1503,7 @@ enum dc_status dc_add_stream_to_ctx( return res; } -bool dc_remove_stream_from_ctx( +enum dc_status dc_remove_stream_from_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream) @@ -2756,7 +2756,7 @@ void resource_build_bit_depth_reduction_ fmt_bit_depth->pixel_encoding = pixel_encoding; } -bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) +enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) { struct dc *core_dc = dc; struct dc_link *link = stream->sink->link; @@ -2780,14 +2780,16 @@ bool dc_validate_stream(struct dc *dc, s link, &stream->timing); - return res == DC_OK; + return res; } -bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) +enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) { + enum dc_status res = DC_OK; + /* TODO For now validates pixel format only */ if (dc->res_pool->funcs->validate_plane) - return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps) == DC_OK; + return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps); - return true; + return res; } --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -686,7 +686,7 @@ enum dc_status dc_add_stream_to_ctx( struct dc_state *new_ctx, struct dc_stream_state *stream); -bool dc_remove_stream_from_ctx( +enum dc_status dc_remove_stream_from_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream); @@ -725,9 +725,9 @@ struct dc_validation_set { uint8_t plane_count; }; -bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); +enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); -bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); +enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); enum dc_status dc_validate_global_state( struct dc *dc, --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -35,13 +35,14 @@ enum dc_status { DC_FAIL_CONTROLLER_VALIDATE = 5, DC_FAIL_ENC_VALIDATE = 6, DC_FAIL_ATTACH_SURFACES = 7, - DC_FAIL_SURFACE_VALIDATE = 8, - DC_NO_DP_LINK_BANDWIDTH = 9, - DC_EXCEED_DONGLE_MAX_CLK = 10, - DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11, - DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */ - DC_FAIL_SCALING = 13, - DC_FAIL_DP_LINK_TRAINING = 14, + DC_FAIL_DETACH_SURFACES = 8, + DC_FAIL_SURFACE_VALIDATE = 9, + DC_NO_DP_LINK_BANDWIDTH = 10, + DC_EXCEED_DONGLE_MAX_CLK = 11, + DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12, + DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */ + DC_FAIL_SCALING = 14, + DC_FAIL_DP_LINK_TRAINING = 15, DC_ERROR_UNEXPECTED = -1 };