Commit 71c4ca2d authored by Nasir Osman's avatar Nasir Osman Committed by Alex Deucher
Browse files

drm/amd/display: Remove stutter only configurations



[why]
Newer ASICs such as DCN314 needs to allow for both self refresh and mem
clk switching rather than just self refresh only. Otherwise, we can see
some p-state hangs on ASICs that do support mem clk switching.

[how]
Added an allow_self_refresh_only flag for dcn30_internal_validate_bw
and created a validate_bw method for DCN314 with the allow_self_refresh_only
flag set to false (to support mem clk switching).

Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarNasir Osman <nasir.osman@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d6ed6d0d
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -1648,7 +1648,8 @@ noinline bool dcn30_internal_validate_bw(
		display_e2e_pipe_params_st *pipes,
		int *pipe_cnt_out,
		int *vlevel_out,
		bool fast_validate)
		bool fast_validate,
		bool allow_self_refresh_only)
{
	bool out = false;
	bool repopulate_pipes = false;
@@ -1675,7 +1676,7 @@ noinline bool dcn30_internal_validate_bw(

	dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);

	if (!fast_validate) {
	if (!fast_validate || !allow_self_refresh_only) {
		/*
		 * DML favors voltage over p-state, but we're more interested in
		 * supporting p-state over voltage. We can't support p-state in
@@ -1688,11 +1689,12 @@ noinline bool dcn30_internal_validate_bw(
		if (vlevel < context->bw_ctx.dml.soc.num_states)
			vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
	}
	if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
			vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
	if (allow_self_refresh_only &&
	    (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
			vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported)) {
		/*
		 * If mode is unsupported or there's still no p-state support then
		 * fall back to favoring voltage.
		 * If mode is unsupported or there's still no p-state support
		 * then fall back to favoring voltage.
		 *
		 * We don't actually support prefetch mode 2, so require that we
		 * at least support prefetch mode 1.
@@ -2063,7 +2065,7 @@ bool dcn30_validate_bandwidth(struct dc *dc,
	BW_VAL_TRACE_COUNT();

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

	if (pipe_cnt == 0)
+2 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ bool dcn30_internal_validate_bw(
		display_e2e_pipe_params_st *pipes,
		int *pipe_cnt_out,
		int *vlevel_out,
		bool fast_validate);
		bool fast_validate,
		bool allow_self_refresh_only);
void dcn30_calculate_wm_and_dlg(
		struct dc *dc, struct dc_state *context,
		display_e2e_pipe_params_st *pipes,
+1 −1
Original line number Diff line number Diff line
@@ -1795,7 +1795,7 @@ bool dcn31_validate_bandwidth(struct dc *dc,
	BW_VAL_TRACE_COUNT();

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

	// Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
+56 −1
Original line number Diff line number Diff line
@@ -1695,6 +1695,61 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi
	*panel_config = panel_config_defaults;
}

bool dcn314_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();

	DC_FP_START();
	// do not support self refresh only
	out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false);
	DC_FP_END();

	// Disable fast_validate to set min dcfclk in calculate_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 validation.\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 resource_funcs dcn314_res_pool_funcs = {
	.destroy = dcn314_destroy_resource_pool,
	.link_enc_create = dcn31_link_encoder_create,
@@ -1702,7 +1757,7 @@ static struct resource_funcs dcn314_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 = dcn31_validate_bandwidth,
	.validate_bandwidth = dcn314_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 = dcn314_populate_dml_pipes_from_context,
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@ struct dcn314_resource_pool {
	struct resource_pool base;
};

bool dcn314_validate_bandwidth(struct dc *dc,
		struct dc_state *context,
		bool fast_validate);

struct resource_pool *dcn314_create_resource_pool(
		const struct dc_init_data *init_data,
		struct dc *dc);
Loading