return ret;
 }
 
+static bool stream_get_crtc_position(struct dc *dc,
+               const struct dc_stream **stream, int num_streams,
+               unsigned int *v_pos, unsigned int *nom_v_pos)
+{
+       /* TODO: Support multiple streams */
+       struct core_dc *core_dc = DC_TO_CORE(dc);
+       struct core_stream *core_stream = DC_STREAM_TO_CORE(stream[0]);
+       int i = 0;
+       bool ret = false;
+       struct crtc_position position;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               struct pipe_ctx *pipe =
+                               &core_dc->current_context->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream == core_stream && pipe->stream_enc) {
+                       core_dc->hwss.get_position(&pipe, 1, &position);
+
+                       *v_pos = position.vertical_count;
+                       *nom_v_pos = position.nominal_vcount;
+                       ret = true;
+               }
+       }
+       return ret;
+}
 
 static bool set_gamut_remap(struct dc *dc,
                        const struct dc_stream **stream, int num_streams)
        core_dc->public.stream_funcs.set_static_screen_events =
                        set_static_screen_events;
 
+       core_dc->public.stream_funcs.get_crtc_position =
+                       stream_get_crtc_position;
+
        core_dc->public.stream_funcs.set_gamut_remap =
                        set_gamut_remap;
 
 
        struct core_dc *core_dc = DC_TO_CORE(dc);
        struct dal_logger *logger =  core_dc->ctx->logger;
        int h_pos[MAX_PIPES], v_pos[MAX_PIPES];
+       struct crtc_position position;
 
        for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
                if (pipe_ctx->stream == NULL)
                        continue;
 
-               pipe_ctx->tg->funcs->get_position(pipe_ctx->tg, &h_pos[i], &v_pos[i]);
+               pipe_ctx->tg->funcs->get_position(pipe_ctx->tg, &position);
+               h_pos[i] = position.horizontal_count;
+               v_pos[i] = position.vertical_count;
        }
        for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 
                        int num_streams,
                        int vmin,
                        int vmax);
+       bool (*get_crtc_position)(struct dc *dc,
+                       const struct dc_stream **stream,
+                       int num_streams,
+                       unsigned int *v_pos,
+                       unsigned int *nom_v_pos);
+
 
        void (*stream_update_scaling)(const struct dc *dc,
                        const struct dc_stream *dc_stream,
 
        }
 }
 
+static void get_position(struct pipe_ctx **pipe_ctx,
+               int num_pipes,
+               struct crtc_position *position)
+{
+       int i = 0;
+
+       /* TODO: handle pipes > 1
+        */
+       for (i = 0; i < num_pipes; i++)
+               pipe_ctx[i]->tg->funcs->get_position(pipe_ctx[i]->tg, position);
+}
+
 static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
                int num_pipes, const struct dc_static_screen_events *events)
 {
        .pipe_control_lock = dce_pipe_control_lock,
        .set_bandwidth = dce110_set_bandwidth,
        .set_drr = set_drr,
+       .get_position = get_position,
        .set_static_screen_control = set_static_screen_control,
        .reset_hw_ctx_wrap = reset_hw_ctx_wrap,
        .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg,
 
 
 /**
  *****************************************************************************
- *  Function: dce110_get_crtc_positions
+ *  Function: dce110_timing_generator_get_position
  *
  *  @brief
  *     Returns CRTC vertical/horizontal counters
  *
- *  @param [out] v_position, h_position
+ *  @param [out] position
  *****************************************************************************
  */
-
-void dce110_timing_generator_get_crtc_positions(
-       struct timing_generator *tg,
-       int32_t *h_position,
-       int32_t *v_position)
+void dce110_timing_generator_get_position(struct timing_generator *tg,
+       struct crtc_position *position)
 {
        uint32_t value;
        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
 
        value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION));
 
-       *h_position = get_reg_field_value(
+       position->horizontal_count = get_reg_field_value(
                        value,
                        CRTC_STATUS_POSITION,
                        CRTC_HORZ_COUNT);
 
-       *v_position = get_reg_field_value(
+       position->vertical_count = get_reg_field_value(
                        value,
                        CRTC_STATUS_POSITION,
                        CRTC_VERT_COUNT);
+
+       value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION));
+
+       position->nominal_vcount = get_reg_field_value(
+                       value,
+                       CRTC_NOM_VERT_POSITION,
+                       CRTC_VERT_COUNT_NOM);
 }
 
 /**
        uint32_t *v_position)
 {
        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+       struct crtc_position position;
 
-       uint32_t v_blank_start_end  = dm_read_reg(tg->ctx,
+       uint32_t value  = dm_read_reg(tg->ctx,
                        CRTC_REG(mmCRTC_V_BLANK_START_END));
 
-       *v_blank_start = get_reg_field_value(v_blank_start_end,
+       *v_blank_start = get_reg_field_value(value,
                                             CRTC_V_BLANK_START_END,
                                             CRTC_V_BLANK_START);
-       *v_blank_end = get_reg_field_value(v_blank_start_end,
+       *v_blank_end = get_reg_field_value(value,
                                           CRTC_V_BLANK_START_END,
                                           CRTC_V_BLANK_END);
 
-       dce110_timing_generator_get_crtc_positions(tg, h_position, v_position);
+       dce110_timing_generator_get_position(
+                       tg, &position);
+
+       *h_position = position.horizontal_count;
+       *v_position = position.vertical_count;
 }
 
 /* TODO: is it safe to assume that mask/shift of Primary and Underlay
  */
 bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg)
 {
-       uint32_t h1 = 0;
-       uint32_t h2 = 0;
-       uint32_t v1 = 0;
-       uint32_t v2 = 0;
+       struct crtc_position position1, position2;
 
-       tg->funcs->get_position(tg, &h1, &v1);
-       tg->funcs->get_position(tg, &h2, &v2);
+       tg->funcs->get_position(tg, &position1);
+       tg->funcs->get_position(tg, &position2);
 
-       if (h1 == h2 && v1 == v2)
+       if (position1.horizontal_count == position2.horizontal_count &&
+               position1.vertical_count == position2.vertical_count)
                return false;
        else
                return true;
        dm_write_reg(ctx, addr, value);
 }
 
-void dce110_tg_get_position(struct timing_generator *tg,
-       struct crtc_position *position)
-{
-       int32_t h_position;
-       int32_t v_position;
-
-       dce110_timing_generator_get_crtc_positions(tg, &h_position, &v_position);
-
-       position->horizontal_count = (uint32_t)h_position;
-       position->vertical_count = (uint32_t)v_position;
-}
-
 void dce110_tg_program_timing(struct timing_generator *tg,
        const struct dc_crtc_timing *timing,
        bool use_vbios)
                .enable_crtc = dce110_timing_generator_enable_crtc,
                .disable_crtc = dce110_timing_generator_disable_crtc,
                .is_counter_moving = dce110_timing_generator_is_counter_moving,
-               .get_position = dce110_timing_generator_get_crtc_positions,
+               .get_position = dce110_timing_generator_get_position,
                .get_frame_count = dce110_timing_generator_get_vblank_counter,
                .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
                .set_early_control = dce110_timing_generator_set_early_control,
 
 uint32_t dce110_timing_generator_get_vblank_counter(
                struct timing_generator *tg);
 
-/* Get current H and V position */
-void dce110_timing_generator_get_crtc_positions(
+void dce110_timing_generator_get_position(
        struct timing_generator *tg,
-       int32_t *h_position,
-       int32_t *v_position);
+       struct crtc_position *position);
 
 /* return true if TG counter is moving. false if TG is stopped */
 bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg);
 void dce110_tg_set_overscan_color(struct timing_generator *tg,
        const struct tg_color *overscan_color);
 
-void dce110_tg_get_position(struct timing_generator *tg,
-       struct crtc_position *position);
-
 void dce110_tg_program_timing(struct timing_generator *tg,
        const struct dc_crtc_timing *timing,
        bool use_vbios);
 
        dm_write_reg(tg->ctx, address, regval);
 }
 
-static void dce110_timing_generator_v_get_crtc_positions(
-       struct timing_generator *tg,
-       int32_t *h_position,
-       int32_t *v_position)
+static void dce110_timing_generator_get_underlay_position(struct timing_generator *tg,
+       struct crtc_position *position)
 {
-       uint32_t value;
-
-       value = dm_read_reg(tg->ctx, mmCRTCV_STATUS_POSITION);
-
-       *h_position = get_reg_field_value(
-                       value,
-                       CRTCV_STATUS_POSITION,
-                       CRTC_HORZ_COUNT);
-
-       *v_position = get_reg_field_value(
-                       value,
-                       CRTCV_STATUS_POSITION,
-                       CRTC_VERT_COUNT);
+       //Should never hit this case
+       ASSERT(false);
 }
 
 static uint32_t dce110_timing_generator_v_get_vblank_counter(struct timing_generator *tg)
                .enable_crtc = dce110_timing_generator_v_enable_crtc,
                .disable_crtc = dce110_timing_generator_v_disable_crtc,
                .is_counter_moving = dce110_timing_generator_v_is_counter_moving,
-               .get_position = dce110_timing_generator_v_get_crtc_positions,
+               .get_position = dce110_timing_generator_get_underlay_position,
                .get_frame_count = dce110_timing_generator_v_get_vblank_counter,
                .set_early_control = dce110_timing_generator_v_set_early_control,
                .wait_for_state = dce110_timing_generator_v_wait_for_state,
 
 }
 
 /* Get current H and V position */
-void dce120_timing_generator_get_crtc_positions(
+void dce120_timing_generator_get_crtc_position(
        struct timing_generator *tg,
-       int32_t *h_position,
-       int32_t *v_position)
+       struct crtc_position *position)
 {
        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
        uint32_t value = dm_read_reg_soc15(
                                mmCRTC0_CRTC_STATUS_POSITION,
                                tg110->offsets.crtc);
 
-       *h_position = get_reg_field_value(
-                                       value, CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
+       position->horizontal_count = get_reg_field_value(value,
+                       CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
 
-       *v_position = get_reg_field_value(
-                                               value, CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
+       position->vertical_count = get_reg_field_value(value,
+                       CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
+
+       value = dm_read_reg_soc15(
+                               tg->ctx,
+                               mmCRTC0_CRTC_NOM_VERT_POSITION,
+                               tg110->offsets.crtc);
+
+       position->nominal_vcount = get_reg_field_value(value,
+                       CRTC0_CRTC_NOM_VERT_POSITION, CRTC_VERT_COUNT_NOM);
 }
 
 /* wait until TG is in beginning of vertical blank region */
        }
 }
 
+/**
+ *****************************************************************************
+ *  Function: dce120_timing_generator_get_position
+ *
+ *  @brief
+ *     Returns CRTC vertical/horizontal counters
+ *
+ *  @param [out] position
+ *****************************************************************************
+ */
+void dce120_timing_generator_get_position(struct timing_generator *tg,
+       struct crtc_position *position)
+{
+       uint32_t value;
+       struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+       value = dm_read_reg_soc15(
+                       tg->ctx,
+                       mmCRTC0_CRTC_STATUS_POSITION,
+                       tg110->offsets.crtc);
+
+       position->horizontal_count = get_reg_field_value(
+                       value,
+                       CRTC0_CRTC_STATUS_POSITION,
+                       CRTC_HORZ_COUNT);
+
+       position->vertical_count = get_reg_field_value(
+                       value,
+                       CRTC0_CRTC_STATUS_POSITION,
+                       CRTC_VERT_COUNT);
+
+       value = dm_read_reg_soc15(
+                       tg->ctx,
+                       mmCRTC0_CRTC_NOM_VERT_POSITION,
+                       tg110->offsets.crtc);
+
+       position->nominal_vcount = get_reg_field_value(
+                       value,
+                       CRTC0_CRTC_NOM_VERT_POSITION,
+                       CRTC_VERT_COUNT_NOM);
+}
+
+
 void dce120_timing_generator_get_crtc_scanoutpos(
        struct timing_generator *tg,
        uint32_t *v_blank_start,
        uint32_t *v_position)
 {
        struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+       struct crtc_position position;
 
        uint32_t v_blank_start_end = dm_read_reg_soc15(
                        tg->ctx,
                                           CRTC0_CRTC_V_BLANK_START_END,
                                           CRTC_V_BLANK_END);
 
-       dce120_timing_generator_get_crtc_positions(tg, h_position, v_position);
+       dce120_timing_generator_get_crtc_position(
+                       tg, &position);
+
+       *h_position = position.horizontal_count;
+       *v_position = position.vertical_count;
 }
 
 void dce120_timing_generator_enable_advanced_request(
                /* used by enable_timing_synchronization. Not need for FPGA */
                .is_counter_moving = dce110_timing_generator_is_counter_moving,
                /* never be called */
-               .get_position = dce120_timing_generator_get_crtc_positions,
+               .get_position = dce120_timing_generator_get_crtc_position,
                .get_frame_count = dce120_timing_generator_get_vblank_counter,
                .get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos,
                .set_early_control = dce120_timing_generator_set_early_control,
 
                .enable_crtc = dce110_timing_generator_enable_crtc,
                .disable_crtc = dce110_timing_generator_disable_crtc,
                .is_counter_moving = dce110_timing_generator_is_counter_moving,
-               .get_position = dce110_timing_generator_get_crtc_positions,
+               .get_position = dce110_timing_generator_get_position,
                .get_frame_count = dce110_timing_generator_get_vblank_counter,
                .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
                .set_early_control = dce110_timing_generator_set_early_control,
 
 
 /* Contains CRTC vertical/horizontal pixel counters */
 struct crtc_position {
-       uint32_t vertical_count;
-       uint32_t horizontal_count;
-       uint32_t nominal_vcount;
+       int32_t vertical_count;
+       int32_t horizontal_count;
+       int32_t nominal_vcount;
 };
 
 struct dcp_gsl_params {
        bool (*disable_crtc)(struct timing_generator *tg);
        bool (*is_counter_moving)(struct timing_generator *tg);
        void (*get_position)(struct timing_generator *tg,
-                                                               int32_t *h_position,
-                                                               int32_t *v_position);
+                               struct crtc_position *position);
+
        uint32_t (*get_frame_count)(struct timing_generator *tg);
        void (*get_scanoutpos)(
                struct timing_generator *tg,
 
        void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
                        int vmin, int vmax);
 
+       void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
+                       struct crtc_position *position);
+
        void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
                        int num_pipes, const struct dc_static_screen_events *events);
 
 
        bool program_fixed_refresh;
 };
 
+struct freesync_range {
+       unsigned int min_refresh;
+       unsigned int max_frame_duration;
+       unsigned int vmax;
+
+       unsigned int max_refresh;
+       unsigned int min_frame_duration;
+       unsigned int vmin;
+};
+
 struct freesync_state {
        bool fullscreen;
        bool static_screen;
        struct gradual_static_ramp static_ramp;
        struct below_the_range btr;
        struct fixed_refresh fixed_refresh;
+       struct freesync_range freesync_range;
 };
 
 struct freesync_entity {
        }
 }
 
-static void calc_vmin_vmax(struct core_freesync *core_freesync,
-               const struct dc_stream *stream, int *vmin, int *vmax)
+static void calc_freesync_range(struct core_freesync *core_freesync,
+               const struct dc_stream *stream,
+               struct freesync_state *state,
+               unsigned int min_refresh_in_uhz,
+               unsigned int max_refresh_in_uhz)
 {
        unsigned int min_frame_duration_in_ns = 0, max_frame_duration_in_ns = 0;
        unsigned int index = map_index_from_stream(core_freesync, stream);
 
        min_frame_duration_in_ns = ((unsigned int) (div64_u64(
                                        (1000000000ULL * 1000000),
-                                       core_freesync->map[index].state.
-                                       nominal_refresh_rate_in_micro_hz)));
+                                       max_refresh_in_uhz)));
        max_frame_duration_in_ns = ((unsigned int) (div64_u64(
-                                       (1000000000ULL * 1000000),
-                                       core_freesync->map[index].caps->min_refresh_in_micro_hz)));
+               (1000000000ULL * 1000000),
+               min_refresh_in_uhz)));
+
+       state->freesync_range.min_refresh = min_refresh_in_uhz;
+       state->freesync_range.max_refresh = max_refresh_in_uhz;
 
-       *vmax = div64_u64(div64_u64(((unsigned long long)(
-                       max_frame_duration_in_ns) * stream->timing.pix_clk_khz),
-                       stream->timing.h_total), 1000000);
-       *vmin = div64_u64(div64_u64(((unsigned long long)(
-                       min_frame_duration_in_ns) * stream->timing.pix_clk_khz),
-                       stream->timing.h_total), 1000000);
+       state->freesync_range.max_frame_duration = max_frame_duration_in_ns;
+       state->freesync_range.min_frame_duration = min_frame_duration_in_ns;
+
+       state->freesync_range.vmax = div64_u64(div64_u64(((unsigned long long)(
+               max_frame_duration_in_ns) * stream->timing.pix_clk_khz),
+               stream->timing.h_total), 1000000);
+       state->freesync_range.vmin = div64_u64(div64_u64(((unsigned long long)(
+               min_frame_duration_in_ns) * stream->timing.pix_clk_khz),
+               stream->timing.h_total), 1000000);
 
        /* In case of 4k free sync monitor, vmin or vmax cannot be less than vtotal */
-       if (*vmin < vtotal) {
+       if (state->freesync_range.vmin < vtotal) {
                ASSERT(false);
-               *vmin = vtotal;
+               state->freesync_range.vmin = vtotal;
        }
 
-       if (*vmax < vtotal) {
+       if (state->freesync_range.vmax < vtotal) {
                ASSERT(false);
-               *vmax = vtotal;
+               state->freesync_range.vmax = vtotal;
        }
+
+       /* Determine whether BTR can be supported */
+       if (max_frame_duration_in_ns >=
+                       2 * min_frame_duration_in_ns)
+               core_freesync->map[index].caps->btr_supported = true;
+       else
+               core_freesync->map[index].caps->btr_supported = false;
+
+       /* Cache the time variables */
+       state->time.max_render_time_in_us =
+               max_frame_duration_in_ns / 1000;
+       state->time.min_render_time_in_us =
+               min_frame_duration_in_ns / 1000;
+       state->btr.mid_point_in_us =
+               (max_frame_duration_in_ns +
+               min_frame_duration_in_ns) / 2000;
 }
 
 static void calc_v_total_from_duration(const struct dc_stream *stream,
                                state->fixed_refresh.fixed_refresh_active == false) {
                                /* Enable freesync */
 
-                               calc_vmin_vmax(core_freesync,
-                                               streams[stream_idx],
-                                               &v_total_min, &v_total_max);
+                               v_total_min = state->freesync_range.vmin;
+                               v_total_max = state->freesync_range.vmax;
 
                                /* Update the freesync context for the stream */
                                update_stream_freesync_context(core_freesync,
                                        (1000000000ULL * 1000000),
                                        state->nominal_refresh_rate_in_micro_hz)));
 
-                       calc_vmin_vmax(core_freesync, *streams, &vmin, &vmax);
+                       vmin = state->freesync_range.vmin;
 
                        inserted_frame_v_total = vmin;
 
        return true;
 }
 
+bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
+               const struct dc_stream *streams,
+               unsigned int min_refresh,
+               unsigned int max_refresh)
+{
+       unsigned int index = 0;
+       struct core_freesync *core_freesync;
+       struct freesync_state *state;
+
+       if (mod_freesync == NULL)
+               return false;
+
+       core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
+       index = map_index_from_stream(core_freesync, streams);
+       state = &core_freesync->map[index].state;
+
+       if (min_refresh == 0 || max_refresh == 0) {
+               /* Restore defaults */
+               calc_freesync_range(core_freesync, streams, state,
+                       core_freesync->map[index].caps->
+                       min_refresh_in_micro_hz,
+                       state->nominal_refresh_rate_in_micro_hz);
+       } else {
+               calc_freesync_range(core_freesync, streams,
+                               state,
+                               min_refresh,
+                               max_refresh);
+
+               /* Program vtotal min/max */
+               core_freesync->dc->stream_funcs.adjust_vmin_vmax(
+                       core_freesync->dc, &streams, 1,
+                       state->freesync_range.vmin,
+                       state->freesync_range.vmax);
+       }
+
+       return true;
+}
+
+bool mod_freesync_get_min_max(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *min_refresh,
+               unsigned int *max_refresh)
+{
+       unsigned int index = 0;
+       struct core_freesync *core_freesync = NULL;
+
+       if (mod_freesync == NULL)
+               return false;
+
+       core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
+       index = map_index_from_stream(core_freesync, stream);
+
+       *min_refresh =
+               core_freesync->map[index].state.freesync_range.min_refresh;
+       *max_refresh =
+               core_freesync->map[index].state.freesync_range.max_refresh;
+
+       return true;
+}
+
+bool mod_freesync_get_vmin_vmax(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *vmin,
+               unsigned int *vmax)
+{
+       unsigned int index = 0;
+       struct core_freesync *core_freesync = NULL;
+
+       if (mod_freesync == NULL)
+               return false;
+
+       core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
+       index = map_index_from_stream(core_freesync, stream);
+
+       *vmin =
+               core_freesync->map[index].state.freesync_range.vmin;
+       *vmax =
+               core_freesync->map[index].state.freesync_range.vmax;
+
+       return true;
+}
+
+bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *nom_v_pos,
+               unsigned int *v_pos)
+{
+       unsigned int index = 0;
+       struct core_freesync *core_freesync = NULL;
+       struct crtc_position position;
+
+       if (mod_freesync == NULL)
+               return false;
+
+       core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
+       index = map_index_from_stream(core_freesync, stream);
+
+       if (core_freesync->dc->stream_funcs.get_crtc_position(
+                       core_freesync->dc, &stream, 1,
+                       &position.vertical_count, &position.nominal_vcount)) {
+
+               *nom_v_pos = position.vertical_count;
+               *v_pos = position.nominal_vcount;
+
+               return true;
+       }
+
+       return false;
+}
+
 void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
                const struct dc_stream **streams, int num_streams)
 {
        unsigned int stream_index, map_index;
-       unsigned min_frame_duration_in_ns, max_frame_duration_in_ns;
        struct freesync_state *state;
        struct core_freesync *core_freesync = NULL;
 
                        unsigned long long temp;
                        temp = streams[stream_index]->timing.pix_clk_khz;
                        temp *= 1000ULL * 1000ULL * 1000ULL;
-                       temp = div_u64(temp, streams[stream_index]->timing.h_total);
-                       temp = div_u64(temp, streams[stream_index]->timing.v_total);
-                       state->nominal_refresh_rate_in_micro_hz = (unsigned int) temp;
+                       temp = div_u64(temp,
+                                       streams[stream_index]->timing.h_total);
+                       temp = div_u64(temp,
+                                       streams[stream_index]->timing.v_total);
+                       state->nominal_refresh_rate_in_micro_hz =
+                                       (unsigned int) temp;
 
                        /* Update the stream */
                        update_stream(core_freesync, streams[stream_index]);
 
-                       /* Determine whether BTR can be supported */
-                       min_frame_duration_in_ns = ((unsigned int) (div64_u64(
-                                       (1000000000ULL * 1000000),
-                                       state->nominal_refresh_rate_in_micro_hz)));
-
-                       max_frame_duration_in_ns = ((unsigned int) (div64_u64(
-                                       (1000000000ULL * 1000000),
-                                       core_freesync->map[map_index].caps->min_refresh_in_micro_hz)));
-
-                       if (max_frame_duration_in_ns >=
-                                       2 * min_frame_duration_in_ns)
-                               core_freesync->map[map_index].caps->btr_supported = true;
-                       else
-                               core_freesync->map[map_index].caps->btr_supported = false;
-
-                       /* Cache the time variables */
-                       state->time.max_render_time_in_us =
-                               max_frame_duration_in_ns / 1000;
-                       state->time.min_render_time_in_us =
-                               min_frame_duration_in_ns / 1000;
-                       state->btr.mid_point_in_us =
-                               (max_frame_duration_in_ns +
-                               min_frame_duration_in_ns) / 2000;
-
+                       /* Calculate vmin/vmax and refresh rate for
+                        * current mode
+                        */
+                       calc_freesync_range(core_freesync, *streams, state,
+                               core_freesync->map[stream_index].caps->
+                               min_refresh_in_micro_hz,
+                               state->nominal_refresh_rate_in_micro_hz);
                }
        }
 
        /* Fixed Refresh set to "active" so engage (fix to max) */
        } else {
 
-               calc_vmin_vmax(core_freesync, stream, &vmin, &vmax);
+               vmin = state->freesync_range.vmin;
 
                vmax = vmin;
 
 
                const struct dc_stream *stream,
                struct mod_freesync_user_enable *user_enable);
 
+bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
+               const struct dc_stream *streams,
+               unsigned int min_refresh,
+               unsigned int max_refresh);
+
+bool mod_freesync_get_min_max(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *min_refresh,
+               unsigned int *max_refresh);
+
+bool mod_freesync_get_vmin_vmax(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *vmin,
+               unsigned int *vmax);
+
+bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
+               const struct dc_stream *stream,
+               unsigned int *nom_v_pos,
+               unsigned int *v_pos);
+
 void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
                const struct dc_stream **streams, int num_streams);