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

Commit 39b485e4 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher
Browse files

drm/amd/display: fix cursor related Pstate hang



Move cursor programming to inside the OTG_MASTER_UPDATE_LOCK

If graphics plane go from 1 pipe to hsplit, the cursor updates
after mpc programming and unlock. Which means there is a window
of time where cursor is enabled on the wrong pipe if it's on
the right side of the screen (i.e. case where cursor need to
move from pipe 0 to pipe 3 post split). This will cause pstate hang.

Solution is to program the cursor while still locked.

Signed-off-by: default avatarEric Yang <Eric.Yang2@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 43b9d273
Loading
Loading
Loading
Loading
+4 −64
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes(

	core_dc = stream->ctx->dc;
	res_ctx = &core_dc->current_state->res_ctx;
	stream->cursor_attributes = *attributes;

	for (i = 0; i < MAX_PIPES; i++) {
		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
@@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes(
			continue;


		if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
			pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
						pipe_ctx->plane_res.ipp, attributes);

		if (pipe_ctx->plane_res.hubp != NULL &&
				pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
			pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
					pipe_ctx->plane_res.hubp, attributes);

		if (pipe_ctx->plane_res.mi != NULL &&
				pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
			pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
					pipe_ctx->plane_res.mi, attributes);


		if (pipe_ctx->plane_res.xfm != NULL &&
				pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
			pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
				pipe_ctx->plane_res.xfm, attributes);

		if (pipe_ctx->plane_res.dpp != NULL &&
				pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
			pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
				pipe_ctx->plane_res.dpp, attributes->color_format);
		core_dc->hwss.set_cursor_attribute(pipe_ctx);
	}

	stream->cursor_attributes = *attributes;

	return true;
}

@@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position(

	core_dc = stream->ctx->dc;
	res_ctx = &core_dc->current_state->res_ctx;
	stream->cursor_position = *position;

	for (i = 0; i < MAX_PIPES; i++) {
		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
		struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
		struct mem_input *mi = pipe_ctx->plane_res.mi;
		struct hubp *hubp = pipe_ctx->plane_res.hubp;
		struct dpp *dpp = pipe_ctx->plane_res.dpp;
		struct dc_cursor_position pos_cpy = *position;
		struct dc_cursor_mi_param param = {
			.pixel_clk_khz = stream->timing.pix_clk_khz,
			.ref_clk_khz = core_dc->res_pool->ref_clock_inKhz,
			.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
			.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
			.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
		};

		if (pipe_ctx->stream != stream ||
				(!pipe_ctx->plane_res.mi  && !pipe_ctx->plane_res.hubp) ||
@@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position(
				!pipe_ctx->plane_res.ipp)
			continue;

		if (pipe_ctx->plane_state->address.type
				== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
			pos_cpy.enable = false;

		if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
			pos_cpy.enable = false;


		if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL)
			ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);

		if (mi != NULL && mi->funcs->set_cursor_position != NULL)
			mi->funcs->set_cursor_position(mi, &pos_cpy, &param);

		if (!hubp)
			continue;

		if (hubp->funcs->set_cursor_position != NULL)
			hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);

		if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
			dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);

		core_dc->hwss.set_cursor_position(pipe_ctx);
	}

	stream->cursor_position = *position;

	return true;
}

+40 −0
Original line number Diff line number Diff line
@@ -2930,6 +2930,44 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
	}
}

void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
{
	struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
	struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
	struct mem_input *mi = pipe_ctx->plane_res.mi;
	struct dc_cursor_mi_param param = {
		.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
		.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
		.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
		.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
		.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
	};

	if (pipe_ctx->plane_state->address.type
			== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
		pos_cpy.enable = false;

	if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
		pos_cpy.enable = false;

	ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
	mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
}

void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
{
	struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;

	pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
				pipe_ctx->plane_res.ipp, attributes);

	pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
			pipe_ctx->plane_res.mi, attributes);

	pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
		pipe_ctx->plane_res.xfm, attributes);
}

static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}

static void optimize_shared_resources(struct dc *dc) {}
@@ -2972,6 +3010,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
	.edp_backlight_control = hwss_edp_backlight_control,
	.edp_power_control = hwss_edp_power_control,
	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
	.set_cursor_position = dce110_set_cursor_position,
	.set_cursor_attribute = dce110_set_cursor_attribute
};

void dce110_hw_sequencer_construct(struct dc *dc)
+43 −2
Original line number Diff line number Diff line
@@ -1761,6 +1761,11 @@ static void update_dchubp_dpp(
			&pipe_ctx->plane_res.scl_data.viewport_c);
	}

	if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
		dc->hwss.set_cursor_position(pipe_ctx);
		dc->hwss.set_cursor_attribute(pipe_ctx);
	}

	if (plane_state->update_flags.bits.full_update) {
		/*gamut remap*/
		program_gamut_remap(pipe_ctx);
@@ -2296,7 +2301,7 @@ static bool dcn10_dummy_display_power_gating(
	return true;
}

void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
{
	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
	struct timing_generator *tg = pipe_ctx->stream_res.tg;
@@ -2316,12 +2321,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
	}
}

void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
{
	if (hws->ctx->dc->res_pool->hubbub != NULL)
		hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
}

static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
{
	struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
	struct hubp *hubp = pipe_ctx->plane_res.hubp;
	struct dpp *dpp = pipe_ctx->plane_res.dpp;
	struct dc_cursor_mi_param param = {
		.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
		.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
		.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
		.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
		.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
	};

	if (pipe_ctx->plane_state->address.type
			== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
		pos_cpy.enable = false;

	if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
		pos_cpy.enable = false;

	hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
	dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
}

static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
{
	struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;

	pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
			pipe_ctx->plane_res.hubp, attributes);
	pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
		pipe_ctx->plane_res.dpp, attributes->color_format);
}

static const struct hw_sequencer_funcs dcn10_funcs = {
	.program_gamut_remap = program_gamut_remap,
	.program_csc_matrix = program_csc_matrix,
@@ -2362,6 +2401,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
	.edp_backlight_control = hwss_edp_backlight_control,
	.edp_power_control = hwss_edp_power_control,
	.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
	.set_cursor_position = dcn10_set_cursor_position,
	.set_cursor_attribute = dcn10_set_cursor_attribute
};


+3 −0
Original line number Diff line number Diff line
@@ -198,6 +198,9 @@ struct hw_sequencer_funcs {
			bool enable);
	void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);

	void (*set_cursor_position)(struct pipe_ctx *pipe);
	void (*set_cursor_attribute)(struct pipe_ctx *pipe);

};

void color_space_to_black_color(