#define DC_LOGGER \
        dccg->ctx->logger
 
-/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV
- * without the probability of causing a DIG FIFO error.
- */
-static void dccg32_wait_for_dentist_change_done(
+static void dccg32_trigger_dio_fifo_resync(
        struct dccg *dccg)
 {
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+       uint32_t dispclk_rdivider_value = 0;
 
-       uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL);
-
-       REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value);
-       REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
+       REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
+       REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
 }
 
 static void dccg32_get_pixel_rate_div(
                REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
                                OTG0_PIXEL_RATE_DIVK1, k1,
                                OTG0_PIXEL_RATE_DIVK2, k2);
-
-               dccg32_wait_for_dentist_change_done(dccg);
                break;
        case 1:
                REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
                                OTG1_PIXEL_RATE_DIVK1, k1,
                                OTG1_PIXEL_RATE_DIVK2, k2);
-
-               dccg32_wait_for_dentist_change_done(dccg);
                break;
        case 2:
                REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
                                OTG2_PIXEL_RATE_DIVK1, k1,
                                OTG2_PIXEL_RATE_DIVK2, k2);
-
-               dccg32_wait_for_dentist_change_done(dccg);
                break;
        case 3:
                REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
                                OTG3_PIXEL_RATE_DIVK1, k1,
                                OTG3_PIXEL_RATE_DIVK2, k2);
-
-               dccg32_wait_for_dentist_change_done(dccg);
                break;
        default:
                BREAK_TO_DEBUGGER();
        .otg_add_pixel = dccg32_otg_add_pixel,
        .otg_drop_pixel = dccg32_otg_drop_pixel,
        .set_pixel_rate_div = dccg32_set_pixel_rate_div,
+       .trigger_dio_fifo_resync = dccg32_trigger_dio_fifo_resync,
 };
 
 struct dccg *dccg32_create(
 
        DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
-       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
-
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh),\
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, mask_sh),\
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh)
 
 struct dccg *dccg32_create(
        struct dc_context *ctx,
 
                                pix_per_cycle);
 }
 
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+{
+       uint8_t i;
+       struct pipe_ctx *pipe = NULL;
+       bool otg_disabled[MAX_PIPES] = {false};
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (pipe->top_pipe || pipe->prev_odm_pipe)
+                       continue;
+
+               if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
+                       reset_sync_context_for_pipe(dc, context, i);
+                       otg_disabled[i] = true;
+               }
+       }
+
+       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (otg_disabled[i])
+                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+       }
+}
+
 void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
                struct dc_link_settings *link_settings)
 {