mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
drm/amd/display: Use min transition for SubVP into MPO
[ Upstream commit 9e7d03e8b0 ]
[Description]
- For SubVP transitioning into MPO, we want to
use a minimal transition to prevent transient
underflow
- Transitioning a phantom pipe directly into a
"real" pipe can result in underflow due to the
HUBP still having it's "phantom" programming
when HUBP is unblanked (have to wait for next
VUPDATE of the new OTG)
- Also ensure subvp pipe lock is acquired early
enough for programming in dc_commit_state_no_check
- When disabling phantom planes, enable phantom OTG
first so the disable gets the double buffer update
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Alan Liu <HaoPing.Liu@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: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cda74cdc28
commit
d5368e054e
@@ -1070,6 +1070,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||
int i, j;
|
||||
struct dc_state *dangling_context = dc_create_state(dc);
|
||||
struct dc_state *current_ctx;
|
||||
struct pipe_ctx *pipe;
|
||||
|
||||
if (dangling_context == NULL)
|
||||
return;
|
||||
@@ -1112,6 +1113,16 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||
}
|
||||
|
||||
if (should_disable && old_stream) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
/* When disabling plane for a phantom pipe, we must turn on the
|
||||
* phantom OTG so the disable programming gets the double buffer
|
||||
* update. Otherwise the pipe will be left in a partially disabled
|
||||
* state that can result in underflow or hang when enabling it
|
||||
* again for different use.
|
||||
*/
|
||||
if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
|
||||
}
|
||||
dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
|
||||
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
|
||||
|
||||
@@ -1760,6 +1771,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
||||
context->stream_count == 0)
|
||||
dc->hwss.prepare_bandwidth(dc, context);
|
||||
|
||||
/* When SubVP is active, all HW programming must be done while
|
||||
* SubVP lock is acquired
|
||||
*/
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
|
||||
|
||||
if (dc->debug.enable_double_buffered_dsc_pg_support)
|
||||
dc->hwss.update_dsc_pg(dc, context, false);
|
||||
|
||||
@@ -1787,9 +1804,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
||||
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
|
||||
}
|
||||
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
|
||||
|
||||
result = dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
|
||||
if (result != DC_OK) {
|
||||
@@ -3576,7 +3590,6 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
||||
|
||||
struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
|
||||
bool force_minimal_pipe_splitting = false;
|
||||
uint32_t i;
|
||||
|
||||
*is_plane_addition = false;
|
||||
|
||||
@@ -3608,27 +3621,11 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
/* For SubVP pipe split case when adding MPO video
|
||||
* we need to add a minimal transition. In this case
|
||||
* there will be 2 streams (1 main stream, 1 phantom
|
||||
* stream).
|
||||
/* For SubVP when adding MPO video we need to add a minimal transition.
|
||||
*/
|
||||
if (cur_stream_status &&
|
||||
dc->current_state->stream_count == 2 &&
|
||||
stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
bool is_pipe_split = false;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream &&
|
||||
(dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe ||
|
||||
dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) {
|
||||
is_pipe_split = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_stream_status && stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
/* determine if minimal transition is required due to SubVP*/
|
||||
if (surface_count > 0 && is_pipe_split) {
|
||||
if (surface_count > 0) {
|
||||
if (cur_stream_status->plane_count > surface_count) {
|
||||
force_minimal_pipe_splitting = true;
|
||||
} else if (cur_stream_status->plane_count < surface_count) {
|
||||
|
||||
Reference in New Issue
Block a user