#include <drm/drm_crtc.h>
 #include <drm/drm_file.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_framebuffer.h>
 
 #include "msm_drv.h"
 #include "dpu_kms.h"
 #include "dpu_hw_dspp.h"
 #include "dpu_hw_dsc.h"
 #include "dpu_hw_merge3d.h"
+#include "dpu_hw_cdm.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_crtc.h"
        struct drm_display_mode *adj_mode;
        struct msm_display_topology topology;
        struct dpu_global_state *global_state;
+       struct drm_framebuffer *fb;
        struct drm_dsc_config *dsc;
        int i = 0;
        int ret = 0;
 
        topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
 
+       /*
+        * Use CDM only for writeback at the moment as other interfaces cannot handle it.
+        * if writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
+        * earlier.
+        */
+       if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
+               fb = conn_state->writeback_job->fb;
+
+               if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))))
+                       topology.needs_cdm = true;
+               if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+                       crtc_state->mode_changed = true;
+               else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
+                       crtc_state->mode_changed = true;
+       }
+
        /*
         * Release and Allocate resources on every modeset
         * Dont allocate when active is false.
 
        dpu_enc->dsc_mask = dsc_mask;
 
+       if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
+               struct dpu_hw_blk *hw_cdm = NULL;
+
+               dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+                                             drm_enc->base.id, DPU_HW_BLK_CDM,
+                                             &hw_cdm, 1);
+               dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
+       }
+
        cstate = to_dpu_crtc_state(crtc_state);
 
        for (i = 0; i < num_lm; i++) {
                                        phys_enc->hw_pp->merge_3d->idx);
        }
 
+       if (phys_enc->hw_cdm) {
+               if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp)
+                       phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm,
+                                                               PINGPONG_NONE);
+               if (phys_enc->hw_ctl->ops.update_pending_flush_cdm)
+                       phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl,
+                                                                      phys_enc->hw_cdm->idx);
+       }
+
        if (dpu_enc->dsc) {
                dpu_encoder_unprep_dsc(dpu_enc);
                dpu_enc->dsc = NULL;