stream_update->adjust->v_total_min,
                                        stream_update->adjust->v_total_max);
 
-                       if (stream_update->vline0_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
+                       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, VLINE0, &stream->vline0_config);
+                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE0, &stream->periodic_vsync_config);
 
-                       if (stream_update->vline1_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
+                       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, VLINE1, &stream->vline1_config);
+                                       pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE1, &stream->enhanced_sync_config);
 
                        if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
                                        stream_update->vrr_infopacket ||
 
        bool dummy;
 };
 
-struct vline_config {
-       unsigned int start_line;
-       unsigned int end_line;
+union vline_config {
+       unsigned int line_number;
+       unsigned long long delta_in_ns;
 };
 
+
 struct dc_stream_state {
        // sink is deprecated, new code should not reference
        // this pointer
        /* DMCU info */
        unsigned int abm_level;
 
-       struct vline_config vline0_config;
-       struct vline_config vline1_config;
+       union vline_config periodic_vsync_config;
+       union vline_config enhanced_sync_config;
 
        /* from core_stream struct */
        struct dc_context *ctx;
        struct dc_info_packet *hdr_static_metadata;
        unsigned int *abm_level;
 
-       struct vline_config *vline0_config;
-       struct vline_config *vline1_config;
+       union vline_config *periodic_vsync_config;
+       union vline_config *enhanced_sync_config;
 
        struct dc_crtc_timing_adjust *adjust;
        struct dc_info_packet *vrr_infopacket;
 
                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(
+               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)
+{
+       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;
+
+               if (*end_line >= dc_crtc_timing->v_total)
+                       *end_line = 2;
+}
+
 void optc1_program_vline_interrupt(
                struct timing_generator *optc,
+               const struct dc_crtc_timing *dc_crtc_timing,
                enum vline_select vline,
-               const struct vline_config *vline_config)
+               const union vline_config *vline_config)
 {
        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, vline_config->start_line,
-                               OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config->end_line);
+                               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->start_line);
+                                       OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config->line_number);
                break;
        default:
                break;