return false;
 }
 
+/* Perform updates here which need to be deferred until next vupdate
+ *
+ * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered
+ * but forcing lut memory to shutdown state is immediate. This causes
+ * single frame corruption as lut gets disabled mid-frame unless shutdown
+ * is deferred until after entering bypass.
+ */
+static void process_deferred_updates(struct dc *dc)
+{
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       int i;
+
+       if (dc->debug.enable_mem_low_power.bits.cm)
+               for (i = 0; i < dc->dcn_ip->max_num_dpp; i++)
+                       if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update)
+                               dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]);
+#endif
+}
+
 void dc_post_update_surfaces_to_stream(struct dc *dc)
 {
        int i;
                        dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
                }
 
+       process_deferred_updates(dc);
+
        dc->hwss.optimize_bandwidth(dc, context);
 
        dc->optimized_required = false;
 
        REG_UPDATE(FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, bias_and_scale->scale_blue);
 }
 
+void dpp3_deferred_update(
+       struct dpp *dpp_base)
+{
+       int bypass_state;
+       struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
+
+       if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
+               REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
+               if (bypass_state == 0) {        // only program if bypass was latched
+                       REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3);
+               } else
+                       ASSERT(0); // LUT select was updated again before vupdate
+               dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false;
+       }
+
+       if (dpp_base->deferred_reg_writes.bits.disable_3dlut) {
+               REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state);
+               if (bypass_state == 0) {        // only program if bypass was latched
+                       REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3);
+               } else
+                       ASSERT(0); // LUT select was updated again before vupdate
+               dpp_base->deferred_reg_writes.bits.disable_3dlut = false;
+       }
+
+       if (dpp_base->deferred_reg_writes.bits.disable_shaper) {
+               REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state);
+               if (bypass_state == 0) {        // only program if bypass was latched
+                       REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3);
+               } else
+                       ASSERT(0); // LUT select was updated again before vupdate
+               dpp_base->deferred_reg_writes.bits.disable_shaper = false;
+       }
+}
+
 static void dpp3_power_on_blnd_lut(
        struct dpp *dpp_base,
        bool power_on)
        struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
        if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
-               REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, power_on ? 0 : 3);
-               if (power_on)
+               if (power_on) {
+                       REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);
                        REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
+               } else {
+                       dpp_base->ctx->dc->optimized_required = true;
+                       dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
+               }
        } else {
                REG_SET(CM_MEM_PWR_CTRL, 0,
                                BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
        struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
        if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
-               REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, power_on ? 0 : 3);
-               if (power_on)
+               if (power_on) {
+                       REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);
                        REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
+               } else {
+                       dpp_base->ctx->dc->optimized_required = true;
+                       dpp_base->deferred_reg_writes.bits.disable_3dlut = true;
+               }
        }
 }
 
        struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
        if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
-               REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, power_on ? 0 : 3);
-               if (power_on)
+               if (power_on) {
+                       REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);
                        REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
+               } else {
+                       dpp_base->ctx->dc->optimized_required = true;
+                       dpp_base->deferred_reg_writes.bits.disable_shaper = true;
+               }
        }
 }
 
        .dpp_program_blnd_lut = dpp3_program_blnd_lut,
        .dpp_program_shaper_lut = dpp3_program_shaper,
        .dpp_program_3dlut = dpp3_program_3dlut,
+       .dpp_deferred_update = dpp3_deferred_update,
        .dpp_program_bias_and_scale     = NULL,
        .dpp_cnv_set_alpha_keyer        = dpp2_cnv_set_alpha_keyer,
        .set_cursor_attributes          = dpp3_set_cursor_attributes,