Commit bc204778 authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher
Browse files

drm/amd/display: Set min dcfclk if pipe count is 0



[WHY]
Clocks don't get recalculated in 0 stream/0 pipe configs,
blocking S0i3 if dcfclk gets high enough

[HOW]
Create DCN31 copy of DCN30 bandwidth validation func which
doesn't entirely skip validation in 0 pipe scenarios

Override dcfclk to vlevel 0/min value during validation if pipe
count is 0

Reviewed-by: default avatarEric Yang <Eric.Yang2@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Tested-by: default avatarDaniel Wheeler <Daniel.Wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e27c41d5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1856,7 +1856,7 @@ static struct pipe_ctx *dcn30_find_split_pipe(
	return pipe;
}

static noinline bool dcn30_internal_validate_bw(
noinline bool dcn30_internal_validate_bw(
		struct dc *dc,
		struct dc_state *context,
		display_e2e_pipe_params_st *pipes,
+7 −0
Original line number Diff line number Diff line
@@ -55,6 +55,13 @@ unsigned int dcn30_calc_max_scaled_time(

bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,
		bool fast_validate);
bool dcn30_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);
void dcn30_calculate_wm_and_dlg(
		struct dc *dc, struct dc_state *context,
		display_e2e_pipe_params_st *pipes,
+62 −1
Original line number Diff line number Diff line
@@ -1827,6 +1827,15 @@ static void dcn31_calculate_wm_and_dlg_fp(
	if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
		dcfclk = context->bw_ctx.dml.soc.min_dcfclk;

	/* We don't recalculate clocks for 0 pipe configs, which can block
	 * S0i3 as high clocks will block low power states
	 * Override any clocks that can block S0i3 to min here
	 */
	if (pipe_cnt == 0) {
		context->bw_ctx.bw.dcn.clk.dcfclk_khz = dcfclk; // always should be vlevel 0
		return;
	}

	pipes[0].clks_cfg.voltage = vlevel;
	pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
@@ -1952,6 +1961,58 @@ static void dcn31_calculate_wm_and_dlg(
	DC_FP_END();
}

bool dcn31_validate_bandwidth(struct dc *dc,
		struct dc_state *context,
		bool fast_validate)
{
	bool out = false;

	BW_VAL_TRACE_SETUP();

	int vlevel = 0;
	int pipe_cnt = 0;
	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
	DC_LOGGER_INIT(dc->ctx->logger);

	BW_VAL_TRACE_COUNT();

	out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);

	// Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
	if (pipe_cnt == 0)
		fast_validate = false;

	if (!out)
		goto validate_fail;

	BW_VAL_TRACE_END_VOLTAGE_LEVEL();

	if (fast_validate) {
		BW_VAL_TRACE_SKIP(fast);
		goto validate_out;
	}

	dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);

	BW_VAL_TRACE_END_WATERMARKS();

	goto validate_out;

validate_fail:
	DC_LOG_WARNING("Mode Validation Warning: %s failed alidation.\n",
		dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));

	BW_VAL_TRACE_SKIP(fail);
	out = false;

validate_out:
	kfree(pipes);

	BW_VAL_TRACE_FINISH();

	return out;
}

static struct dc_cap_funcs cap_funcs = {
	.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
};
@@ -2034,7 +2095,7 @@ static struct resource_funcs dcn31_res_pool_funcs = {
	.link_encs_assign = link_enc_cfg_link_encs_assign,
	.link_enc_unassign = link_enc_cfg_link_enc_unassign,
	.panel_cntl_create = dcn31_panel_cntl_create,
	.validate_bandwidth = dcn30_validate_bandwidth,
	.validate_bandwidth = dcn31_validate_bandwidth,
	.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
	.update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
	.populate_dml_pipes = dcn31_populate_dml_pipes_from_context,