Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e07f541f authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher
Browse files

drm/amd/display: Use real BE and FE index to program regs.



In case of some pipes are fused, pipe_idx should not
be used to program pipe regs. Instead of that, BE and FE
inst number should be used for reg index.

Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c8242b98
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -486,6 +486,7 @@ static void split_stream_across_pipes(
	secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
	secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
	secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
	secondary_pipe->plane_res.mpcc_inst = pool->dpps[secondary_pipe->pipe_idx]->inst;
	if (primary_pipe->bottom_pipe) {
		ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
		secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
+2 −0
Original line number Diff line number Diff line
@@ -1054,6 +1054,7 @@ static int acquire_first_split_pipe(
			pipe_ctx->plane_res.ipp = pool->ipps[i];
			pipe_ctx->plane_res.dpp = pool->dpps[i];
			pipe_ctx->stream_res.opp = pool->opps[i];
			pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
			pipe_ctx->pipe_idx = i;

			pipe_ctx->stream = stream;
@@ -1406,6 +1407,7 @@ static int acquire_first_free_pipe(
			pipe_ctx->plane_res.xfm = pool->transforms[i];
			pipe_ctx->plane_res.dpp = pool->dpps[i];
			pipe_ctx->stream_res.opp = pool->opps[i];
			pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
			pipe_ctx->pipe_idx = i;


+7 −7
Original line number Diff line number Diff line
@@ -625,7 +625,7 @@ static enum dc_status bios_parser_crtc_source_select(
	const struct dc_sink *sink = pipe_ctx->stream->sink;

	crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id;
	crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1;
	crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1;
	/*TODO: Need to un-hardcode color depth, dp_audio and account for
	 * the case where signal and sink signal is different (translator
	 * encoder)*/
@@ -1091,7 +1091,7 @@ static void build_audio_output(

	audio_output->pll_info.dto_source =
		translate_to_dto_source(
			pipe_ctx->pipe_idx + 1);
			pipe_ctx->stream_res.tg->inst + 1);

	/* TODO hard code to enable for now. Need get from stream */
	audio_output->pll_info.ss_enabled = true;
@@ -2147,7 +2147,7 @@ static void program_surface_visibility(const struct dc *dc,
	} else if (!pipe_ctx->plane_state->visible)
		blank_target = true;

	dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode);
	dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
	pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);

}
@@ -2189,7 +2189,7 @@ static void set_plane_config(
	memset(&tbl_entry, 0, sizeof(tbl_entry));
	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;

	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
	dce_enable_fe_clock(dc->hwseq, mi->inst, true);

	set_default_colors(pipe_ctx);
	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
@@ -2495,7 +2495,7 @@ void dce110_fill_display_configs(

		num_cfgs++;
		cfg->signal = pipe_ctx->stream->signal;
		cfg->pipe_idx = pipe_ctx->pipe_idx;
		cfg->pipe_idx = pipe_ctx->stream_res.tg->inst;
		cfg->src_height = stream->src.height;
		cfg->src_width = stream->src.width;
		cfg->ddi_channel_mapping =
@@ -2659,7 +2659,7 @@ static void dce110_program_front_end_for_pipe(
	memset(&adjust, 0, sizeof(adjust));
	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;

	dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
	dce_enable_fe_clock(dc->hwseq, mi->inst, true);

	set_default_colors(pipe_ctx);
	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
@@ -2817,7 +2817,7 @@ static void dce110_apply_ctx_for_surface(

static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	int fe_idx = pipe_ctx->pipe_idx;
	int fe_idx = pipe_ctx->plane_res.mi->inst;

	/* Do not power down fe when stream is active on dce*/
	if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
+2 −2
Original line number Diff line number Diff line
@@ -700,7 +700,7 @@ static void get_pixel_clock_parameters(
	pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
	pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
	pixel_clk_params->signal_type = pipe_ctx->stream->signal;
	pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
	pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
	/* TODO: un-hardcode*/
	pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
						LINK_RATE_REF_FREQ_IN_KHZ;
@@ -973,7 +973,7 @@ static struct pipe_ctx *dce110_acquire_underlay(

		dc->hwss.enable_display_power_gating(
				dc,
				pipe_ctx->pipe_idx,
				pipe_ctx->stream_res.tg->inst,
				dcb, PIPE_GATING_CONTROL_DISABLE);

		/*
+40 −23
Original line number Diff line number Diff line
@@ -597,8 +597,8 @@ static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
/* trigger HW to start disconnect plane from stream on the next vsync */
static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	int fe_idx = pipe_ctx->pipe_idx;
	struct hubp *hubp = dc->res_pool->hubps[fe_idx];
	struct hubp *hubp = pipe_ctx->plane_res.hubp;
	int dpp_id = pipe_ctx->plane_res.dpp->inst;
	struct mpc *mpc = dc->res_pool->mpc;
	int opp_id;
	struct mpc_tree *mpc_tree_params;
@@ -609,7 +609,7 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
		struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];

		mpc_tree_params = &(opp->mpc_tree_params);
		mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
		mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
		if (mpcc_to_remove != NULL)
			break;
	}
@@ -619,7 +619,7 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
		return;

	mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
	dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[fe_idx] = true;
	dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;

	dc->optimized_required = true;

@@ -630,21 +630,21 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
		dcn10_verify_allow_pstate_change_high(dc);
}

static void plane_atomic_power_down(struct dc *dc, int fe_idx)
static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	struct dce_hwseq *hws = dc->hwseq;
	struct dpp *dpp = dc->res_pool->dpps[fe_idx];
	struct dpp *dpp = pipe_ctx->plane_res.dpp;

	if (REG(DC_IP_REQUEST_CNTL)) {
		REG_SET(DC_IP_REQUEST_CNTL, 0,
				IP_REQUEST_EN, 1);
		dpp_pg_control(hws, fe_idx, false);
		hubp_pg_control(hws, fe_idx, false);
		dpp_pg_control(hws, dpp->inst, false);
		hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, false);
		dpp->funcs->dpp_reset(dpp);
		REG_SET(DC_IP_REQUEST_CNTL, 0,
				IP_REQUEST_EN, 0);
		dm_logger_write(dc->ctx->logger, LOG_DEBUG,
				"Power gated front end %d\n", fe_idx);
				"Power gated front end %d\n", pipe_ctx->pipe_idx);
	}
}

@@ -653,16 +653,16 @@ static void plane_atomic_power_down(struct dc *dc, int fe_idx)
 */
static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	int fe_idx = pipe_ctx->pipe_idx;
	struct dce_hwseq *hws = dc->hwseq;
	struct hubp *hubp = dc->res_pool->hubps[fe_idx];
	struct hubp *hubp = pipe_ctx->plane_res.hubp;
	int opp_id = hubp->opp_id;
	int dpp_id = pipe_ctx->plane_res.dpp->inst;

	dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);

	hubp->funcs->hubp_clk_cntl(hubp, false);

	REG_UPDATE(DPP_CONTROL[fe_idx],
	REG_UPDATE(DPP_CONTROL[dpp_id],
			DPP_CLOCK_ENABLE, 0);

	if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
@@ -672,7 +672,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
	hubp->power_gated = true;
	dc->optimized_required = false; /* We're powering off, no need to optimize */

	plane_atomic_power_down(dc, fe_idx);
	plane_atomic_power_down(dc, pipe_ctx);

	pipe_ctx->stream = NULL;
	memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
@@ -768,18 +768,21 @@ static void dcn10_init_hw(struct dc *dc)
		struct timing_generator *tg = dc->res_pool->timing_generators[i];
		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
		struct hubp *hubp = dc->res_pool->hubps[i];
		struct dpp *dpp = dc->res_pool->dpps[i];

		pipe_ctx->stream_res.tg = tg;
		pipe_ctx->pipe_idx = i;

		pipe_ctx->plane_res.hubp = hubp;
		hubp->mpcc_id = i;
		pipe_ctx->plane_res.dpp = dpp;
		pipe_ctx->plane_res.mpcc_inst = dpp->inst;
		hubp->mpcc_id = dpp->inst;
		hubp->opp_id = 0xf;
		hubp->power_gated = false;

		dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
		dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
		dc->res_pool->opps[i]->mpcc_disconnect_pending[i] = true;
		dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
		pipe_ctx->stream_res.opp = dc->res_pool->opps[i];

		plane_atomic_disconnect(dc, pipe_ctx);
@@ -1323,7 +1326,7 @@ static void dcn10_enable_plane(
	undo_DEGVIDCN10_253_wa(dc);

	power_on_plane(dc->hwseq,
		pipe_ctx->pipe_idx);
		pipe_ctx->plane_res.hubp->inst);

	/* enable DCFCLK current DCHUB */
	pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
@@ -1687,7 +1690,7 @@ static void update_dchubp_dpp(
	if (plane_state->update_flags.bits.full_update) {
		enable_dppclk(
			dc->hwseq,
			pipe_ctx->pipe_idx,
			pipe_ctx->plane_res.dpp->inst,
			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk,
			context->bw.dcn.calc_clk.dppclk_div);
		dc->current_state->bw.dcn.cur_clk.dppclk_div =
@@ -2231,12 +2234,24 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
	return;
}

static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
{
	int i;

	for (i = 0; i < res_pool->pipe_count; i++) {
		if (res_pool->hubps[i]->inst == mpcc_inst)
			return res_pool->hubps[i];
	}
	ASSERT(false);
	return NULL;
}

static void dcn10_wait_for_mpcc_disconnect(
		struct dc *dc,
		struct resource_pool *res_pool,
		struct pipe_ctx *pipe_ctx)
{
	int i;
	int mpcc_inst;

	if (dc->debug.sanity_checks) {
		dcn10_verify_allow_pstate_change_high(dc);
@@ -2245,11 +2260,13 @@ static void dcn10_wait_for_mpcc_disconnect(
	if (!pipe_ctx->stream_res.opp)
		return;

	for (i = 0; i < MAX_PIPES; i++) {
		if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
			res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
			pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
			res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
	for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
		if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
			struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);

			res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
			pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
			hubp->funcs->set_blank(hubp, true);
			/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
					"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
					i);*/
Loading