Skip to content

Commit 59de751

Browse files
Samson Tamalexdeucher
authored andcommitted
drm/amd/display: add ODM case when looking for first split pipe
[Why] When going from ODM 2:1 single display case to max displays, second odm pipe needs to be repurposed for one of the new single displays. However, acquire_first_split_pipe() only handles MPC case and not ODM case [How] Add ODM conditions in acquire_first_split_pipe() Add commit_minimal_transition_state() in commit_streams() to handle odm 2:1 exit first, and then process new streams Handle ODM condition in commit_minimal_transition_state() Cc: Mario Limonciello <[email protected]> Cc: Alex Deucher <[email protected]> Cc: [email protected] Acked-by: Stylon Wang <[email protected]> Signed-off-by: Samson Tam <[email protected]> Reviewed-by: Alvin Lee <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 99b3886 commit 59de751

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
19811981
return result;
19821982
}
19831983

1984+
static bool commit_minimal_transition_state(struct dc *dc,
1985+
struct dc_state *transition_base_context);
1986+
19841987
/**
19851988
* dc_commit_streams - Commit current stream state
19861989
*
@@ -2002,6 +2005,8 @@ enum dc_status dc_commit_streams(struct dc *dc,
20022005
struct dc_state *context;
20032006
enum dc_status res = DC_OK;
20042007
struct dc_validation_set set[MAX_STREAMS] = {0};
2008+
struct pipe_ctx *pipe;
2009+
bool handle_exit_odm2to1 = false;
20052010

20062011
if (dc->ctx->dce_environment == DCE_ENV_VIRTUAL_HW)
20072012
return res;
@@ -2026,6 +2031,22 @@ enum dc_status dc_commit_streams(struct dc *dc,
20262031
}
20272032
}
20282033

2034+
/* Check for case where we are going from odm 2:1 to max
2035+
* pipe scenario. For these cases, we will call
2036+
* commit_minimal_transition_state() to exit out of odm 2:1
2037+
* first before processing new streams
2038+
*/
2039+
if (stream_count == dc->res_pool->pipe_count) {
2040+
for (i = 0; i < dc->res_pool->pipe_count; i++) {
2041+
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
2042+
if (pipe->next_odm_pipe)
2043+
handle_exit_odm2to1 = true;
2044+
}
2045+
}
2046+
2047+
if (handle_exit_odm2to1)
2048+
res = commit_minimal_transition_state(dc, dc->current_state);
2049+
20292050
context = dc_create_state(dc);
20302051
if (!context)
20312052
goto context_alloc_fail;
@@ -3872,6 +3893,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
38723893
unsigned int i, j;
38733894
unsigned int pipe_in_use = 0;
38743895
bool subvp_in_use = false;
3896+
bool odm_in_use = false;
38753897

38763898
if (!transition_context)
38773899
return false;
@@ -3900,6 +3922,18 @@ static bool commit_minimal_transition_state(struct dc *dc,
39003922
}
39013923
}
39023924

3925+
/* If ODM is enabled and we are adding or removing planes from any ODM
3926+
* pipe, we must use the minimal transition.
3927+
*/
3928+
for (i = 0; i < dc->res_pool->pipe_count; i++) {
3929+
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
3930+
3931+
if (pipe->stream && pipe->next_odm_pipe) {
3932+
odm_in_use = true;
3933+
break;
3934+
}
3935+
}
3936+
39033937
/* When the OS add a new surface if we have been used all of pipes with odm combine
39043938
* and mpc split feature, it need use commit_minimal_transition_state to transition safely.
39053939
* After OS exit MPO, it will back to use odm and mpc split with all of pipes, we need
@@ -3908,7 +3942,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
39083942
* Reduce the scenarios to use dc_commit_state_no_check in the stage of flip. Especially
39093943
* enter/exit MPO when DCN still have enough resources.
39103944
*/
3911-
if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use) {
3945+
if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use && !odm_in_use) {
39123946
dc_release_state(transition_context);
39133947
return true;
39143948
}

drivers/gpu/drm/amd/display/dc/core/dc_resource.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,26 @@ static int acquire_first_split_pipe(
14441444
split_pipe->plane_res.mpcc_inst = pool->dpps[i]->inst;
14451445
split_pipe->pipe_idx = i;
14461446

1447+
split_pipe->stream = stream;
1448+
return i;
1449+
} else if (split_pipe->prev_odm_pipe &&
1450+
split_pipe->prev_odm_pipe->plane_state == split_pipe->plane_state) {
1451+
split_pipe->prev_odm_pipe->next_odm_pipe = split_pipe->next_odm_pipe;
1452+
if (split_pipe->next_odm_pipe)
1453+
split_pipe->next_odm_pipe->prev_odm_pipe = split_pipe->prev_odm_pipe;
1454+
1455+
if (split_pipe->prev_odm_pipe->plane_state)
1456+
resource_build_scaling_params(split_pipe->prev_odm_pipe);
1457+
1458+
memset(split_pipe, 0, sizeof(*split_pipe));
1459+
split_pipe->stream_res.tg = pool->timing_generators[i];
1460+
split_pipe->plane_res.hubp = pool->hubps[i];
1461+
split_pipe->plane_res.ipp = pool->ipps[i];
1462+
split_pipe->plane_res.dpp = pool->dpps[i];
1463+
split_pipe->stream_res.opp = pool->opps[i];
1464+
split_pipe->plane_res.mpcc_inst = pool->dpps[i]->inst;
1465+
split_pipe->pipe_idx = i;
1466+
14471467
split_pipe->stream = stream;
14481468
return i;
14491469
}

0 commit comments

Comments
 (0)