Commit 799c5b9c authored by Wesley Chalmers's avatar Wesley Chalmers Committed by Alex Deucher
Browse files

drm/amd/display: Revert fixup DPP programming sequence



[WHY]
This change was made because DTO programming was double-buffered, which
is itself an issue. After deactivating the DTO double buffer, this
change becomes unnecessary.

Signed-off-by: default avatarWesley Chalmers <Wesley.Chalmers@amd.com>
Reviewed-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6bd0a112
Loading
Loading
Loading
Loading
+36 −75
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
{
	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;

@@ -113,75 +114,28 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
		dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
		dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
		clk_mgr->dccg->funcs->update_dpp_dto(
				clk_mgr->dccg, dpp_inst, dppclk_khz, false);
				clk_mgr->dccg, dpp_inst, dppclk_khz);
	}
}

static void update_global_dpp_clk(struct clk_mgr_internal *clk_mgr, unsigned int khz)
void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
{
	int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
			* clk_mgr->dentist_vco_freq_khz / khz;

	uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);

	REG_UPDATE(DENTIST_DISPCLK_CNTL,
			DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider);
	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100);
}

static void update_display_clk(struct clk_mgr_internal *clk_mgr, unsigned int khz)
{
			* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
	int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
			* clk_mgr->dentist_vco_freq_khz / khz;
			* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;

	uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
	uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);

	REG_UPDATE(DENTIST_DISPCLK_CNTL,
			DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider);
//	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 5, 100);
	REG_UPDATE(DENTIST_DISPCLK_CNTL,
			DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider);
	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100);
}

static void request_voltage_and_program_disp_clk(struct clk_mgr *clk_mgr_base, unsigned int khz)
{
	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
	struct dc *dc = clk_mgr_base->ctx->dc;
	struct pp_smu_funcs_nv *pp_smu = NULL;
	bool going_up = clk_mgr->base.clks.dispclk_khz < khz;

	if (dc->res_pool->pp_smu)
		pp_smu = &dc->res_pool->pp_smu->nv_funcs;

	clk_mgr->base.clks.dispclk_khz = khz;

	if (going_up && pp_smu && pp_smu->set_voltage_by_freq)
		pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_DISPCLK, clk_mgr_base->clks.dispclk_khz / 1000);

	update_display_clk(clk_mgr, khz);

	if (!going_up && pp_smu && pp_smu->set_voltage_by_freq)
		pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_DISPCLK, clk_mgr_base->clks.dispclk_khz / 1000);
}

static void request_voltage_and_program_global_dpp_clk(struct clk_mgr *clk_mgr_base, unsigned int khz)
{
	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
	struct dc *dc = clk_mgr_base->ctx->dc;
	struct pp_smu_funcs_nv *pp_smu = NULL;
	bool going_up = clk_mgr->base.clks.dppclk_khz < khz;

	if (dc->res_pool->pp_smu)
		pp_smu = &dc->res_pool->pp_smu->nv_funcs;

	clk_mgr->base.clks.dppclk_khz = khz;
	clk_mgr->dccg->ref_dppclk = khz;

	if (going_up && pp_smu && pp_smu->set_voltage_by_freq)
		pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_PIXELCLK, clk_mgr_base->clks.dppclk_khz / 1000);

	update_global_dpp_clk(clk_mgr, khz);

	if (!going_up && pp_smu && pp_smu->set_voltage_by_freq)
		pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_PIXELCLK, clk_mgr_base->clks.dppclk_khz / 1000);
}

void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
			struct dc_state *context,
@@ -192,8 +146,10 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
	struct dc *dc = clk_mgr_base->ctx->dc;
	struct pp_smu_funcs_nv *pp_smu = NULL;
	int display_count;
	bool update_dppclk = false;
	bool update_dispclk = false;
	bool enter_display_off = false;
	bool dpp_clock_lowered = false;
	struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
	bool force_reset = false;

@@ -250,12 +206,10 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,

	if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
		clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;

		clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support;
		if (pp_smu && pp_smu->set_pstate_handshake_support)
			pp_smu->set_pstate_handshake_support(&pp_smu->pp_smu, clk_mgr_base->clks.p_state_change_support);
	}
	clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;

	if (should_set_clock(safe_to_lower, new_clocks->dramclk_khz, clk_mgr_base->clks.dramclk_khz)) {
		clk_mgr_base->clks.dramclk_khz = new_clocks->dramclk_khz;
@@ -263,28 +217,35 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
			pp_smu->set_hard_min_uclk_by_freq(&pp_smu->pp_smu, clk_mgr_base->clks.dramclk_khz / 1000);
	}

	if (dc->config.forced_clocks == false) {
		// First update display clock
		if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz))
			request_voltage_and_program_disp_clk(clk_mgr_base, new_clocks->dispclk_khz);
	if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
		if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
			dpp_clock_lowered = true;
		clk_mgr->base.clks.dppclk_khz = new_clocks->dppclk_khz;

		// Updating DPP clock requires some more logic
		if (!safe_to_lower) {
			// For pre-programming, we need to make sure any DPP clock that will go up has to go up
		if (pp_smu && pp_smu->set_voltage_by_freq)
			pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_PIXELCLK, clk_mgr_base->clks.dppclk_khz / 1000);

			// First raise the global reference if needed
			if (new_clocks->dppclk_khz > clk_mgr_base->clks.dppclk_khz)
				request_voltage_and_program_global_dpp_clk(clk_mgr_base, new_clocks->dppclk_khz);
		update_dppclk = true;
	}

			// Then raise any dividers that need raising
	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
		clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
		if (pp_smu && pp_smu->set_voltage_by_freq)
			pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_DISPCLK, clk_mgr_base->clks.dispclk_khz / 1000);

		update_dispclk = true;
	}
	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_dentist(clk_mgr);
		} else {
			// For post-programming, we can lower ref clk if needed, and unconditionally set all the DTOs

			if (new_clocks->dppclk_khz < clk_mgr_base->clks.dppclk_khz)
				request_voltage_and_program_global_dpp_clk(clk_mgr_base, new_clocks->dppclk_khz);
			// if clock is being raised, increase refclk before lowering DTO
			if (update_dppclk || update_dispclk)
				dcn20_update_clocks_update_dentist(clk_mgr);
			if (update_dppclk)
				dcn20_update_clocks_update_dpp_dto(clk_mgr, context);

		}
	}
	if (update_dispclk &&
+0 −3
Original line number Diff line number Diff line
@@ -1646,9 +1646,6 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
			updates[i].surface->update_flags.raw = 0xFFFFFFFF;
	}

	if (type == UPDATE_TYPE_FAST && memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0)
		dc->optimized_required = true;

	return type;
}

+1 −2
Original line number Diff line number Diff line
@@ -2304,8 +2304,7 @@ void update_dchubp_dpp(
			dc->res_pool->dccg->funcs->update_dpp_dto(
					dc->res_pool->dccg,
					dpp->inst,
					pipe_ctx->plane_res.bw.dppclk_khz,
					false);
					pipe_ctx->plane_res.bw.dppclk_khz);
		else
			dc->clk_mgr->clks.dppclk_khz = should_divided_by_2 ?
						dc->clk_mgr->clks.dispclk_khz / 2 :
+4 −27
Original line number Diff line number Diff line
@@ -44,16 +44,12 @@
#define DC_LOGGER \
	dccg->ctx->logger

void dccg2_update_dpp_dto(struct dccg *dccg,
		int dpp_inst,
		int req_dppclk,
		bool reduce_divider_only)
void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);

	if (dccg->ref_dppclk && req_dppclk) {
		int ref_dppclk = dccg->ref_dppclk;
		int current_phase, current_modulo;

		ASSERT(req_dppclk <= ref_dppclk);
		/* need to clamp to 8 bits */
@@ -65,28 +61,9 @@ void dccg2_update_dpp_dto(struct dccg *dccg,
			if (req_dppclk > ref_dppclk)
				req_dppclk = ref_dppclk;
		}

		REG_GET_2(DPPCLK_DTO_PARAM[dpp_inst],
				DPPCLK0_DTO_PHASE, &current_phase,
				DPPCLK0_DTO_MODULO, &current_modulo);

		if (reduce_divider_only) {
			// requested phase/modulo greater than current
			if (req_dppclk * current_modulo >= current_phase * ref_dppclk) {
		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
				DPPCLK0_DTO_PHASE, req_dppclk,
				DPPCLK0_DTO_MODULO, ref_dppclk);
			} else {
				REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
						DPPCLK0_DTO_PHASE, current_phase,
						DPPCLK0_DTO_MODULO, current_modulo);
			}
		} else {
			REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
					DPPCLK0_DTO_PHASE, req_dppclk,
					DPPCLK0_DTO_MODULO, ref_dppclk);
		}

		REG_UPDATE(DPPCLK_DTO_CTRL,
				DPPCLK_DTO_ENABLE[dpp_inst], 1);
	} else {
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ struct dcn_dccg {
	const struct dccg_mask *dccg_mask;
};

void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk, bool raise_divider_only);
void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk);

void dccg2_get_dccg_ref_freq(struct dccg *dccg,
		unsigned int xtalin_freq_inKhz,
Loading