Commit 7ae0caf3 authored by Samson Tam's avatar Samson Tam Committed by Alex Deucher

drm/amd/display: fix underflow in some two display subvp/non-subvp configs

[Why]
In two display configuration, switching between subvp and non-subvp
 may cause underflow because it moves an existing pipe between
 displays

[How]
Create helper function for applying pipe split flags
Apply pipe split flags prior to deciding on subvp
During subvp check, do not merge pipes, so it can retain previous
 pipe configuration
Add check for prev odm pipe in subvp check
For single display subvp case, use same odm policy for phantom pipes
 as main subvp pipe
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarSamson Tam <samson.tam@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4df96ba6
...@@ -180,6 +180,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { ...@@ -180,6 +180,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
}; };
static bool dcn32_apply_merge_split_flags_helper(struct dc *dc, struct dc_state *context,
bool *repopulate_pipes, int *split, bool *merge);
void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
{ {
/* defaults */ /* defaults */
...@@ -622,7 +625,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, ...@@ -622,7 +625,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc,
* to combine this with SubVP can cause issues with the scheduling). * to combine this with SubVP can cause issues with the scheduling).
* - Not TMZ surface * - Not TMZ surface
*/ */
if (pipe->plane_state && !pipe->top_pipe && !dcn32_is_center_timing(pipe) && if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe && !dcn32_is_center_timing(pipe) &&
!(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) && !(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) &&
(!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) && (!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) &&
dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE && dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE &&
...@@ -1425,13 +1428,14 @@ static bool is_test_pattern_enabled( ...@@ -1425,13 +1428,14 @@ static bool is_test_pattern_enabled(
return false; return false;
} }
static void dcn32_full_validate_bw_helper(struct dc *dc, static bool dcn32_full_validate_bw_helper(struct dc *dc,
struct dc_state *context, struct dc_state *context,
display_e2e_pipe_params_st *pipes, display_e2e_pipe_params_st *pipes,
int *vlevel, int *vlevel,
int *split, int *split,
bool *merge, bool *merge,
int *pipe_cnt) int *pipe_cnt,
bool *repopulate_pipes)
{ {
struct vba_vars_st *vba = &context->bw_ctx.dml.vba; struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
unsigned int dc_pipe_idx = 0; unsigned int dc_pipe_idx = 0;
...@@ -1461,6 +1465,12 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, ...@@ -1461,6 +1465,12 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
vba->VoltageLevel = *vlevel; vba->VoltageLevel = *vlevel;
} }
/* Apply split and merge flags before checking for subvp */
if (!dcn32_apply_merge_split_flags_helper(dc, context, repopulate_pipes, split, merge))
return false;
memset(split, 0, MAX_PIPES * sizeof(int));
memset(merge, 0, MAX_PIPES * sizeof(bool));
/* Conditions for setting up phantom pipes for SubVP: /* Conditions for setting up phantom pipes for SubVP:
* 1. Not force disable SubVP * 1. Not force disable SubVP
* 2. Full update (i.e. !fast_validate) * 2. Full update (i.e. !fast_validate)
...@@ -1475,19 +1485,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, ...@@ -1475,19 +1485,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported || vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported ||
dc->debug.force_subvp_mclk_switch)) { dc->debug.force_subvp_mclk_switch)) {
dcn32_merge_pipes_for_subvp(dc, context);
memset(merge, 0, MAX_PIPES * sizeof(bool));
vlevel_temp = *vlevel; vlevel_temp = *vlevel;
/* to re-initialize viewport after the pipe merge */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
if (!pipe_ctx->plane_state || !pipe_ctx->stream)
continue;
resource_build_scaling_params(pipe_ctx);
}
while (!found_supported_config && dcn32_enough_pipes_for_subvp(dc, context) && while (!found_supported_config && dcn32_enough_pipes_for_subvp(dc, context) &&
dcn32_assign_subvp_pipe(dc, context, &dc_pipe_idx)) { dcn32_assign_subvp_pipe(dc, context, &dc_pipe_idx)) {
...@@ -1576,8 +1574,6 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, ...@@ -1576,8 +1574,6 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
* add phantom pipes. If pipe split (ODM / MPC) is required, both the main * 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. * 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); *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge);
vba->VoltageLevel = *vlevel; vba->VoltageLevel = *vlevel;
// Note: We can't apply the phantom pipes to hardware at this time. We have to wait // Note: We can't apply the phantom pipes to hardware at this time. We have to wait
...@@ -1590,6 +1586,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, ...@@ -1590,6 +1586,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
try_odm_power_optimization_and_revalidate( try_odm_power_optimization_and_revalidate(
dc, context, pipes, split, merge, vlevel, *pipe_cnt); dc, context, pipes, split, merge, vlevel, *pipe_cnt);
return true;
} }
static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
...@@ -1929,106 +1926,23 @@ static bool dcn32_split_stream_for_mpc_or_odm( ...@@ -1929,106 +1926,23 @@ static bool dcn32_split_stream_for_mpc_or_odm(
return true; return true;
} }
bool dcn32_internal_validate_bw(struct dc *dc, static bool dcn32_apply_merge_split_flags_helper(
struct dc *dc,
struct dc_state *context, struct dc_state *context,
display_e2e_pipe_params_st *pipes, bool *repopulate_pipes,
int *pipe_cnt_out, int *split,
int *vlevel_out, bool *merge)
bool fast_validate)
{ {
bool out = false; int i, pipe_idx;
bool repopulate_pipes = false;
int split[MAX_PIPES] = { 0 };
bool merge[MAX_PIPES] = { false };
bool newly_split[MAX_PIPES] = { false }; bool newly_split[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx;
int vlevel = context->bw_ctx.dml.soc.num_states;
struct vba_vars_st *vba = &context->bw_ctx.dml.vba; struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
dc_assert_fp_enabled();
ASSERT(pipes);
if (!pipes)
return false;
// For each full update, remove all existing phantom pipes first
dc_state_remove_phantom_streams_and_planes(dc, context);
dc_state_release_phantom_streams_and_planes(dc, context);
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
if (!pipe_cnt) {
out = true;
goto validate_out;
}
dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
context->bw_ctx.dml.soc.max_vratio_pre = dcn32_determine_max_vratio_prefetch(dc, context);
if (!fast_validate)
dcn32_full_validate_bw_helper(dc, context, pipes, &vlevel, split, merge, &pipe_cnt);
if (fast_validate ||
(dc->debug.dml_disallow_alternate_prefetch_modes &&
(vlevel == context->bw_ctx.dml.soc.num_states ||
vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported))) {
/*
* If dml_disallow_alternate_prefetch_modes is false, then we have already
* tried alternate prefetch modes during full validation.
*
* If mode is unsupported or there is no p-state support, then
* fall back to favouring voltage.
*
* If Prefetch mode 0 failed for this config, or passed with Max UCLK, then try
* to support with Prefetch mode 1 (dm_prefetch_support_fclk_and_stutter == 2)
*/
context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
dm_prefetch_support_none;
context->bw_ctx.dml.validate_max_state = fast_validate;
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
context->bw_ctx.dml.validate_max_state = false;
if (vlevel < context->bw_ctx.dml.soc.num_states) {
memset(split, 0, sizeof(split));
memset(merge, 0, sizeof(merge));
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
// dcn20_validate_apply_pipe_split_flags can modify voltage level outside of DML
vba->VoltageLevel = vlevel;
}
}
dml_log_mode_support_params(&context->bw_ctx.dml);
if (vlevel == context->bw_ctx.dml.soc.num_states)
goto validate_fail;
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
if (!pipe->stream)
continue;
if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
&& !dc->config.enable_windowed_mpo_odm
&& pipe->plane_state && mpo_pipe
&& memcmp(&mpo_pipe->plane_state->clip_rect,
&pipe->stream->src,
sizeof(struct rect)) != 0) {
ASSERT(mpo_pipe->plane_state != pipe->plane_state);
goto validate_fail;
}
pipe_idx++;
}
if (dc->config.enable_windowed_mpo_odm) { if (dc->config.enable_windowed_mpo_odm) {
repopulate_pipes = update_pipes_with_split_flags( if (update_pipes_with_split_flags(
dc, context, vba, split, merge); dc, context, vba, split, merge))
*repopulate_pipes = true;
} else { } else {
/* the code below will be removed once windowed mpo odm is fully /* the code below will be removed once windowed mpo odm is fully
* enabled. * enabled.
*/ */
...@@ -2085,7 +1999,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2085,7 +1999,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
memset(&pipe->link_res, 0, sizeof(pipe->link_res)); memset(&pipe->link_res, 0, sizeof(pipe->link_res));
repopulate_pipes = true; *repopulate_pipes = true;
} else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) { } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
struct pipe_ctx *top_pipe = pipe->top_pipe; struct pipe_ctx *top_pipe = pipe->top_pipe;
struct pipe_ctx *bottom_pipe = pipe->bottom_pipe; struct pipe_ctx *bottom_pipe = pipe->bottom_pipe;
...@@ -2101,7 +2015,7 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2101,7 +2015,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
memset(&pipe->link_res, 0, sizeof(pipe->link_res)); memset(&pipe->link_res, 0, sizeof(pipe->link_res));
repopulate_pipes = true; *repopulate_pipes = true;
} else } else
ASSERT(0); /* Should never try to merge master pipe */ ASSERT(0); /* Should never try to merge master pipe */
...@@ -2140,15 +2054,15 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2140,15 +2054,15 @@ bool dcn32_internal_validate_bw(struct dc *dc,
hsplit_pipe = dcn32_find_split_pipe(dc, context, old_index); hsplit_pipe = dcn32_find_split_pipe(dc, context, old_index);
ASSERT(hsplit_pipe); ASSERT(hsplit_pipe);
if (!hsplit_pipe) if (!hsplit_pipe)
goto validate_fail; return false;
if (!dcn32_split_stream_for_mpc_or_odm( if (!dcn32_split_stream_for_mpc_or_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
pipe, hsplit_pipe, odm)) pipe, hsplit_pipe, odm))
goto validate_fail; return false;
newly_split[hsplit_pipe->pipe_idx] = true; newly_split[hsplit_pipe->pipe_idx] = true;
repopulate_pipes = true; *repopulate_pipes = true;
} }
if (split[i] == 4) { if (split[i] == 4) {
struct pipe_ctx *pipe_4to1; struct pipe_ctx *pipe_4to1;
...@@ -2163,11 +2077,11 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2163,11 +2077,11 @@ bool dcn32_internal_validate_bw(struct dc *dc,
pipe_4to1 = dcn32_find_split_pipe(dc, context, old_index); pipe_4to1 = dcn32_find_split_pipe(dc, context, old_index);
ASSERT(pipe_4to1); ASSERT(pipe_4to1);
if (!pipe_4to1) if (!pipe_4to1)
goto validate_fail; return false;
if (!dcn32_split_stream_for_mpc_or_odm( if (!dcn32_split_stream_for_mpc_or_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
pipe, pipe_4to1, odm)) pipe, pipe_4to1, odm))
goto validate_fail; return false;
newly_split[pipe_4to1->pipe_idx] = true; newly_split[pipe_4to1->pipe_idx] = true;
if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe
...@@ -2182,11 +2096,11 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2182,11 +2096,11 @@ bool dcn32_internal_validate_bw(struct dc *dc,
pipe_4to1 = dcn32_find_split_pipe(dc, context, old_index); pipe_4to1 = dcn32_find_split_pipe(dc, context, old_index);
ASSERT(pipe_4to1); ASSERT(pipe_4to1);
if (!pipe_4to1) if (!pipe_4to1)
goto validate_fail; return false;
if (!dcn32_split_stream_for_mpc_or_odm( if (!dcn32_split_stream_for_mpc_or_odm(
dc, &context->res_ctx, dc, &context->res_ctx,
hsplit_pipe, pipe_4to1, odm)) hsplit_pipe, pipe_4to1, odm))
goto validate_fail; return false;
newly_split[pipe_4to1->pipe_idx] = true; newly_split[pipe_4to1->pipe_idx] = true;
} }
if (odm) if (odm)
...@@ -2198,11 +2112,114 @@ bool dcn32_internal_validate_bw(struct dc *dc, ...@@ -2198,11 +2112,114 @@ bool dcn32_internal_validate_bw(struct dc *dc,
if (pipe->plane_state) { if (pipe->plane_state) {
if (!resource_build_scaling_params(pipe)) if (!resource_build_scaling_params(pipe))
return false;
}
}
}
return true;
}
bool dcn32_internal_validate_bw(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *pipe_cnt_out,
int *vlevel_out,
bool fast_validate)
{
bool out = false;
bool repopulate_pipes = false;
int split[MAX_PIPES] = { 0 };
bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx;
int vlevel = context->bw_ctx.dml.soc.num_states;
struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
dc_assert_fp_enabled();
ASSERT(pipes);
if (!pipes)
return false;
/* For each full update, remove all existing phantom pipes first */
dc_state_remove_phantom_streams_and_planes(dc, context);
dc_state_release_phantom_streams_and_planes(dc, context);
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
if (!pipe_cnt) {
out = true;
goto validate_out;
}
dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
context->bw_ctx.dml.soc.max_vratio_pre = dcn32_determine_max_vratio_prefetch(dc, context);
if (!fast_validate) {
if (!dcn32_full_validate_bw_helper(dc, context, pipes, &vlevel, split, merge,
&pipe_cnt, &repopulate_pipes))
goto validate_fail; goto validate_fail;
} }
if (fast_validate ||
(dc->debug.dml_disallow_alternate_prefetch_modes &&
(vlevel == context->bw_ctx.dml.soc.num_states ||
vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported))) {
/*
* If dml_disallow_alternate_prefetch_modes is false, then we have already
* tried alternate prefetch modes during full validation.
*
* If mode is unsupported or there is no p-state support, then
* fall back to favouring voltage.
*
* If Prefetch mode 0 failed for this config, or passed with Max UCLK, then try
* to support with Prefetch mode 1 (dm_prefetch_support_fclk_and_stutter == 2)
*/
context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
dm_prefetch_support_none;
context->bw_ctx.dml.validate_max_state = fast_validate;
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
context->bw_ctx.dml.validate_max_state = false;
if (vlevel < context->bw_ctx.dml.soc.num_states) {
memset(split, 0, sizeof(split));
memset(merge, 0, sizeof(merge));
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
/* dcn20_validate_apply_pipe_split_flags can modify voltage level outside of DML */
vba->VoltageLevel = vlevel;
} }
} }
dml_log_mode_support_params(&context->bw_ctx.dml);
if (vlevel == context->bw_ctx.dml.soc.num_states)
goto validate_fail;
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
if (!pipe->stream)
continue;
if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
&& !dc->config.enable_windowed_mpo_odm
&& pipe->plane_state && mpo_pipe
&& memcmp(&mpo_pipe->plane_state->clip_rect,
&pipe->stream->src,
sizeof(struct rect)) != 0) {
ASSERT(mpo_pipe->plane_state != pipe->plane_state);
goto validate_fail;
}
pipe_idx++;
}
if (!dcn32_apply_merge_split_flags_helper(dc, context, &repopulate_pipes, split, merge))
goto validate_fail;
/* Actual dsc count per stream dsc validation*/ /* Actual dsc count per stream dsc validation*/
if (!dcn20_validate_dsc(dc, context)) { if (!dcn20_validate_dsc(dc, context)) {
vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE; vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
......
...@@ -1815,9 +1815,47 @@ int dcn32_populate_dml_pipes_from_context( ...@@ -1815,9 +1815,47 @@ int dcn32_populate_dml_pipes_from_context(
struct pipe_ctx *pipe = NULL; struct pipe_ctx *pipe = NULL;
bool subvp_in_use = false; bool subvp_in_use = false;
struct dc_crtc_timing *timing; struct dc_crtc_timing *timing;
int subvp_main_pipe_index = -1;
enum mall_stream_type mall_type;
bool single_display_subvp = false;
struct dc_stream_state *stream = NULL;
int num_subvp_main = 0;
int num_subvp_phantom = 0;
int num_subvp_none = 0;
dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
/* For single display subvp, look for subvp main so if we have phantom
* pipe, we can set odm policy to match main pipe
*/
for (i = 0; i < context->stream_count; i++) {
stream = context->streams[i];
mall_type = dc_state_get_stream_subvp_type(context, stream);
if (mall_type == SUBVP_MAIN)
num_subvp_main++;
else if (mall_type == SUBVP_PHANTOM)
num_subvp_phantom++;
else
num_subvp_none++;
}
if (num_subvp_main == 1 && num_subvp_phantom == 1 && num_subvp_none == 0)
single_display_subvp = true;
if (single_display_subvp) {
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &res_ctx->pipe_ctx[i];
if (!res_ctx->pipe_ctx[i].stream)
continue;
mall_type = dc_state_get_pipe_subvp_type(context, pipe);
if (mall_type == SUBVP_MAIN) {
if (resource_is_pipe_type(pipe, OTG_MASTER))
subvp_main_pipe_index = pipe_cnt;
}
pipe_cnt++;
}
}
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
if (!res_ctx->pipe_ctx[i].stream) if (!res_ctx->pipe_ctx[i].stream)
...@@ -1832,6 +1870,18 @@ int dcn32_populate_dml_pipes_from_context( ...@@ -1832,6 +1870,18 @@ int dcn32_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
if (dc->config.enable_windowed_mpo_odm && if (dc->config.enable_windowed_mpo_odm &&
dc->debug.enable_single_display_2to1_odm_policy) { dc->debug.enable_single_display_2to1_odm_policy) {
/* For single display subvp, if pipe is phantom pipe,
* then copy odm policy from subvp main pipe
*/
mall_type = dc_state_get_pipe_subvp_type(context, pipe);
if (single_display_subvp && (mall_type == SUBVP_PHANTOM)) {
if (subvp_main_pipe_index < 0) {
ASSERT(0);
} else {
pipes[pipe_cnt].pipe.dest.odm_combine_policy =
pipes[subvp_main_pipe_index].pipe.dest.odm_combine_policy;
}
} else {
switch (resource_get_odm_slice_count(pipe)) { switch (resource_get_odm_slice_count(pipe)) {
case 2: case 2:
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
...@@ -1842,9 +1892,11 @@ int dcn32_populate_dml_pipes_from_context( ...@@ -1842,9 +1892,11 @@ int dcn32_populate_dml_pipes_from_context(
default: default:
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
} }
}
} else { } else {
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
} }
pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19; pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
......
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