drm/amd/display: Calc DLG from dummy p-state if full p-state unsupported
[Why] Currently, when full p-state changes are not supported, DLG parameters are calculated for no p-state support at all. However, we are required to always support dummy p-state changes, so we should instead calculate DLG based on dummy p-state latency when full p-state is unsupported. This behaviour already exists for DCN2. [How] - move DLG calculation inside WM calculation - if p-state unsupported, do not recalculate for set A, instead copy from set C, and perform DLG calculation with dummy p-state latency Signed-off-by: Joshua Aberback <joshua.aberback@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ba578afd5a
commit
8e02c26a58
@ -2127,7 +2127,7 @@ validate_out:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dcn30_calculate_wm(
|
void dcn30_calculate_wm_and_dlg(
|
||||||
struct dc *dc, struct dc_state *context,
|
struct dc *dc, struct dc_state *context,
|
||||||
display_e2e_pipe_params_st *pipes,
|
display_e2e_pipe_params_st *pipes,
|
||||||
int pipe_cnt,
|
int pipe_cnt,
|
||||||
@ -2135,6 +2135,8 @@ static void dcn30_calculate_wm(
|
|||||||
{
|
{
|
||||||
int i, pipe_idx;
|
int i, pipe_idx;
|
||||||
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||||
|
bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] !=
|
||||||
|
dm_dram_clock_change_unsupported;
|
||||||
|
|
||||||
if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
|
if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
|
||||||
dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
|
dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
|
||||||
@ -2168,30 +2170,12 @@ static void dcn30_calculate_wm(
|
|||||||
pipes[0].clks_cfg.voltage = vlevel;
|
pipes[0].clks_cfg.voltage = vlevel;
|
||||||
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
|
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
|
||||||
|
|
||||||
/* Set C:
|
|
||||||
* DCFCLK: Min Required
|
|
||||||
* FCLK(proportional to UCLK): 1GHz or Max
|
|
||||||
* pstate latency overriden to 5us
|
|
||||||
*/
|
|
||||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
|
|
||||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us;
|
|
||||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
|
|
||||||
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
|
|
||||||
}
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
|
||||||
|
|
||||||
/* Set D:
|
/* Set D:
|
||||||
* DCFCLK: Min Required
|
* DCFCLK: Min Required
|
||||||
* FCLK(proportional to UCLK): 1GHz or Max
|
* FCLK(proportional to UCLK): 1GHz or Max
|
||||||
* sr_enter_exit = 4, sr_exit = 2us
|
* sr_enter_exit = 4, sr_exit = 2us
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
|
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
|
||||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
|
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
|
||||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
|
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
|
||||||
@ -2205,7 +2189,47 @@ static void dcn30_calculate_wm(
|
|||||||
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Set C:
|
||||||
|
* DCFCLK: Min Required
|
||||||
|
* FCLK(proportional to UCLK): 1GHz or Max
|
||||||
|
* pstate latency overridden to 5us
|
||||||
|
*/
|
||||||
|
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
|
||||||
|
unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
|
||||||
|
unsigned int min_dram_speed_mts_margin = 160;
|
||||||
|
|
||||||
|
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us;
|
||||||
|
|
||||||
|
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_unsupported)
|
||||||
|
min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16;
|
||||||
|
|
||||||
|
for (i = 3; i > 0; i--) {
|
||||||
|
if ((min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts) &&
|
||||||
|
(min_dram_speed_mts - min_dram_speed_mts_margin < dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts))
|
||||||
|
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
|
||||||
|
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
|
||||||
|
}
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
|
||||||
|
if (!pstate_en) {
|
||||||
|
/* The only difference between A and C is p-state latency, if p-state is not supported we want to
|
||||||
|
* calculate DLG based on dummy p-state latency, and max out the set A p-state watermark
|
||||||
|
*/
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0x13FFFF;
|
||||||
|
} else {
|
||||||
/* Set A:
|
/* Set A:
|
||||||
* DCFCLK: Min Required
|
* DCFCLK: Min Required
|
||||||
* FCLK(proportional to UCLK): 1GHz or Max
|
* FCLK(proportional to UCLK): 1GHz or Max
|
||||||
@ -2225,9 +2249,12 @@ static void dcn30_calculate_wm(
|
|||||||
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
context->perf_params.stutter_period_us =
|
context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
|
||||||
context->bw_ctx.dml.vba.StutterPeriod;
|
|
||||||
|
/* Make set D = set A until set D is enabled */
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a;
|
||||||
|
|
||||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||||
@ -2247,6 +2274,13 @@ static void dcn30_calculate_wm(
|
|||||||
|
|
||||||
pipe_idx++;
|
pipe_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
|
||||||
|
|
||||||
|
if (!pstate_en)
|
||||||
|
/* Restore full p-state latency */
|
||||||
|
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
|
||||||
|
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dcn30_validate_bandwidth(struct dc *dc,
|
bool dcn30_validate_bandwidth(struct dc *dc,
|
||||||
@ -2279,8 +2313,7 @@ bool dcn30_validate_bandwidth(struct dc *dc,
|
|||||||
goto validate_out;
|
goto validate_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dcn30_calculate_wm(dc, context, pipes, pipe_cnt, vlevel);
|
dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
|
||||||
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
|
|
||||||
|
|
||||||
BW_VAL_TRACE_END_WATERMARKS();
|
BW_VAL_TRACE_END_WATERMARKS();
|
||||||
|
|
||||||
@ -2448,6 +2481,7 @@ static const struct resource_funcs dcn30_res_pool_funcs = {
|
|||||||
.link_enc_create = dcn30_link_encoder_create,
|
.link_enc_create = dcn30_link_encoder_create,
|
||||||
.panel_cntl_create = dcn30_panel_cntl_create,
|
.panel_cntl_create = dcn30_panel_cntl_create,
|
||||||
.validate_bandwidth = dcn30_validate_bandwidth,
|
.validate_bandwidth = dcn30_validate_bandwidth,
|
||||||
|
.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
|
||||||
.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
|
.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
|
||||||
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
||||||
.add_stream_to_ctx = dcn30_add_stream_to_ctx,
|
.add_stream_to_ctx = dcn30_add_stream_to_ctx,
|
||||||
|
@ -55,6 +55,11 @@ unsigned int dcn30_calc_max_scaled_time(
|
|||||||
|
|
||||||
bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||||
bool fast_validate);
|
bool fast_validate);
|
||||||
|
void dcn30_calculate_wm_and_dlg(
|
||||||
|
struct dc *dc, struct dc_state *context,
|
||||||
|
display_e2e_pipe_params_st *pipes,
|
||||||
|
int pipe_cnt,
|
||||||
|
int vlevel);
|
||||||
void dcn30_populate_dml_writeback_from_context(
|
void dcn30_populate_dml_writeback_from_context(
|
||||||
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
|
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ struct resource_funcs {
|
|||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context,
|
struct dc_state *context,
|
||||||
bool fast_validate);
|
bool fast_validate);
|
||||||
void (*calculate_wm)(
|
void (*calculate_wm_and_dlg)(
|
||||||
struct dc *dc, struct dc_state *context,
|
struct dc *dc, struct dc_state *context,
|
||||||
display_e2e_pipe_params_st *pipes,
|
display_e2e_pipe_params_st *pipes,
|
||||||
int pipe_cnt,
|
int pipe_cnt,
|
||||||
|
Loading…
Reference in New Issue
Block a user