Commit 54790345 authored by Sung Lee's avatar Sung Lee Committed by Alex Deucher
Browse files

drm/amd/display: Lower DPP DTO only when safe



[Why]
A corner case currently exists where DPP DTO is lowered before
pipes are updated to a higher viewport. This causes underflow
as the DPPCLK is too low for the current viewport.

[How]
Only lower DPP DTO when it is safe to lower, or if
the newer clocks are higher than the current ones.

Signed-off-by: default avatarSung Lee <sung.lee@amd.com>
Reviewed-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 68c0fca5
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -101,13 +101,13 @@ uint32_t dentist_get_did_from_divider(int divider)
}

void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
		struct dc_state *context)
		struct dc_state *context, bool safe_to_lower)
{
	int i;

	clk_mgr->dccg->ref_dppclk = clk_mgr->base.clks.dppclk_khz;
	for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
		int dpp_inst, dppclk_khz;
		int dpp_inst, dppclk_khz, prev_dppclk_khz;

		/* Loop index will match dpp->inst if resource exists,
		 * and we want to avoid dependency on dpp object
@@ -115,10 +115,14 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
		dpp_inst = i;
		dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;

		prev_dppclk_khz = clk_mgr->base.ctx->dc->current_state->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;

		if (safe_to_lower || prev_dppclk_khz < dppclk_khz) {
			clk_mgr->dccg->funcs->update_dpp_dto(
							clk_mgr->dccg, dpp_inst, dppclk_khz);
		}
	}
}

void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
{
@@ -244,7 +248,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
	if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
		if (dpp_clock_lowered) {
			// if clock is being lowered, increase DTO before lowering refclk
			dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
			dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
			dcn20_update_clocks_update_dentist(clk_mgr);
		} else {
			// if clock is being raised, increase refclk before lowering DTO
@@ -252,7 +256,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
				dcn20_update_clocks_update_dentist(clk_mgr);
			// always update dtos unless clock is lowered and not safe to lower
			if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
				dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
				dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
		}
	}

+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
			struct dc_state *context,
			bool safe_to_lower);
void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
		struct dc_state *context);
		struct dc_state *context, bool safe_to_lower);

void dcn2_init_clocks(struct clk_mgr *clk_mgr);

+4 −4
Original line number Diff line number Diff line
@@ -164,16 +164,16 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
	}

	if (dpp_clock_lowered) {
		// if clock is being lowered, increase DTO before lowering refclk
		dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
		// increase per DPP DTO before lowering global dppclk
		dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
		rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
	} else {
		// if clock is being raised, increase refclk before lowering DTO
		// increase global DPPCLK before lowering per DPP DTO
		if (update_dppclk || update_dispclk)
			rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
		// always update dtos unless clock is lowered and not safe to lower
		if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
			dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
			dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
	}

	if (update_dispclk &&