Commit 8fde60b7 authored by Fatemeh Darbehani's avatar Fatemeh Darbehani Committed by Alex Deucher
Browse files

drm/amd/display: Add Vline1 interrupt source to InterruptManager



[Why]
Enhanced sync need to use vertical_interrupt1.

[How]
Add vertical_interrupt1 source to irq manger,
Implment setup vline interrupt interface.

Signed-off-by: default avatarFatemeh Darbehani <fatemeh.darbehani@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 43a6a02e
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1463,11 +1463,13 @@ static void commit_planes_do_stream_update(struct dc *dc,
					stream_update->adjust->v_total_min,
					stream_update->adjust->v_total_max);

			if (stream_update->periodic_fn_vsync_delta &&
					pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
			if (stream_update->vline0_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
				pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
					pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing,
					pipe_ctx->stream->periodic_fn_vsync_delta);
					pipe_ctx->stream_res.tg, VLINE0, stream->vline0_config);

			if (stream_update->vline1_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
				pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
					pipe_ctx->stream_res.tg, VLINE1, stream->vline1_config);

			if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
					stream_update->vrr_infopacket ||
+11 −3
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ struct freesync_context {
	bool dummy;
};

struct vline_config {
	unsigned int start_line;
	unsigned int end_line;
};

struct dc_stream_state {
	// sink is deprecated, new code should not reference
	// this pointer
@@ -85,8 +90,6 @@ struct dc_stream_state {
	uint8_t qs_bit;
	uint8_t qy_bit;

	unsigned long long periodic_fn_vsync_delta;

	/* TODO: custom INFO packets */
	/* TODO: ABM info (DMCU) */
	/* PSR info */
@@ -96,6 +99,9 @@ struct dc_stream_state {
	/* DMCU info */
	unsigned int abm_level;

	struct vline_config vline0_config;
	struct vline_config vline1_config;

	/* from core_stream struct */
	struct dc_context *ctx;

@@ -143,7 +149,9 @@ struct dc_stream_update {
	struct dc_info_packet *hdr_static_metadata;
	unsigned int *abm_level;

	unsigned long long *periodic_fn_vsync_delta;
	struct vline_config *vline0_config;
	struct vline_config *vline1_config;

	struct dc_crtc_timing_adjust *adjust;
	struct dc_info_packet *vrr_infopacket;
	struct dc_info_packet *vsc_infopacket;
+15 −57
Original line number Diff line number Diff line
@@ -92,68 +92,26 @@ static void optc1_disable_stereo(struct timing_generator *optc)
		OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
}

static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing)
{
	struct dc_crtc_timing patched_crtc_timing;
	int vesa_sync_start;
	int asic_blank_end;
	int vertical_line_start;

	patched_crtc_timing = *dc_crtc_timing;
	optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);

	vesa_sync_start = patched_crtc_timing.v_addressable +
			patched_crtc_timing.v_border_bottom +
			patched_crtc_timing.v_front_porch;

	asic_blank_end = (patched_crtc_timing.v_total -
			vesa_sync_start -
			patched_crtc_timing.v_border_top);

	vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
	if (vertical_line_start < 0)
		vertical_line_start = 0;

	return vertical_line_start;
}

void optc1_program_vline_interrupt(
		struct timing_generator *optc,
		const struct dc_crtc_timing *dc_crtc_timing,
		unsigned long long vsync_delta)
		enum vline_select vline,
		struct vline_config vline_config)
{

	struct optc *optc1 = DCN10TG_FROM_TG(optc);

	unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000);
	unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_100hz + 999), 1000);
	uint32_t req_delta_lines = (uint32_t) div64_u64(
			(req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1),
								dc_crtc_timing->h_total);

	uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing);
	uint32_t start_line = 0;
	uint32_t end_line = 0;

	if (req_delta_lines != 0)
		req_delta_lines--;

	if (req_delta_lines > vsync_line)
		start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) + 2;
	else
		start_line = vsync_line - req_delta_lines;

	end_line = start_line + 2;

	if (start_line >= dc_crtc_timing->v_total)
		start_line = start_line % dc_crtc_timing->v_total;

	if (end_line >= dc_crtc_timing->v_total)
		end_line = end_line % dc_crtc_timing->v_total;

	switch (vline) {
	case VLINE0:
		REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
			OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
			OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
				OTG_VERTICAL_INTERRUPT0_LINE_START, vline_config.start_line,
				OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config.end_line);
		break;
	case VLINE1:
		REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
					OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config.start_line);
		break;
	default:
		break;
	}
}

/**
+10 −2
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@
	SRI(OTG_CLOCK_CONTROL, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT1_CONTROL, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT1_POSITION, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
	SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
	SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
@@ -135,6 +137,8 @@ struct dcn_optc_registers {
	uint32_t OTG_CLOCK_CONTROL;
	uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL;
	uint32_t OTG_VERTICAL_INTERRUPT0_POSITION;
	uint32_t OTG_VERTICAL_INTERRUPT1_CONTROL;
	uint32_t OTG_VERTICAL_INTERRUPT1_POSITION;
	uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
	uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
	uint32_t OPTC_INPUT_CLOCK_CONTROL;
@@ -227,6 +231,8 @@ struct dcn_optc_registers {
	SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT1_CONTROL, OTG_VERTICAL_INTERRUPT1_INT_ENABLE, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT1_POSITION, OTG_VERTICAL_INTERRUPT1_LINE_START, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
	SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
	SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
@@ -361,6 +367,8 @@ struct dcn_optc_registers {
	type OTG_VERTICAL_INTERRUPT0_INT_ENABLE;\
	type OTG_VERTICAL_INTERRUPT0_LINE_START;\
	type OTG_VERTICAL_INTERRUPT0_LINE_END;\
	type OTG_VERTICAL_INTERRUPT1_INT_ENABLE;\
	type OTG_VERTICAL_INTERRUPT1_LINE_START;\
	type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
	type OTG_VERTICAL_INTERRUPT2_LINE_START;\
	type OPTC_INPUT_CLK_EN;\
@@ -476,8 +484,8 @@ void optc1_program_timing(
	bool use_vbios);

void optc1_program_vline_interrupt(struct timing_generator *optc,
		const struct dc_crtc_timing *dc_crtc_timing,
		unsigned long long vsync_delta);
		enum vline_select vline,
		struct vline_config vline_config);

void optc1_program_global_sync(
		struct timing_generator *optc);
+11 −2
Original line number Diff line number Diff line
@@ -134,6 +134,15 @@ struct dc_crtc_timing;

struct drr_params;

struct vline_config;


enum vline_select {
	VLINE0,
	VLINE1,
	VLINE2
};

struct timing_generator_funcs {
	bool (*validate_timing)(struct timing_generator *tg,
							const struct dc_crtc_timing *timing);
@@ -141,8 +150,8 @@ struct timing_generator_funcs {
							const struct dc_crtc_timing *timing,
							bool use_vbios);
	void (*program_vline_interrupt)(struct timing_generator *optc,
			const struct dc_crtc_timing *dc_crtc_timing,
			unsigned long long vsync_delta);
			enum vline_select vline,
			struct vline_config vline_config);
	bool (*enable_crtc)(struct timing_generator *tg);
	bool (*disable_crtc)(struct timing_generator *tg);
	bool (*is_counter_moving)(struct timing_generator *tg);
Loading