#include "dc.h"
 #include "mod_freesync.h"
 #include "core_types.h"
+#include "dm_services.h"
 
 #define MOD_FREESYNC_MAX_CONCURRENT_STREAMS  32
 
 /* Number of consecutive frames to check before entering/exiting fixed refresh */
 #define FIXED_REFRESH_ENTER_FRAME_COUNT 5
 #define FIXED_REFRESH_EXIT_FRAME_COUNT 10
+/* Flip interval workaround constants */
+#define VSYNCS_BETWEEN_FLIP_THRESHOLD 2
+#define FREESYNC_CONSEC_FLIP_AFTER_VSYNC 5
+#define FREESYNC_VSYNC_TO_FLIP_DELTA_IN_US 500
 
 struct core_freesync {
        struct mod_freesync public;
        }
 }
 
+static void determine_flip_interval_workaround_req(struct mod_vrr_params *in_vrr,
+               unsigned int curr_time_stamp_in_us)
+{
+       in_vrr->flip_interval.vsync_to_flip_in_us = curr_time_stamp_in_us -
+                       in_vrr->flip_interval.v_update_timestamp_in_us;
+
+       /* Determine conditions for stopping workaround */
+       if (in_vrr->flip_interval.flip_interval_workaround_active &&
+                       in_vrr->flip_interval.vsyncs_between_flip < VSYNCS_BETWEEN_FLIP_THRESHOLD &&
+                       in_vrr->flip_interval.vsync_to_flip_in_us > FREESYNC_VSYNC_TO_FLIP_DELTA_IN_US) {
+               in_vrr->flip_interval.flip_interval_detect_counter = 0;
+               in_vrr->flip_interval.program_flip_interval_workaround = true;
+               in_vrr->flip_interval.flip_interval_workaround_active = false;
+       } else {
+               /* Determine conditions for starting workaround */
+               if (in_vrr->flip_interval.vsyncs_between_flip >= VSYNCS_BETWEEN_FLIP_THRESHOLD &&
+                               in_vrr->flip_interval.vsync_to_flip_in_us < FREESYNC_VSYNC_TO_FLIP_DELTA_IN_US) {
+                       /* Increase flip interval counter we have 2 vsyncs between flips and
+                        * vsync to flip interval is less than 500us
+                        */
+                       in_vrr->flip_interval.flip_interval_detect_counter++;
+                       if (in_vrr->flip_interval.flip_interval_detect_counter > FREESYNC_CONSEC_FLIP_AFTER_VSYNC) {
+                               /* Start workaround if we detect 5 consecutive instances of the above case */
+                               in_vrr->flip_interval.program_flip_interval_workaround = true;
+                               in_vrr->flip_interval.flip_interval_workaround_active = true;
+                       }
+               } else {
+                       /* Reset the flip interval counter if we condition is no longer met */
+                       in_vrr->flip_interval.flip_interval_detect_counter = 0;
+               }
+       }
+
+       in_vrr->flip_interval.vsyncs_between_flip = 0;
+}
+
 static bool vrr_settings_require_update(struct core_freesync *core_freesync,
                struct mod_freesync_config *in_config,
                unsigned int min_refresh_in_uhz,
                                in_out_vrr);
                }
 
+               determine_flip_interval_workaround_req(in_out_vrr,
+                               curr_time_stamp_in_us);
+
        }
 }
 
                struct mod_vrr_params *in_out_vrr)
 {
        struct core_freesync *core_freesync = NULL;
+       unsigned int cur_timestamp_in_us;
 
        if ((mod_freesync == NULL) || (stream == NULL) || (in_out_vrr == NULL))
                return;
        if (in_out_vrr->supported == false)
                return;
 
+       cur_timestamp_in_us = dm_get_timestamp(core_freesync->dc->ctx)/10;
+
+       in_out_vrr->flip_interval.vsyncs_between_flip++;
+       in_out_vrr->flip_interval.v_update_timestamp_in_us = cur_timestamp_in_us;
+
+       if (in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE &&
+                       (in_out_vrr->flip_interval.flip_interval_workaround_active ||
+                       (!in_out_vrr->flip_interval.flip_interval_workaround_active &&
+                       in_out_vrr->flip_interval.program_flip_interval_workaround))) {
+               // set freesync vmin vmax to nominal for workaround
+               in_out_vrr->adjust.v_total_min =
+                       mod_freesync_calc_v_total_from_refresh(
+                       stream, in_out_vrr->max_refresh_in_uhz);
+               in_out_vrr->adjust.v_total_max =
+                               in_out_vrr->adjust.v_total_min;
+               in_out_vrr->flip_interval.program_flip_interval_workaround = false;
+               in_out_vrr->flip_interval.do_flip_interval_workaround_cleanup = true;
+               return;
+       }
+
+       if (in_out_vrr->state != VRR_STATE_ACTIVE_VARIABLE &&
+                       in_out_vrr->flip_interval.do_flip_interval_workaround_cleanup) {
+               in_out_vrr->flip_interval.do_flip_interval_workaround_cleanup = false;
+               in_out_vrr->flip_interval.flip_interval_detect_counter = 0;
+               in_out_vrr->flip_interval.vsyncs_between_flip = 0;
+               in_out_vrr->flip_interval.vsync_to_flip_in_us = 0;
+       }
+
        /* Below the Range Logic */
 
        /* Only execute if in fullscreen mode */
 
 bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz,
                uint32_t max_refresh_cap_in_uhz,
-               uint32_t nominal_field_rate_in_uhz) 
+               uint32_t nominal_field_rate_in_uhz)
 {
 
        /* Typically nominal refresh calculated can have some fractional part.