Commit 380202c8 authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher

drm/amd/display: For SubVP pipe split case use min transition into MPO

[Description]
- For SubVP pipe split case we need to use a minimial transition
  when opening MPO video since we are transitioning from 4 pipes
  to 3 pipes where an OPP for a previous MPCC will change
- Also save and restore mall config when doing fast_validate in case
  there was a shallow copy of the dc->current_state
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarAlvin Lee <Alvin.Lee2@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1178ac68
......@@ -3564,6 +3564,7 @@ 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;
......@@ -3595,6 +3596,36 @@ 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).
*/
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;
}
}
/* determine if minimal transition is required due to SubVP*/
if (surface_count > 0 && is_pipe_split) {
if (cur_stream_status->plane_count > surface_count) {
force_minimal_pipe_splitting = true;
} else if (cur_stream_status->plane_count < surface_count) {
force_minimal_pipe_splitting = true;
*is_plane_addition = true;
}
}
}
return force_minimal_pipe_splitting;
}
......@@ -3604,6 +3635,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
struct dc_state *transition_context = dc_create_state(dc);
enum pipe_split_policy tmp_mpc_policy;
bool temp_dynamic_odm_policy;
bool temp_subvp_policy;
enum dc_status ret = DC_ERROR_UNEXPECTED;
unsigned int i, j;
......@@ -3618,6 +3650,9 @@ static bool commit_minimal_transition_state(struct dc *dc,
temp_dynamic_odm_policy = dc->debug.enable_single_display_2to1_odm_policy;
dc->debug.enable_single_display_2to1_odm_policy = false;
temp_subvp_policy = dc->debug.force_disable_subvp;
dc->debug.force_disable_subvp = true;
dc_resource_state_copy_construct(transition_base_context, transition_context);
//commit minimal state
......@@ -3646,6 +3681,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
dc->debug.pipe_split_policy = tmp_mpc_policy;
dc->debug.enable_single_display_2to1_odm_policy = temp_dynamic_odm_policy;
dc->debug.force_disable_subvp = temp_subvp_policy;
if (ret != DC_OK) {
/*this should never happen*/
......
......@@ -1798,14 +1798,32 @@ bool dcn32_validate_bandwidth(struct dc *dc,
int vlevel = 0;
int pipe_cnt = 0;
display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
struct mall_temp_config mall_temp_config;
DC_LOGGER_INIT(dc->ctx->logger);
/* For fast validation, there are situations where a shallow copy of
* of the dc->current_state is created for the validation. In this case
* we want to save and restore the mall config because we always
* teardown subvp at the beginning of validation (and don't attempt
* to add it back if it's fast validation). If we don't restore the
* subvp config in cases of fast validation + shallow copy of the
* dc->current_state, the dc->current_state will have a partially
* removed subvp state when we did not intend to remove it.
*/
if (fast_validate) {
memset(&mall_temp_config, 0, sizeof(mall_temp_config));
dcn32_save_mall_state(dc, context, &mall_temp_config);
}
BW_VAL_TRACE_COUNT();
DC_FP_START();
out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
DC_FP_END();
if (fast_validate)
dcn32_restore_mall_state(dc, context, &mall_temp_config);
if (pipe_cnt == 0)
goto validate_out;
......
......@@ -45,6 +45,17 @@
extern struct _vcs_dpi_ip_params_st dcn3_2_ip;
extern struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc;
/* Temp struct used to save and restore MALL config
* during validation.
*
* TODO: Move MALL config into dc_state instead of stream struct
* to avoid needing to save/restore.
*/
struct mall_temp_config {
struct mall_stream_config mall_stream_config[MAX_PIPES];
bool is_phantom_plane[MAX_PIPES];
};
struct dcn32_resource_pool {
struct resource_pool base;
};
......@@ -122,6 +133,15 @@ void dcn32_determine_det_override(struct dc *dc,
void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes);
void dcn32_save_mall_state(struct dc *dc,
struct dc_state *context,
struct mall_temp_config *temp_config);
void dcn32_restore_mall_state(struct dc *dc,
struct dc_state *context,
struct mall_temp_config *temp_config);
/* definitions for run time init of reg offsets */
/* CLK SRC */
......
......@@ -380,3 +380,74 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
} else
dcn32_determine_det_override(dc, context, pipes);
}
/**
* *******************************************************************************************
* dcn32_save_mall_state: Save MALL (SubVP) state for fast validation cases
*
* This function saves the MALL (SubVP) case for fast validation cases. For fast validation,
* there are situations where a shallow copy of the dc->current_state is created for the
* validation. In this case we want to save and restore the mall config because we always
* teardown subvp at the beginning of validation (and don't attempt to add it back if it's
* fast validation). If we don't restore the subvp config in cases of fast validation +
* shallow copy of the dc->current_state, the dc->current_state will have a partially
* removed subvp state when we did not intend to remove it.
*
* NOTE: This function ONLY works if the streams are not moved to a different pipe in the
* validation. We don't expect this to happen in fast_validation=1 cases.
*
* @param [in]: dc: Current DC state
* @param [in]: context: New DC state to be programmed
* @param [out]: temp_config: struct used to cache the existing MALL state
*
* @return: void
*
* *******************************************************************************************
*/
void dcn32_save_mall_state(struct dc *dc,
struct dc_state *context,
struct mall_temp_config *temp_config)
{
uint32_t i;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (pipe->stream)
temp_config->mall_stream_config[i] = pipe->stream->mall_stream_config;
if (pipe->plane_state)
temp_config->is_phantom_plane[i] = pipe->plane_state->is_phantom;
}
}
/**
* *******************************************************************************************
* dcn32_restore_mall_state: Restore MALL (SubVP) state for fast validation cases
*
* Restore the MALL state based on the previously saved state from dcn32_save_mall_state
*
* @param [in]: dc: Current DC state
* @param [in/out]: context: New DC state to be programmed, restore MALL state into here
* @param [in]: temp_config: struct that has the cached MALL state
*
* @return: void
*
* *******************************************************************************************
*/
void dcn32_restore_mall_state(struct dc *dc,
struct dc_state *context,
struct mall_temp_config *temp_config)
{
uint32_t i;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (pipe->stream)
pipe->stream->mall_stream_config = temp_config->mall_stream_config[i];
if (pipe->plane_state)
pipe->plane_state->is_phantom = temp_config->is_phantom_plane[i];
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment