mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 15:43:35 -04:00
drm/amd/display: SubVP pipe split case
[Why and How] For SubVP pipe split case, pass in split index for main and phantom pipes to ensure that the P-State sequence will force P-State for all required pipes. Reviewed-by: Nevenko Stupar <Nevenko.Stupar@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Wayne Lin <wayne.lin@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>
This commit is contained in:
@@ -674,12 +674,32 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
||||
pipe_data->pipe_config.subvp_data.processing_delay_lines =
|
||||
div64_u64(((uint64_t)(dc->caps.subvp_fw_processing_delay_us) * ((uint64_t)phantom_timing->pix_clk_100hz * 100) +
|
||||
((uint64_t)phantom_timing->h_total * 1000000 - 1)), ((uint64_t)phantom_timing->h_total * 1000000));
|
||||
|
||||
/* TODO: Uncomment once FW headers are promoted
|
||||
if (subvp_pipe->bottom_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.main_split_pipe_index = subvp_pipe->bottom_pipe->pipe_idx;
|
||||
} else if (subvp_pipe->next_odm_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.main_split_pipe_index = subvp_pipe->next_odm_pipe->pipe_idx;
|
||||
} else {
|
||||
pipe_data->pipe_config.subvp_data.main_split_pipe_index = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// Find phantom pipe index based on phantom stream
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *phantom_pipe = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (phantom_pipe->stream == subvp_pipe->stream->mall_stream_config.paired_stream) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->pipe_idx;
|
||||
/* TODO: Uncomment once FW headers are promoted
|
||||
if (phantom_pipe->bottom_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->pipe_idx;
|
||||
} else if (phantom_pipe->next_odm_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->pipe_idx;
|
||||
} else {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = 0;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -724,7 +744,9 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
||||
if (!pipe->stream)
|
||||
continue;
|
||||
|
||||
if (pipe->plane_state && !pipe->top_pipe &&
|
||||
/* For SubVP pipe count, only count the top most (ODM / MPC) pipe
|
||||
*/
|
||||
if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe &&
|
||||
pipe->stream->mall_stream_config.type == SUBVP_MAIN)
|
||||
subvp_pipes[subvp_count++] = pipe;
|
||||
}
|
||||
@@ -737,7 +759,12 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
||||
if (!pipe->stream)
|
||||
continue;
|
||||
|
||||
/* When populating subvp cmd info, only pass in the top most (ODM / MPC) pipe.
|
||||
* Any ODM or MPC splits being used in SubVP will be handled internally in
|
||||
* populate_subvp_cmd_pipe_info
|
||||
*/
|
||||
if (pipe->plane_state && pipe->stream->mall_stream_config.paired_stream &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe &&
|
||||
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
|
||||
} else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) {
|
||||
|
||||
@@ -1906,10 +1906,13 @@ void dcn20_post_unlock_program_front_end(
|
||||
* can underflow due to HUBP_VTG_SEL programming if done in the regular front end
|
||||
* programming sequence).
|
||||
*/
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
if (dc->hwss.update_phantom_vp_position)
|
||||
dc->hwss.update_phantom_vp_position(dc, context, pipe);
|
||||
dcn20_program_pipe(dc, pipe, context);
|
||||
while (pipe) {
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
if (dc->hwss.update_phantom_vp_position)
|
||||
dc->hwss.update_phantom_vp_position(dc, context, pipe);
|
||||
dcn20_program_pipe(dc, pipe, context);
|
||||
}
|
||||
pipe = pipe->bottom_pipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,17 +1160,23 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
|
||||
vba->VoltageLevel = *vlevel;
|
||||
}
|
||||
} else {
|
||||
// only call dcn20_validate_apply_pipe_split_flags if we found a supported config
|
||||
memset(split, 0, MAX_PIPES * sizeof(int));
|
||||
memset(merge, 0, MAX_PIPES * sizeof(bool));
|
||||
*vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge);
|
||||
vba->VoltageLevel = *vlevel;
|
||||
|
||||
// Most populate phantom DLG params before programming hardware / timing for phantom pipe
|
||||
DC_FP_START();
|
||||
dcn32_helper_populate_phantom_dlg_params(dc, context, pipes, *pipe_cnt);
|
||||
DC_FP_END();
|
||||
|
||||
/* Call validate_apply_pipe_split flags after calling DML getters for
|
||||
* phantom dlg params, or some of the VBA params indicating pipe split
|
||||
* can be overwritten by the getters.
|
||||
*
|
||||
* When setting up SubVP config, all pipes are merged before attempting to
|
||||
* add phantom pipes. If pipe split (ODM / MPC) is required, both the main
|
||||
* and phantom pipes will be split in the regular pipe splitting sequence.
|
||||
*/
|
||||
memset(split, 0, MAX_PIPES * sizeof(int));
|
||||
memset(merge, 0, MAX_PIPES * sizeof(bool));
|
||||
*vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge);
|
||||
vba->VoltageLevel = *vlevel;
|
||||
// Note: We can't apply the phantom pipes to hardware at this time. We have to wait
|
||||
// until driver has acquired the DMCUB lock to do it safely.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user