aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch559
1 files changed, 559 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch
new file mode 100644
index 00000000..e529e9b8
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1269-drm-amd-display-Refactor-for-setup-periodic-interrup.patch
@@ -0,0 +1,559 @@
+From 8f93bafbf9ff52601046e93a9730e8caec6eb583 Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <yongqiang.sun@amd.com>
+Date: Fri, 25 Jan 2019 14:40:14 -0500
+Subject: [PATCH 1269/2940] drm/amd/display: Refactor for setup periodic
+ interrupt.
+
+[Why]
+Current periodic interrupt start point calc in optc
+is not clear.
+
+[How]
+1. DM convert delta time to lines number and dc will calculate the
+ start position as per lines number and interrupt type.
+2. hwss calculates the start point as per line offset.
+3. optc programs vertical interrupts register as per start point
+ and interrupt source.
+
+Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 12 +-
+ drivers/gpu/drm/amd/display/dc/dc_stream.h | 24 ++-
+ .../display/dc/dce110/dce110_hw_sequencer.c | 6 +-
+ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 145 +++++++++++++++++-
+ .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 2 +
+ .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 133 +++-------------
+ .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 13 +-
+ .../amd/display/dc/inc/hw/timing_generator.h | 23 ++-
+ .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 8 +
+ 9 files changed, 215 insertions(+), 151 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 3625624bb1e7..0099e625ac88 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1623,13 +1623,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_vsync_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, VLINE0, &stream->periodic_vsync_config);
++ if (stream_update->periodic_interrupt0 &&
++ dc->hwss.setup_periodic_interrupt)
++ dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE0);
+
+- if (stream_update->enhanced_sync_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, VLINE1, &stream->enhanced_sync_config);
++ if (stream_update->periodic_interrupt1 &&
++ dc->hwss.setup_periodic_interrupt)
++ dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE1);
+
+ if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->vrr_infopacket ||
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+index a798694992b9..5657cb3a2ad3 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+@@ -51,9 +51,19 @@ struct freesync_context {
+ bool dummy;
+ };
+
+-union vline_config {
+- unsigned int line_number;
+- unsigned long long delta_in_ns;
++enum vertical_interrupt_ref_point {
++ START_V_UPDATE = 0,
++ START_V_SYNC,
++ INVALID_POINT
++
++ //For now, only v_update interrupt is used.
++ //START_V_BLANK,
++ //START_V_ACTIVE
++};
++
++struct periodic_interrupt_config {
++ enum vertical_interrupt_ref_point ref_point;
++ int lines_offset;
+ };
+
+
+@@ -106,8 +116,8 @@ struct dc_stream_state {
+ /* DMCU info */
+ unsigned int abm_level;
+
+- union vline_config periodic_vsync_config;
+- union vline_config enhanced_sync_config;
++ struct periodic_interrupt_config periodic_interrupt0;
++ struct periodic_interrupt_config periodic_interrupt1;
+
+ /* from core_stream struct */
+ struct dc_context *ctx;
+@@ -158,8 +168,8 @@ struct dc_stream_update {
+ struct dc_info_packet *hdr_static_metadata;
+ unsigned int *abm_level;
+
+- union vline_config *periodic_vsync_config;
+- union vline_config *enhanced_sync_config;
++ struct periodic_interrupt_config *periodic_interrupt0;
++ struct periodic_interrupt_config *periodic_interrupt1;
+
+ struct dc_crtc_timing_adjust *adjust;
+ struct dc_info_packet *vrr_infopacket;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+index b5fe3eb3c93c..702dfe0a2e2b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+@@ -1333,10 +1333,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
+ if (!pipe_ctx->stream->apply_seamless_boot_optimization)
+ dc->hwss.enable_stream_timing(pipe_ctx, context, dc);
+
+- if (pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt)
+- pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt(
+- pipe_ctx->stream_res.tg,
+- &stream->timing);
++ if (dc->hwss.setup_vupdate_interrupt)
++ dc->hwss.setup_vupdate_interrupt(pipe_ctx);
+
+ params.vertical_total_min = stream->adjust.v_total_min;
+ params.vertical_total_max = stream->adjust.v_total_max;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 23b85a3f1b79..b910d6e3ed83 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -2740,6 +2740,147 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
+ pipe_ctx->plane_res.dpp, &opt_attr);
+ }
+
++/**
++* apply_front_porch_workaround TODO FPGA still need?
++*
++* This is a workaround for a bug that has existed since R5xx and has not been
++* fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
++*/
++static void apply_front_porch_workaround(
++ struct dc_crtc_timing *timing)
++{
++ if (timing->flags.INTERLACE == 1) {
++ if (timing->v_front_porch < 2)
++ timing->v_front_porch = 2;
++ } else {
++ if (timing->v_front_porch < 1)
++ timing->v_front_porch = 1;
++ }
++}
++
++int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
++{
++ struct timing_generator *optc = pipe_ctx->stream_res.tg;
++ const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
++ struct dc_crtc_timing patched_crtc_timing;
++ int vesa_sync_start;
++ int asic_blank_end;
++ int interlace_factor;
++ int vertical_line_start;
++
++ patched_crtc_timing = *dc_crtc_timing;
++ apply_front_porch_workaround(&patched_crtc_timing);
++
++ interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
++
++ 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)
++ * interlace_factor;
++
++ vertical_line_start = asic_blank_end -
++ optc->dlg_otg_param.vstartup_start + 1;
++
++ return vertical_line_start;
++}
++
++static void calc_vupdate_position(
++ struct pipe_ctx *pipe_ctx,
++ uint32_t *start_line,
++ uint32_t *end_line)
++{
++ const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
++ int vline_int_offset_from_vupdate =
++ pipe_ctx->stream->periodic_interrupt0.lines_offset;
++ int vupdate_offset_from_vsync = get_vupdate_offset_from_vsync(pipe_ctx);
++ int start_position;
++
++ if (vline_int_offset_from_vupdate > 0)
++ vline_int_offset_from_vupdate--;
++ else if (vline_int_offset_from_vupdate < 0)
++ vline_int_offset_from_vupdate++;
++
++ start_position = vline_int_offset_from_vupdate + vupdate_offset_from_vsync;
++
++ if (start_position >= 0)
++ *start_line = start_position;
++ else
++ *start_line = dc_crtc_timing->v_total + start_position - 1;
++
++ *end_line = *start_line + 2;
++
++ if (*end_line >= dc_crtc_timing->v_total)
++ *end_line = 2;
++}
++
++static void cal_vline_position(
++ struct pipe_ctx *pipe_ctx,
++ enum vline_select vline,
++ uint32_t *start_line,
++ uint32_t *end_line)
++{
++ enum vertical_interrupt_ref_point ref_point = INVALID_POINT;
++
++ if (vline == VLINE0)
++ ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point;
++ else if (vline == VLINE1)
++ ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point;
++
++ switch (ref_point) {
++ case START_V_UPDATE:
++ calc_vupdate_position(
++ pipe_ctx,
++ start_line,
++ end_line);
++ break;
++ case START_V_SYNC:
++ // Suppose to do nothing because vsync is 0;
++ break;
++ default:
++ ASSERT(0);
++ break;
++ }
++}
++
++static void dcn10_setup_periodic_interrupt(
++ struct pipe_ctx *pipe_ctx,
++ enum vline_select vline)
++{
++ struct timing_generator *tg = pipe_ctx->stream_res.tg;
++
++ if (vline == VLINE0) {
++ uint32_t start_line = 0;
++ uint32_t end_line = 0;
++
++ cal_vline_position(pipe_ctx, vline, &start_line, &end_line);
++
++ tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
++
++ } else if (vline == VLINE1) {
++ pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1(
++ tg,
++ pipe_ctx->stream->periodic_interrupt1.lines_offset);
++ }
++}
++
++static void dcn10_setup_vupdate_interrupt(struct pipe_ctx *pipe_ctx)
++{
++ struct timing_generator *tg = pipe_ctx->stream_res.tg;
++ int start_line = get_vupdate_offset_from_vsync(pipe_ctx);
++
++ if (start_line < 0) {
++ ASSERT(0);
++ start_line = 0;
++ }
++
++ if (tg->funcs->setup_vertical_interrupt2)
++ tg->funcs->setup_vertical_interrupt2(tg, start_line);
++}
++
+ static const struct hw_sequencer_funcs dcn10_funcs = {
+ .program_gamut_remap = program_gamut_remap,
+ .init_hw = dcn10_init_hw,
+@@ -2789,7 +2930,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
+ .set_cursor_attribute = dcn10_set_cursor_attribute,
+ .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
+ .disable_stream_gating = NULL,
+- .enable_stream_gating = NULL
++ .enable_stream_gating = NULL,
++ .setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
++ .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt
+ };
+
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+index f8eea10e4c64..6d66084df55f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+@@ -81,4 +81,6 @@ struct pipe_ctx *find_top_pipe_for_stream(
+ struct dc_state *context,
+ const struct dc_stream_state *stream);
+
++int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
++
+ #endif /* __DC_HWSS_DCN10_H__ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+index 2f78a84f0dcb..0345d51e9d6f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+@@ -92,134 +92,36 @@ 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 interlace_factor;
+- 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.h_addressable +
+- patched_crtc_timing.h_border_right +
+- patched_crtc_timing.h_front_porch;
+-
+- asic_blank_end = patched_crtc_timing.h_total -
+- vesa_sync_start -
+- patched_crtc_timing.h_border_left;
+-
+- interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
+-
+- 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)
+- * interlace_factor;
+-
+- vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
+- if (vertical_line_start < 0) {
+- ASSERT(0);
+- vertical_line_start = 0;
+- }
+-
+- return vertical_line_start;
+-}
+-
+-static void calc_vline_position(
++void optc1_setup_vertical_interrupt0(
+ struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- unsigned long long vsync_delta,
+- uint32_t *start_line,
+- uint32_t *end_line)
++ uint32_t start_line,
++ uint32_t end_line)
+ {
+- 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);
+-
+- 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) - 1;
+- else
+- *start_line = vsync_line - req_delta_lines;
+-
+- *end_line = *start_line + 2;
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+- if (*end_line >= dc_crtc_timing->v_total)
+- *end_line = 2;
++ REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
++ OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
++ OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
+ }
+
+-void optc1_program_vline_interrupt(
++void optc1_setup_vertical_interrupt1(
+ struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- enum vline_select vline,
+- const union vline_config *vline_config)
++ uint32_t start_line)
+ {
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- uint32_t start_line = 0;
+- uint32_t end_line = 0;
+-
+- switch (vline) {
+- case VLINE0:
+- calc_vline_position(optc, dc_crtc_timing, vline_config->delta_in_ns, &start_line, &end_line);
+- REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
+- OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
+- OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
+- break;
+- case VLINE1:
+- REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
+- OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config->line_number);
+- break;
+- default:
+- break;
+- }
++
++ REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
++ OTG_VERTICAL_INTERRUPT1_LINE_START, start_line);
+ }
+
+-void optc1_program_vupdate_interrupt(
++void optc1_setup_vertical_interrupt2(
+ struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing)
++ uint32_t start_line)
+ {
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+- int32_t vertical_line_start;
+- uint32_t asic_blank_end;
+- uint32_t vesa_sync_start;
+- struct dc_crtc_timing patched_crtc_timing;
+-
+- patched_crtc_timing = *dc_crtc_timing;
+- optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
+-
+- /* asic_h_blank_end = HsyncWidth + HbackPorch =
+- * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
+- * vesa.h_left_border
+- */
+- vesa_sync_start = patched_crtc_timing.h_addressable +
+- patched_crtc_timing.h_border_right +
+- patched_crtc_timing.h_front_porch;
+-
+- asic_blank_end = patched_crtc_timing.h_total -
+- vesa_sync_start -
+- patched_crtc_timing.h_border_left;
+-
+- /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
+- * program the reg for interrupt postition.
+- */
+- vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
+- if (vertical_line_start < 0)
+- vertical_line_start = 0;
+
+ REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
+- OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
++ OTG_VERTICAL_INTERRUPT2_LINE_START, start_line);
+ }
+
+ /**
+@@ -1480,8 +1382,9 @@ bool optc1_get_crc(struct timing_generator *optc,
+ static const struct timing_generator_funcs dcn10_tg_funcs = {
+ .validate_timing = optc1_validate_timing,
+ .program_timing = optc1_program_timing,
+- .program_vline_interrupt = optc1_program_vline_interrupt,
+- .program_vupdate_interrupt = optc1_program_vupdate_interrupt,
++ .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0,
++ .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1,
++ .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2,
+ .program_global_sync = optc1_program_global_sync,
+ .enable_crtc = optc1_enable_crtc,
+ .disable_crtc = optc1_disable_crtc,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+index 24452f11c598..4eb9a898c237 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+@@ -483,11 +483,16 @@ void optc1_program_timing(
+ const struct dc_crtc_timing *dc_crtc_timing,
+ bool use_vbios);
+
+-void optc1_program_vline_interrupt(
++void optc1_setup_vertical_interrupt0(
+ struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- enum vline_select vline,
+- const union vline_config *vline_config);
++ uint32_t start_line,
++ uint32_t end_line);
++void optc1_setup_vertical_interrupt1(
++ struct timing_generator *optc,
++ uint32_t start_line);
++void optc1_setup_vertical_interrupt2(
++ struct timing_generator *optc,
++ uint32_t start_line);
+
+ void optc1_program_global_sync(
+ struct timing_generator *optc);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+index 03ae941895f3..c25f7df7b5e3 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+@@ -134,14 +134,6 @@ struct dc_crtc_timing;
+
+ struct drr_params;
+
+-union vline_config;
+-
+-
+-enum vline_select {
+- VLINE0,
+- VLINE1,
+- VLINE2
+-};
+
+ struct timing_generator_funcs {
+ bool (*validate_timing)(struct timing_generator *tg,
+@@ -149,14 +141,17 @@ struct timing_generator_funcs {
+ void (*program_timing)(struct timing_generator *tg,
+ const struct dc_crtc_timing *timing,
+ bool use_vbios);
+- void (*program_vline_interrupt)(
++ void (*setup_vertical_interrupt0)(
++ struct timing_generator *optc,
++ uint32_t start_line,
++ uint32_t end_line);
++ void (*setup_vertical_interrupt1)(
++ struct timing_generator *optc,
++ uint32_t start_line);
++ void (*setup_vertical_interrupt2)(
+ struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing,
+- enum vline_select vline,
+- const union vline_config *vline_config);
++ uint32_t start_line);
+
+- void (*program_vupdate_interrupt)(struct timing_generator *optc,
+- const struct dc_crtc_timing *dc_crtc_timing);
+ bool (*enable_crtc)(struct timing_generator *tg);
+ bool (*disable_crtc)(struct timing_generator *tg);
+ bool (*is_counter_moving)(struct timing_generator *tg);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index fc03320c81a1..7676f25216b1 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -38,6 +38,11 @@ enum pipe_gating_control {
+ PIPE_GATING_CONTROL_INIT
+ };
+
++enum vline_select {
++ VLINE0,
++ VLINE1
++};
++
+ struct dce_hwseq_wa {
+ bool blnd_crtc_trigger;
+ bool DEGVIDCN10_253;
+@@ -224,6 +229,9 @@ struct hw_sequencer_funcs {
+ void (*set_cursor_attribute)(struct pipe_ctx *pipe);
+ void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe);
+
++ void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline);
++ void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
++
+ };
+
+ void color_space_to_black_color(
+--
+2.17.1
+