Commit 8e02c26a authored by Joshua Aberback's avatar Joshua Aberback Committed by Alex Deucher

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: default avatarJoshua Aberback <joshua.aberback@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ba578afd
...@@ -2127,7 +2127,7 @@ static bool dcn30_internal_validate_bw( ...@@ -2127,7 +2127,7 @@ static bool dcn30_internal_validate_bw(
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( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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->bw_ctx.dml.vba.StutterPeriod;
context->perf_params.stutter_period_us = /* Make set D = set A until set D is enabled */
context->bw_ctx.dml.vba.StutterPeriod; 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( ...@@ -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, ...@@ -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 = { ...@@ -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( ...@@ -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 { ...@@ -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,
......
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