@@ -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 }
0 commit comments