Commit 60df8441 authored by Wyatt Wood's avatar Wyatt Wood Committed by Alex Deucher
Browse files

drm/amd/display: Refactor visual confirm



[Why + How]
Visual confirm has no asic-specific logic,
so we can refactor and unify these functions
that are currently spread out across multiple
dcn files.
Add a new hw sequencer interface update_visual_confirm_color,
and a new mpc function pointer set_bg_color.
This will allow visual confirm to updated independently
of MPCC blending updates.

v2: squash in DCN3.1 fixes

Signed-off-by: default avatarWyatt Wood <wyatt.wood@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarStylon Wang <stylon.wang@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2259918e
Loading
Loading
Loading
Loading
+98 −0
Original line number Diff line number Diff line
@@ -291,3 +291,101 @@ bool hwss_wait_for_blank_complete(

	return true;
}

void get_mpctree_visual_confirm_color(
		struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	const struct tg_color pipe_colors[6] = {
			{MAX_TG_COLOR_VALUE, 0, 0}, /* red */
			{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */
			{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */
			{0, MAX_TG_COLOR_VALUE, 0}, /* green */
			{0, 0, MAX_TG_COLOR_VALUE}, /* blue */
			{MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */
	};

	struct pipe_ctx *top_pipe = pipe_ctx;

	while (top_pipe->top_pipe)
		top_pipe = top_pipe->top_pipe;

	*color = pipe_colors[top_pipe->pipe_idx];
}

void get_surface_visual_confirm_color(
		const struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	uint32_t color_value = MAX_TG_COLOR_VALUE;

	switch (pipe_ctx->plane_res.scl_data.format) {
	case PIXEL_FORMAT_ARGB8888:
		/* set border color to red */
		color->color_r_cr = color_value;
		break;

	case PIXEL_FORMAT_ARGB2101010:
		/* set border color to blue */
		color->color_b_cb = color_value;
		break;
	case PIXEL_FORMAT_420BPP8:
		/* set border color to green */
		color->color_g_y = color_value;
		break;
	case PIXEL_FORMAT_420BPP10:
		/* set border color to yellow */
		color->color_g_y = color_value;
		color->color_r_cr = color_value;
		break;
	case PIXEL_FORMAT_FP16:
		/* set border color to white */
		color->color_r_cr = color_value;
		color->color_b_cb = color_value;
		color->color_g_y = color_value;
		break;
	default:
		break;
	}
}

void get_hdr_visual_confirm_color(
		struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	uint32_t color_value = MAX_TG_COLOR_VALUE;

	/* Determine the overscan color based on the top-most (desktop) plane's context */
	struct pipe_ctx *top_pipe_ctx  = pipe_ctx;

	while (top_pipe_ctx->top_pipe != NULL)
		top_pipe_ctx = top_pipe_ctx->top_pipe;

	switch (top_pipe_ctx->plane_res.scl_data.format) {
	case PIXEL_FORMAT_ARGB2101010:
		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
			/* HDR10, ARGB2101010 - set border color to red */
			color->color_r_cr = color_value;
		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
			/* FreeSync 2 ARGB2101010 - set border color to pink */
			color->color_r_cr = color_value;
			color->color_b_cb = color_value;
		}
		break;
	case PIXEL_FORMAT_FP16:
		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
			/* HDR10, FP16 - set border color to blue */
			color->color_b_cb = color_value;
		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
			/* FreeSync 2 HDR - set border color to green */
			color->color_g_y = color_value;
		}
		break;
	default:
		/* SDR - set border color to Gray */
		color->color_r_cr = color_value/2;
		color->color_b_cb = color_value/2;
		color->color_g_y = color_value/2;
		break;
	}
}
+0 −35
Original line number Diff line number Diff line
@@ -1312,41 +1312,6 @@ static void build_audio_output(
			pipe_ctx->pll_settings.ss_percentage;
}

static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4;

	switch (pipe_ctx->plane_res.scl_data.format) {
	case PIXEL_FORMAT_ARGB8888:
		/* set boarder color to red */
		color->color_r_cr = color_value;
		break;

	case PIXEL_FORMAT_ARGB2101010:
		/* set boarder color to blue */
		color->color_b_cb = color_value;
		break;
	case PIXEL_FORMAT_420BPP8:
		/* set boarder color to green */
		color->color_g_y = color_value;
		break;
	case PIXEL_FORMAT_420BPP10:
		/* set boarder color to yellow */
		color->color_g_y = color_value;
		color->color_r_cr = color_value;
		break;
	case PIXEL_FORMAT_FP16:
		/* set boarder color to white */
		color->color_r_cr = color_value;
		color->color_b_cb = color_value;
		color->color_g_y = color_value;
		break;
	default:
		break;
	}
}

static void program_scaler(const struct dc *dc,
		const struct pipe_ctx *pipe_ctx)
{
+18 −90
Original line number Diff line number Diff line
@@ -2407,83 +2407,6 @@ void dcn10_program_output_csc(struct dc *dc,
	}
}

void dcn10_get_surface_visual_confirm_color(
		const struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	uint32_t color_value = MAX_TG_COLOR_VALUE;

	switch (pipe_ctx->plane_res.scl_data.format) {
	case PIXEL_FORMAT_ARGB8888:
		/* set border color to red */
		color->color_r_cr = color_value;
		break;

	case PIXEL_FORMAT_ARGB2101010:
		/* set border color to blue */
		color->color_b_cb = color_value;
		break;
	case PIXEL_FORMAT_420BPP8:
		/* set border color to green */
		color->color_g_y = color_value;
		break;
	case PIXEL_FORMAT_420BPP10:
		/* set border color to yellow */
		color->color_g_y = color_value;
		color->color_r_cr = color_value;
		break;
	case PIXEL_FORMAT_FP16:
		/* set border color to white */
		color->color_r_cr = color_value;
		color->color_b_cb = color_value;
		color->color_g_y = color_value;
		break;
	default:
		break;
	}
}

void dcn10_get_hdr_visual_confirm_color(
		struct pipe_ctx *pipe_ctx,
		struct tg_color *color)
{
	uint32_t color_value = MAX_TG_COLOR_VALUE;

	// Determine the overscan color based on the top-most (desktop) plane's context
	struct pipe_ctx *top_pipe_ctx  = pipe_ctx;

	while (top_pipe_ctx->top_pipe != NULL)
		top_pipe_ctx = top_pipe_ctx->top_pipe;

	switch (top_pipe_ctx->plane_res.scl_data.format) {
	case PIXEL_FORMAT_ARGB2101010:
		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
			/* HDR10, ARGB2101010 - set border color to red */
			color->color_r_cr = color_value;
		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
			/* FreeSync 2 ARGB2101010 - set border color to pink */
			color->color_r_cr = color_value;
			color->color_b_cb = color_value;
		}
		break;
	case PIXEL_FORMAT_FP16:
		if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
			/* HDR10, FP16 - set border color to blue */
			color->color_b_cb = color_value;
		} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
			/* FreeSync 2 HDR - set border color to green */
			color->color_g_y = color_value;
		}
		break;
	default:
		/* SDR - set border color to Gray */
		color->color_r_cr = color_value/2;
		color->color_b_cb = color_value/2;
		color->color_g_y = color_value/2;
		break;
	}
}

static void dcn10_update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
{
	struct dc_bias_and_scale bns_params = {0};
@@ -2502,9 +2425,24 @@ static void dcn10_update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state
		dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
}

void dcn10_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, struct tg_color *color, int mpcc_id)
{
	struct mpc *mpc = dc->res_pool->mpc;

	if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR)
		get_hdr_visual_confirm_color(pipe_ctx, color);
	else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
		get_surface_visual_confirm_color(pipe_ctx, color);
	else
		color_space_to_black_color(
				dc, pipe_ctx->stream->output_color_space, color);

	if (mpc->funcs->set_bg_color)
		mpc->funcs->set_bg_color(mpc, color, mpcc_id);
}

void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
	struct dce_hwseq *hws = dc->hwseq;
	struct hubp *hubp = pipe_ctx->plane_res.hubp;
	struct mpcc_blnd_cfg blnd_cfg = {{0}};
	bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
@@ -2513,18 +2451,6 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
	struct mpc *mpc = dc->res_pool->mpc;
	struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);

	if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
		hws->funcs.get_hdr_visual_confirm_color(
				pipe_ctx, &blnd_cfg.black_color);
	} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
		hws->funcs.get_surface_visual_confirm_color(
				pipe_ctx, &blnd_cfg.black_color);
	} else {
		color_space_to_black_color(
				dc, pipe_ctx->stream->output_color_space,
				&blnd_cfg.black_color);
	}

	if (per_pixel_alpha)
		blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
	else
@@ -2559,6 +2485,7 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
	/* If there is no full update, don't need to touch MPC tree*/
	if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
		mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
		dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
		return;
	}

@@ -2580,6 +2507,7 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
			NULL,
			hubp->inst,
			mpcc_id);
	dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);

	ASSERT(new_mpcc != NULL);

+6 −6
Original line number Diff line number Diff line
@@ -189,12 +189,6 @@ void dcn10_bios_golden_init(struct dc *dc);
void dcn10_plane_atomic_power_down(struct dc *dc,
		struct dpp *dpp,
		struct hubp *hubp);
void dcn10_get_surface_visual_confirm_color(
		const struct pipe_ctx *pipe_ctx,
		struct tg_color *color);
void dcn10_get_hdr_visual_confirm_color(
		struct pipe_ctx *pipe_ctx,
		struct tg_color *color);
bool dcn10_disconnect_pipes(
		struct dc *dc,
		struct dc_state *context);
@@ -206,4 +200,10 @@ void dcn10_verify_allow_pstate_change_high(struct dc *dc);

void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits);

void dcn10_update_visual_confirm_color(
		struct dc *dc,
		struct pipe_ctx *pipe_ctx,
		struct tg_color *color,
		int mpcc_id);

#endif /* __DC_HWSS_DCN10_H__ */
+1 −2
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
	.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
	.set_pipe = dce110_set_pipe,
	.get_dcc_en_bits = dcn10_get_dcc_en_bits,
	.update_visual_confirm_color = dcn10_update_visual_confirm_color,
};

static const struct hwseq_private_funcs dcn10_private_funcs = {
@@ -111,8 +112,6 @@ static const struct hwseq_private_funcs dcn10_private_funcs = {
	.dpp_pg_control = dcn10_dpp_pg_control,
	.hubp_pg_control = dcn10_hubp_pg_control,
	.dsc_pg_control = NULL,
	.get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color,
	.get_hdr_visual_confirm_color = dcn10_get_hdr_visual_confirm_color,
	.set_hdr_multiplier = dcn10_set_hdr_multiplier,
	.verify_allow_pstate_change_high = dcn10_verify_allow_pstate_change_high,
};
Loading