Commit 254eb07c authored by Joshua Aberback's avatar Joshua Aberback Committed by Alex Deucher

drm/amd/display: Optimize bandwidth validation by adding early return

We can split validation into three parts: getting voltage level, getting
watermarks, and rq/dlg calculations. The voltage level is enough to answer
the question "do we support this state", and the rest of it is to determine
what hardware programming is needed to support the state. Most of the calls
to validate_bandwidth only care about the first part, so we added an early
return in that case
Signed-off-by: default avatarJoshua Aberback <joshua.aberback@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 776c1f56
...@@ -1116,9 +1116,8 @@ bool dcn_validate_bandwidth( ...@@ -1116,9 +1116,8 @@ bool dcn_validate_bandwidth(
context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 /
(ddr4_dram_factor_single_Channel * v->number_of_channels)); (ddr4_dram_factor_single_Channel * v->number_of_channels));
if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) { if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65)
context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32);
}
context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
context->bw_ctx.bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000); context->bw_ctx.bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000);
...@@ -1133,7 +1132,8 @@ bool dcn_validate_bandwidth( ...@@ -1133,7 +1132,8 @@ bool dcn_validate_bandwidth(
dc->debug.min_disp_clk_khz; dc->debug.min_disp_clk_khz;
} }
context->bw_ctx.bw.dcn.clk.dppclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz / v->dispclk_dppclk_ratio; context->bw_ctx.bw.dcn.clk.dppclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz /
v->dispclk_dppclk_ratio;
context->bw_ctx.bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; context->bw_ctx.bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level];
switch (v->voltage_level) { switch (v->voltage_level) {
case 0: case 0:
...@@ -1220,9 +1220,7 @@ bool dcn_validate_bandwidth( ...@@ -1220,9 +1220,7 @@ bool dcn_validate_bandwidth(
/* pipe not split previously needs split */ /* pipe not split previously needs split */
hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool, pipe); hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool, pipe);
ASSERT(hsplit_pipe); ASSERT(hsplit_pipe);
split_stream_across_pipes( split_stream_across_pipes(&context->res_ctx, pool, pipe, hsplit_pipe);
&context->res_ctx, pool,
pipe, hsplit_pipe);
} }
dcn_bw_calc_rq_dlg_ttu(dc, v, hsplit_pipe, input_idx); dcn_bw_calc_rq_dlg_ttu(dc, v, hsplit_pipe, input_idx);
...@@ -1253,7 +1251,6 @@ bool dcn_validate_bandwidth( ...@@ -1253,7 +1251,6 @@ bool dcn_validate_bandwidth(
} }
if (v->voltage_level == 0) { if (v->voltage_level == 0) {
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us =
dc->dcn_soc->sr_enter_plus_exit_time; dc->dcn_soc->sr_enter_plus_exit_time;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time; context->bw_ctx.dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time;
......
...@@ -1415,9 +1415,8 @@ bool dcn20_update_bandwidth( ...@@ -1415,9 +1415,8 @@ bool dcn20_update_bandwidth(
int i; int i;
/* recalculate DML parameters */ /* recalculate DML parameters */
if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false))
return false; return false;
}
/* apply updated bandwidth parameters */ /* apply updated bandwidth parameters */
dc->hwss.prepare_bandwidth(dc, context); dc->hwss.prepare_bandwidth(dc, context);
......
...@@ -1907,10 +1907,11 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx) ...@@ -1907,10 +1907,11 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
} }
#endif #endif
bool dcn20_validate_bandwidth(struct dc *dc, bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
struct dc_state *context, bool fast_validate)
bool fast_validate)
{ {
bool out = false;
int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit; int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
int pipe_split_from[MAX_PIPES]; int pipe_split_from[MAX_PIPES];
bool odm_capable = context->bw_ctx.dml.ip.odm_capable; bool odm_capable = context->bw_ctx.dml.ip.odm_capable;
...@@ -1954,11 +1955,16 @@ bool dcn20_validate_bandwidth(struct dc *dc, ...@@ -1954,11 +1955,16 @@ bool dcn20_validate_bandwidth(struct dc *dc,
} }
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, &context->res_ctx, pipes); pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, &context->res_ctx, pipes);
if (!pipe_cnt)
goto validate_pass; if (!pipe_cnt) {
out = true;
goto validate_out;
}
context->bw_ctx.dml.ip.odm_capable = 0; context->bw_ctx.dml.ip.odm_capable = 0;
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
context->bw_ctx.dml.ip.odm_capable = odm_capable; context->bw_ctx.dml.ip.odm_capable = odm_capable;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
...@@ -2111,6 +2117,11 @@ bool dcn20_validate_bandwidth(struct dc *dc, ...@@ -2111,6 +2117,11 @@ bool dcn20_validate_bandwidth(struct dc *dc,
} }
#endif #endif
if (fast_validate) {
out = true;
goto validate_out;
}
for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream) if (!context->res_ctx.pipe_ctx[i].stream)
continue; continue;
...@@ -2235,21 +2246,27 @@ bool dcn20_validate_bandwidth(struct dc *dc, ...@@ -2235,21 +2246,27 @@ bool dcn20_validate_bandwidth(struct dc *dc,
pipe_idx, pipe_idx,
cstate_en, cstate_en,
context->bw_ctx.bw.dcn.clk.p_state_change_support); context->bw_ctx.bw.dcn.clk.p_state_change_support);
context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml, context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
&context->res_ctx.pipe_ctx[i].rq_regs, &context->res_ctx.pipe_ctx[i].rq_regs,
pipes[pipe_idx].pipe); pipes[pipe_idx].pipe);
pipe_idx++; pipe_idx++;
} }
validate_pass: out = true;
kfree(pipes); goto validate_out;
return true;
validate_fail: validate_fail:
DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n", DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
out = false;
validate_out:
kfree(pipes); kfree(pipes);
return false;
return out;
} }
struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer( struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
......
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