From: Rafal Ostrowski <[email protected]>

Combine two related color manager improvements:

1. Migrate MCM/RMCM, shaper and 3DLUT HW programming to dc_plane_cm
   - Continue convergence with upstream Color Manager refactor
   - Migrate MCM/RMCM, shaper and 3DLUT programming for dcn401+ to dc_plane_cm
   - Unify MCM programming across both legacy and 3DLUT DMA paths
   - Add 3DLUT DMA broadcast support for multi-pipe planes

2. Reprogram MCM blend LUT on blend_enable falling edge
   - Fix issue where SDR desktop remained desaturated after video playback
   - Detect blend_enable falling edge (1->0) in surface update detection
   - Force MCM LUT reprogramming on blend state change

Reviewed-by: Dillon Varone <[email protected]>
Signed-off-by: Rafal Ostrowski <[email protected]>
Signed-off-by: Roman Li <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  66 +--
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  18 +
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |   3 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |  12 +-
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.c  | 201 +++++---
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.h  |  23 +-
 .../amd/display/dc/hubp/dcn42/dcn42_hubp.c    |  78 ++-
 .../amd/display/dc/hubp/dcn42/dcn42_hubp.h    |  10 +-
 .../amd/display/dc/hubp/dcn50/dcn50_hubp.c    |  10 +-
 .../amd/display/dc/hubp/dcn60/dcn60_hubp.c    |   7 +-
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 428 ++++++---------
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.h |   7 +-
 .../amd/display/dc/hwss/dcn401/dcn401_init.c  |   1 -
 .../amd/display/dc/hwss/dcn42/dcn42_hwseq.c   | 488 ++----------------
 .../amd/display/dc/hwss/dcn42/dcn42_hwseq.h   |   6 -
 .../amd/display/dc/hwss/dcn42/dcn42_init.c    |   2 -
 .../amd/display/dc/hwss/dcn60/dcn60_init.c    |   2 -
 .../drm/amd/display/dc/hwss/hw_sequencer.h    |   2 +-
 .../display/dc/hwss/hw_sequencer_private.h    |   5 -
 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h  |  35 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |  81 +--
 .../amd/display/dc/mpc/dcn401/dcn401_mpc.c    | 177 ++++---
 .../amd/display/dc/mpc/dcn401/dcn401_mpc.h    |  25 +-
 .../drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c  | 405 ++-------------
 .../drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h  |  55 +-
 .../drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c  | 235 ++++-----
 .../drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h  |  15 -
 .../dc/resource/dcn42/dcn42_resource.c        |   1 +
 .../dc/resource/dcn60/dcn60_resource.c        |   1 +
 29 files changed, 778 insertions(+), 1621 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 7f378b5e896c..68f228014305 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3027,13 +3027,14 @@ static struct dc_update_descriptor det_surface_update(
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, 
LOCK_DESCRIPTOR_STREAM);
        }
 
-       if ((u->cm && u->cm->flags.bits.blend_enable) ||
+       if ((u->cm && (u->cm->flags.bits.blend_enable ||
+                       u->cm->flags.bits.blend_enable != 
u->surface->cm.flags.bits.blend_enable)) ||
                        (u->gamma && dce_use_lut(u->plane_info ? 
u->plane_info->format : u->surface->format))) {
                update_bits->gamma_change = 1;
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, 
LOCK_DESCRIPTOR_STREAM);
        }
 
-       if (u->cm && (u->cm->flags.bits.lut3d_enable || 
u->cm->flags.bits.shaper_enable)) {
+       if (u->cm && (u->cm->flags.bits.lut3d_enable || 
u->surface->cm.flags.bits.lut3d_enable)) {
                update_bits->lut_3d = 1;
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, 
LOCK_DESCRIPTOR_STREAM);
        }
@@ -3075,25 +3076,12 @@ static struct dc_update_descriptor det_surface_update(
                        }
                };
 
-               if (u->cm->flags.bits.shaper_enable != 
u->surface->cm.flags.bits.shaper_enable
-                               || u->cm->flags.bits.blend_enable != 
u->surface->cm.flags.bits.blend_enable
-                               || u->cm->flags.bits.lut3d_enable != 
u->surface->cm.flags.bits.lut3d_enable
-                               || u->cm->flags.bits.lut3d_dma_enable != 
u->surface->cm.flags.bits.lut3d_dma_enable) {
-                       update_bits->mcm_transfer_function_enable_change = 1;
-                       elevate_update_type(&overall_type, UPDATE_TYPE_FULL, 
LOCK_DESCRIPTOR_GLOBAL);
-               }
-
                if ((u->cm->flags.all != blend_only_flags.all && 
u->cm->flags.all != 0) ||
                                (u->surface->cm.flags.all != 
blend_only_flags.all && u->surface->cm.flags.all != 0)) {
                        elevate_update_type(&overall_type, UPDATE_TYPE_FULL, 
LOCK_DESCRIPTOR_GLOBAL);
                }
        }
 
-       if (update_bits->lut_3d &&
-                       !u->surface->cm.flags.bits.lut3d_dma_enable) {
-               elevate_update_type(&overall_type, UPDATE_TYPE_FULL, 
LOCK_DESCRIPTOR_GLOBAL);
-       }
-
        if (check_config->enable_legacy_fast_update &&
                        (update_bits->gamma_change ||
                        update_bits->gamut_remap_change ||
@@ -3446,46 +3434,6 @@ static void copy_surface_update_to_plane(
                memcpy(&surface->cm, srf_update->cm, sizeof(surface->cm));
                surface->cm.refcount = refcount;
 
-#ifndef TRIM_CM2
-               /* Populate mcm_luts from cm for legacy consumers (dml2, hwseq) 
*/
-               surface->mcm_luts.lut1d_func = &surface->cm.blend_func;
-               surface->mcm_luts.shaper = &surface->cm.shaper_func;
-               if (srf_update->cm->flags.bits.lut3d_dma_enable) {
-                       surface->mcm_luts.lut3d_data.lut3d_src = 
DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM;
-                       surface->mcm_luts.lut3d_data.gpu_mem_params.addr = 
surface->cm.lut3d_dma.addr;
-                       surface->mcm_luts.lut3d_data.gpu_mem_params.layout =
-                               (surface->cm.lut3d_dma.swizzle == 
CM_LUT_3D_SWIZZLE_LINEAR_RGB) ?
-                                       
DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB :
-                               (surface->cm.lut3d_dma.swizzle == 
CM_LUT_3D_SWIZZLE_LINEAR_BGR) ?
-                                       
DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR :
-                                       DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR;
-                       
surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.format =
-                               (surface->cm.lut3d_dma.format == 
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB) ?
-                                       
DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB :
-                               (surface->cm.lut3d_dma.format == 
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB) ?
-                                       
DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB :
-                                       
DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
-                       
surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias =
-                               surface->cm.lut3d_dma.bias;
-                       
surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale =
-                               surface->cm.lut3d_dma.scale;
-                       
surface->mcm_luts.lut3d_data.gpu_mem_params.component_order =
-                               DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA;
-                       surface->mcm_luts.lut3d_data.gpu_mem_params.size = 
DC_CM2_GPU_MEM_SIZE_TRANSFORMED;
-                       surface->mcm_luts.lut3d_data.mpc_3dlut_enable = 
(srf_update->cm->flags.bits.lut3d_enable != 0);
-               } else {
-                       surface->mcm_luts.lut3d_data.lut3d_src = 
DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM;
-                       surface->mcm_luts.lut3d_data.lut3d_func = 
&surface->cm.lut3d_func;
-               }
-
-               if (srf_update->cm->flags.bits.shaper_enable &&
-                               srf_update->cm->flags.bits.lut3d_enable)
-                       surface->mcm_shaper_3dlut_setting = 
DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT;
-               else if (srf_update->cm->flags.bits.shaper_enable)
-                       surface->mcm_shaper_3dlut_setting = 
DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER;
-               else
-                       surface->mcm_shaper_3dlut_setting = 
DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
-#endif /* TRIM_CM2 */
        }
 
        if (srf_update->hdr_mult.value)
@@ -3496,12 +3444,6 @@ static void copy_surface_update_to_plane(
                surface->sdr_white_level_nits =
                                srf_update->sdr_white_level_nits;
 
-       if (srf_update->cm &&
-                       (srf_update->cm->flags.bits.blend_enable ||
-                       srf_update->cm->flags.bits.shaper_enable ||
-                       srf_update->cm->flags.bits.lut3d_enable))
-               surface->lut_bank_a = !surface->lut_bank_a;
-
        if (srf_update->input_csc_color_matrix)
                surface->input_csc_color_matrix =
                        *srf_update->input_csc_color_matrix;
@@ -5243,7 +5185,7 @@ static void commit_planes_for_stream(struct dc *dc,
                                                
srf_updates[i].cm->flags.bits.lut3d_enable &&
                                                
srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
                                                dc->hwss.trigger_3dlut_dma_load)
-                                       dc->hwss.trigger_3dlut_dma_load(dc, 
pipe_ctx);
+                                       
dc->hwss.trigger_3dlut_dma_load(pipe_ctx);
 
                                /*program triple buffer after lock based on 
flip type*/
                                if (dc->hwss.program_triplebuffer != NULL && 
dc->debug.enable_tri_buf) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 8878652434d2..76e3509f73c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -1457,6 +1457,24 @@ void hwss_build_fast_sequence(struct dc *dc,
                                        (*num_steps)++;
                                }
 
+                               if 
(current_mpc_pipe->plane_state->update_bits.hdr_mult) {
+                                       struct fixed31_32 multiplier = 
current_mpc_pipe->plane_state->hdr_mult;
+                                       uint32_t hw_mult = 0x1f000; // 1.0 
default multiplier
+                                       struct custom_float_format fmt;
+
+                                       fmt.exponenta_bits = 6;
+                                       fmt.mantissa_bits = 12;
+                                       fmt.sign = true;
+
+                                       if (!dc_fixpt_eq(multiplier, 
dc_fixpt_from_int(0)) && // check != 0
+                                               
convert_to_custom_float_format(multiplier, &fmt, &hw_mult)) {
+                                               
block_sequence[*num_steps].params.dpp_set_hdr_multiplier_params.dpp = 
current_mpc_pipe->plane_res.dpp;
+                                               
block_sequence[*num_steps].params.dpp_set_hdr_multiplier_params.hw_mult = 
hw_mult;
+                                               block_sequence[*num_steps].func 
= DPP_SET_HDR_MULTIPLIER;
+                                               (*num_steps)++;
+                                       }
+                               }
+
                                if (dc->hwss.program_gamut_remap &&
                                                
(current_mpc_pipe->plane_state->update_bits.gamut_remap_change ||
                                                 
current_mpc_pipe->stream->update_flags.bits.gamut_remap)) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index ce5b9e82db8d..9f3068e899e1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -991,6 +991,7 @@ void dc_stream_log(const struct dc *dc, const struct 
dc_stream_state *stream)
        }
 }
 
+/* TODO - move to per plane ownership? */
 /*
 *      dc_stream_get_3dlut()
 *      Requirements:
@@ -1042,7 +1043,6 @@ void dc_stream_release_3dlut_for_stream(
        if (rmcm_3dlut) {
                rmcm_3dlut->isInUse = false;
                rmcm_3dlut->stream  = NULL;
-               rmcm_3dlut->protection_bits = 0;
        }
 }
 
@@ -1054,7 +1054,6 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
        for (unsigned int i = 0; i < num_rmcm; i++) {
                dc->res_pool->rmcm_3dlut[i].isInUse = false;
                dc->res_pool->rmcm_3dlut[i].stream = NULL;
-               dc->res_pool->rmcm_3dlut[i].protection_bits = 0;
        }
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 683b5fb1945d..b2fd3a94f067 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1459,6 +1459,7 @@ struct dc_transfer_func {
        enum dc_transfer_func_predefined tf;
        /* FP16 1.0 reference level in nits, default is 80 nits, only for PQ*/
        uint32_t sdr_ref_white_level;
+       struct fixed31_32 hdr_multiplier;
        union {
                struct pwl_params pwl;
                struct dc_transfer_func_distributed_points tf_pts;
@@ -1509,13 +1510,11 @@ struct lut_mem_mapping {
 struct dc_rmcm_3dlut {
        bool isInUse;
        const struct dc_stream_state *stream;
-       uint8_t protection_bits;
 };
 
 struct dc_3dlut {
        struct kref refcount;
        struct tetrahedral_params lut_3d;
-       struct fixed31_32 hdr_multiplier;
        union dc_3dlut_state state;
 };
 
@@ -1595,7 +1594,6 @@ struct pipe_update_bits {
        uint32_t stereo_format_change:1;
        uint32_t lut_3d:1;
        uint32_t tmz_changed:1;
-       uint32_t mcm_transfer_function_enable_change:1; /* disable or enable 
MCM transfer func */
        uint32_t full_update:1;
        uint32_t sdr_white_level_nits:1;
        uint32_t cm_hist_change:1;
@@ -1640,7 +1638,6 @@ static inline void dc_pipe_update_bits_set_full(struct 
pipe_update_bits *flags)
        flags->stereo_format_change = 1;
        flags->lut_3d = 1;
        flags->tmz_changed = 1;
-       flags->mcm_transfer_function_enable_change = 1;
        flags->full_update = 1;
        flags->sdr_white_level_nits = 1;
        flags->cm_hist_change = 1;
@@ -1674,7 +1671,6 @@ static inline bool dc_pipe_update_bits_is_any_set(const 
struct pipe_update_bits
                flags->stereo_format_change ||
                flags->lut_3d ||
                flags->tmz_changed ||
-               flags->mcm_transfer_function_enable_change ||
                flags->full_update ||
                flags->sdr_white_level_nits ||
                flags->cm_hist_change;
@@ -1709,18 +1705,16 @@ struct dc_plane_state {
        enum dc_color_space color_space;
 
 #ifndef TRIM_CM2
-       // TODO: No longer used, remove
+       bool lut_bank_a;
        struct dc_hdr_static_metadata hdr_static_ctx;
-
        struct dc_3dlut lut3d_func;
        struct dc_transfer_func in_shaper_func;
        struct dc_transfer_func blend_tf;
        enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
        bool mcm_lut1d_enable;
        struct dc_cm2_func_luts mcm_luts;
-#endif /* TRIM_CM2 */
-       bool lut_bank_a;
        enum mpcc_movable_cm_location mcm_location;
+#endif /* TRIM_CM2 */
        struct dc_plane_cm cm;
 
        struct dc_transfer_func *gamcor_tf;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index 9965cf572354..a2e0bafb711a 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -41,12 +41,12 @@
        hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
 
 void hubp401_program_3dlut_fl_addr(struct hubp *hubp,
-       const struct dc_plane_address address)
+       const struct dc_plane_address *address)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, 
address.lut3d.addr.high_part);
-       REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part);
+       REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, 
address->lut3d.addr.high_part);
+       REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address->lut3d.addr.low_part);
 }
 
 void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int 
refcyc_per_3dlut_group)
@@ -72,33 +72,46 @@ uint32_t hubp401_get_3dlut_fl_done(struct hubp *hubp)
        return ret;
 }
 
-void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum 
hubp_3dlut_fl_addressing_mode addr_mode)
+static void hubp401_get_3dlut_fl_xbar_map(
+               const enum dc_cm_lut_pixel_format format,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
 {
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-
-       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
-}
-
-void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum 
hubp_3dlut_fl_width width)
-{
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-
-       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width);
+       switch (format) {
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+               /* BGRA */
+               *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+               *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+               *bit_slice_cb_b =  hubp_3dlut_fl_crossbar_bit_slice_0_15;
+               break;
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+       default:
+               /* RGBA */
+               *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+               *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+               *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+               break;
+       }
 }
 
-void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t 
protection_bits)
+void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
+               const enum dc_cm_lut_pixel_format format)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
-}
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r = 0;
 
-void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r)
-{
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       hubp401_get_3dlut_fl_xbar_map(format,
+                       &bit_slice_y_g,
+                       &bit_slice_cb_b,
+                       &bit_slice_cr_r);
 
        REG_UPDATE_3(HUBP_3DLUT_CONTROL,
                        HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
@@ -106,62 +119,122 @@ void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
                        HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
 }
 
-void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, 
uint16_t scale)
+static enum hubp_3dlut_fl_width hubp401_get_3dlut_fl_width(
+               const enum dc_cm_lut_size size,
+               const enum dc_cm_lut_swizzle swizzle)
 {
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       enum hubp_3dlut_fl_width width = 0;
+
+       switch (size) {
+       case CM_LUT_SIZE_333333:
+               ASSERT(swizzle != CM_LUT_1D_PACKED_LINEAR);
+               width = hubp_3dlut_fl_width_33;
+               break;
+       case CM_LUT_SIZE_171717:
+               if (swizzle != CM_LUT_1D_PACKED_LINEAR) {
+                       width = hubp_3dlut_fl_width_17;
+               } else {
+                       width = hubp_3dlut_fl_width_17_transformed;
+               }
+               break;
+       default:
+               width = 0;
+               break;
+       }
 
-       REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, 
HUBP0_3DLUT_FL_SCALE, scale);
+       return width;
 }
 
-void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode 
mode)
+static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format(
+               const enum dc_cm_lut_pixel_format dc_format)
 {
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       enum hubp_3dlut_fl_format hubp_format = 
hubp_3dlut_fl_format_unorm_12msb_bitslice;
 
-       REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
+       switch (dc_format) {
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+               hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+               break;
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+               hubp_format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+               break;
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+               hubp_format = hubp_3dlut_fl_format_float_fp1_5_10;
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               break;
+       }
+
+       return hubp_format;
 }
 
-void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum 
hubp_3dlut_fl_format format)
+static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode(
+               const enum dc_cm_lut_swizzle swizzle)
 {
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       enum hubp_3dlut_fl_addressing_mode addr_mode;
+
+       switch (swizzle) {
+       case CM_LUT_1D_PACKED_LINEAR:
+               addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
+               break;
+       case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
+       case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
+       default:
+               addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+               break;
+       }
 
-       REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
+       return addr_mode;
 }
 
-void hubp401_program_3dlut_fl_config(
-       struct hubp *hubp,
-       struct hubp_fl_3dlut_config *cfg)
+static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode(
+               const enum dc_cm_lut_swizzle swizzle)
 {
-       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+       enum hubp_3dlut_fl_mode mode;
 
-       uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
-       uint32_t width = {cfg->width};
+       switch (swizzle) {
+       case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
+               mode = hubp_3dlut_fl_mode_native_1;
+               break;
+       case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
+               mode = hubp_3dlut_fl_mode_native_2;
+               break;
+       case CM_LUT_1D_PACKED_LINEAR:
+               mode = hubp_3dlut_fl_mode_transform;
+               break;
+       default:
+               mode = hubp_3dlut_fl_mode_disable;
+               break;
+       }
 
-       if (cfg->layout == CM_LUT_1D_PACKED_LINEAR)
-               width = (cfg->width == 17) ? 4916 : 35940;
+       return mode;
+}
+
+void hubp401_program_3dlut_fl_config(struct hubp *hubp,
+               const struct dc_3dlut_dma *config)
+{
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+       enum hubp_3dlut_fl_width width = 
hubp401_get_3dlut_fl_width(config->size, config->swizzle);
+       enum hubp_3dlut_fl_format format = 
hubp401_get_3dlut_fl_format(config->format);
+       enum hubp_3dlut_fl_addressing_mode addr_mode = 
hubp401_get_3dlut_fl_addr_mode(config->swizzle);
+       enum hubp_3dlut_fl_mode mode = 
hubp401_get_3dlut_fl_mode(config->swizzle);
 
        REG_UPDATE_2(_3DLUT_FL_CONFIG,
-               HUBP0_3DLUT_FL_MODE, cfg->mode,
-               HUBP0_3DLUT_FL_FORMAT, cfg->format);
+                       HUBP0_3DLUT_FL_MODE, mode,
+                       HUBP0_3DLUT_FL_FORMAT, format);
 
        REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
-               HUBP0_3DLUT_FL_BIAS, cfg->bias,
-               HUBP0_3DLUT_FL_SCALE, cfg->scale);
-
-       REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
-               HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
-       REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
-               HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
-
-       //cross bar
-       REG_UPDATE_8(HUBP_3DLUT_CONTROL,
-               HUBP_3DLUT_MPC_WIDTH, mpc_width,
-               HUBP_3DLUT_WIDTH, width,
-               HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
-               HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
-               HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
-               HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
-               HUBP_3DLUT_TMZ, cfg->protection_bits,
-               HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
+                       HUBP0_3DLUT_FL_BIAS, config->bias,
+                       HUBP0_3DLUT_FL_SCALE, config->scale);
+
+       REG_UPDATE_3(HUBP_3DLUT_CONTROL,
+                       HUBP_3DLUT_WIDTH, width,
+                       HUBP_3DLUT_ADDRESSING_MODE, addr_mode,
+                       HUBP_3DLUT_TMZ, config->addr.tmz_surface);
 }
 
 void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool 
c_cursor)
@@ -1062,19 +1135,13 @@ static struct hubp_funcs dcn401_hubp_funcs = {
        .hubp_update_mall_sel = hubp401_update_mall_sel,
        .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
        .hubp_program_mcache_id_and_split_coordinate = 
hubp401_program_mcache_id_and_split_coordinate,
-       .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
-       .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
-       .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
        .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+       .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
        .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
        .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
-       .hubp_program_3dlut_fl_addressing_mode = 
hubp401_program_3dlut_fl_addressing_mode,
-       .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
-       .hubp_program_3dlut_fl_tmz_protected = 
hubp401_program_3dlut_fl_tmz_protected,
        .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
        .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
        .hubp_clear_tiling = hubp401_clear_tiling,
-       .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
        .hubp_read_reg_state = hubp3_read_reg_state
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
index 4116834c552d..adf343837652 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
@@ -328,32 +328,17 @@ uint32_t hubp401_get_3dlut_fl_done(struct hubp *hubp);
 
 void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable);
 
-void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, 
uint16_t scale);
-
 void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
-
-void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t 
protection_bits);
-
-void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum 
hubp_3dlut_fl_width width);
-
-void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum 
hubp_3dlut_fl_addressing_mode addr_mode);
+               const enum dc_cm_lut_pixel_format format);
 
 void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable);
 
 void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int 
refcyc_per_3dlut_group);
 
-void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct 
dc_plane_address address);
+void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct 
dc_plane_address *address);
 
-void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum 
hubp_3dlut_fl_format format);
-
-void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode 
mode);
-
-void hubp401_program_3dlut_fl_config(
-       struct hubp *hubp,
-       struct hubp_fl_3dlut_config *cfg);
+void hubp401_program_3dlut_fl_config(struct hubp *hubp,
+               const struct dc_3dlut_dma *config);
 
 void hubp401_clear_tiling(struct hubp *hubp);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
index 94730f3cff42..86e49eb84a54 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
@@ -317,19 +317,84 @@ static void hubp42_program_surface_config(
        hubp42_program_pixel_format(hubp, format);
 }
 
+static void hubp42_get_3dlut_fl_xbar_map(
+               const enum dc_cm_lut_pixel_format format,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
+               enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
+{
+       switch (format) {
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+       case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+               /* BGRA */
+               *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+               *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+               *bit_slice_cb_b =  hubp_3dlut_fl_crossbar_bit_slice_0_15;
+               break;
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+       case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+       default:
+               /* RGBA */
+               *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+               *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+               *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+               break;
+       }
+}
+
 void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b)
+               const enum dc_cm_lut_pixel_format format)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0;
+
+       hubp42_get_3dlut_fl_xbar_map(format,
+                       &bit_slice_g,
+                       &bit_slice_b,
+                       &bit_slice_r);
+
        REG_UPDATE_3(HUBP_3DLUT_CONTROL,
                HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
                HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
                HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
 }
 
+static uint32_t hubp42_get_3dlut_fl_mpc_width(
+               const enum dc_cm_lut_size size)
+{
+       uint32_t width = 0;
+
+       switch (size) {
+       case CM_LUT_SIZE_333333:
+               width = 1;
+               break;
+       case CM_LUT_SIZE_171717:
+       default:
+               width = 0;
+               break;
+       }
+
+       return width;
+}
+
+void hubp42_program_3dlut_fl_config(struct hubp *hubp,
+               const struct dc_3dlut_dma *config)
+{
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+       uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size);
+
+       REG_UPDATE(HUBP_3DLUT_CONTROL,
+                       HUBP_3DLUT_MPC_WIDTH, mpc_width);
+
+       hubp401_program_3dlut_fl_config(hubp, config);
+}
+
 static bool hubp42_program_surface_flip_and_addr(
        struct hubp *hubp,
        const struct dc_plane_address *address,
@@ -660,15 +725,10 @@ struct hubp_funcs dcn42_hubp_funcs = {
        .hubp_set_flip_int = hubp1_set_flip_int,
        .hubp_in_blank = hubp1_in_blank,
        .program_extended_blank = hubp31_program_extended_blank_value,
-       .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
-       .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
-       .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
        .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+       .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
        .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
        .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
-       .hubp_program_3dlut_fl_addressing_mode = 
hubp401_program_3dlut_fl_addressing_mode,
-       .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
-       .hubp_program_3dlut_fl_tmz_protected = 
hubp401_program_3dlut_fl_tmz_protected,
        .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
        .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
        .hubp_clear_tiling = hubp3_clear_tiling,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
index ba4a58c353dd..3a030e5e517e 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
@@ -79,11 +79,11 @@ bool hubp42_construct(
        const struct dcn_hubp2_shift *hubp_shift,
        const struct dcn_hubp2_mask *hubp_mask);
 
-void hubp42_program_3dlut_fl_crossbar(
-       struct hubp *hubp,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
-       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b);
+void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
+               const enum dc_cm_lut_pixel_format format);
+
+void hubp42_program_3dlut_fl_config(struct hubp *hubp,
+               const struct dc_3dlut_dma *config);
 
 void hubp42_read_state(struct hubp *hubp);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
index e704ce5cd0a0..0230f03590cf 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
@@ -7,6 +7,7 @@
 #include "reg_helper.h"
 #include "basics/conversion.h"
 #include "dcn50_hubp.h"
+#include "dcn42/dcn42_hubp.h"
 
 #define REG(reg)\
        hubp2->hubp_regs->reg
@@ -500,16 +501,11 @@ static struct hubp_funcs dcn50_hubp_funcs = {
        .hubp_update_mall_sel = hubp401_update_mall_sel,
        .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
        .hubp_program_mcache_id_and_split_coordinate = 
hubp401_program_mcache_id_and_split_coordinate,
-       .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
-       .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
-       .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
        .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+       .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
        .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
        .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
-       .hubp_program_3dlut_fl_addressing_mode = 
hubp401_program_3dlut_fl_addressing_mode,
-       .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
-       .hubp_program_3dlut_fl_tmz_protected = 
hubp401_program_3dlut_fl_tmz_protected,
-       .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
+       .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
        .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
        .hubp_clear_tiling = hubp401_clear_tiling,
        .hubp_read_reg_state = hubp3_read_reg_state
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
index 1065303f1d72..d22fe26aae62 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
@@ -441,15 +441,10 @@ static struct hubp_funcs dcn60_hubp_funcs = {
        .hubp_update_mall_sel = NULL,
        .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
        .hubp_program_mcache_id_and_split_coordinate = 
hubp401_program_mcache_id_and_split_coordinate,
-       .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
-       .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
-       .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
        .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+       .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
        .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
        .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
-       .hubp_program_3dlut_fl_addressing_mode = 
hubp401_program_3dlut_fl_addressing_mode,
-       .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
-       .hubp_program_3dlut_fl_tmz_protected = 
hubp401_program_3dlut_fl_tmz_protected,
        .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
        .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
        .hubp_clear_tiling = hubp401_clear_tiling,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 904780e02f70..51596f445a09 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -99,10 +99,6 @@ void dcn401_program_gamut_remap(struct 
program_gamut_remap_params *params)
        unsigned int i = 0;
        struct mpc_grph_gamut_adjustment mpc_adjust;
 
-       //For now assert if location is not pre-blend
-       if (plane)
-               ASSERT(plane->mcm_location == MPCC_MOVABLE_CM_LOCATION_BEFORE);
-
        // program MPCC_MCM_FIRST_GAMUT_REMAP
        memset(&mpc_adjust, 0, sizeof(mpc_adjust));
        mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -413,289 +409,200 @@ void dcn401_init_hw(struct dc *dc)
        }
 }
 
-static void dcn401_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct 
pipe_ctx *pipe_ctx,
-               enum MCM_LUT_XABLE *shaper_xable,
-               enum MCM_LUT_XABLE *lut3d_xable,
-               enum MCM_LUT_XABLE *lut1d_xable)
+void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx)
 {
-       struct mpc *mpc = dc->res_pool->mpc;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
-       if (!pipe_ctx->plane_state)
-               return;
+       const struct pipe_ctx *primary_dpp_pipe_ctx = 
resource_get_primary_dpp_pipe(pipe_ctx);
+       struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+                       primary_dpp_pipe_ctx->plane_res.hubp : NULL;
 
-       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
-       pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-
-       *lut1d_xable = pipe_ctx->plane_state->cm.flags.bits.blend_enable ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-       *shaper_xable = pipe_ctx->plane_state->cm.flags.bits.shaper_enable ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-       *lut3d_xable = (pipe_ctx->plane_state->cm.flags.bits.shaper_enable &&
-                       pipe_ctx->plane_state->cm.flags.bits.lut3d_enable) ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+       if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+               primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
+       }
 }
 
-void dcn401_populate_mcm_luts(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               const struct dc_plane_cm *cm,
-               bool lut_bank_a)
+bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
+                               const struct dc_plane_state *plane_state)
 {
+       struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+       const struct pipe_ctx *primary_dpp_pipe_ctx = 
resource_get_primary_dpp_pipe(pipe_ctx);
        struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
        struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+                       primary_dpp_pipe_ctx->plane_res.hubp : hubp;   /* fall 
back to current pipe */
+       const struct dc_plane_cm *cm = &plane_state->cm;
        int mpcc_id = hubp->inst;
        struct mpc *mpc = dc->res_pool->mpc;
        union mcm_lut_params m_lut_params;
-       const bool lut3d_dma = !!cm->flags.bits.lut3d_dma_enable;
-       enum hubp_3dlut_fl_format format = 0;
-       enum hubp_3dlut_fl_mode mode;
-       /* Width was previously hard-coded to TRANSFORMED via local_mcm build,
-        * preserve identical behavior.
-        */
-       enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_transformed;
-       enum hubp_3dlut_fl_addressing_mode addr_mode;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
-       enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
-       enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
-       enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
+       struct dc_3dlut_dma lut3d_dma;
+       bool lut_enable;
+       bool lut_bank_a;
        bool rval;
+       bool result = true;
+
+       /* decide LUT bank based on current in use */
+       mpc->funcs->get_lut_mode(mpc, MCM_LUT_1DLUT, mpcc_id, &lut_enable, 
&lut_bank_a);
+       if (!lut_enable) {
+               mpc->funcs->get_lut_mode(mpc, MCM_LUT_SHAPER, mpcc_id, 
&lut_enable, &lut_bank_a);
+       }
+       if (!lut_enable) {
+               mpc->funcs->get_lut_mode(mpc, MCM_LUT_3DLUT, mpcc_id, 
&lut_enable, &lut_bank_a);
+       }
 
-       dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, 
&lut3d_xable, &lut1d_xable);
+       /* switch to the next bank */
+       if (lut_enable) {
+               lut_bank_a = !lut_bank_a;
+       }
+
+       /* MCM location fixed to pre-blend */
+       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
 
        /* 1D LUT */
-       {
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
+       lut_enable = cm->flags.bits.blend_enable != 0u;
+       memset(&m_lut_params, 0, sizeof(m_lut_params));
+       if (lut_enable) {
                if (cm->blend_func.type == TF_TYPE_HWPWL)
                        m_lut_params.pwl = &cm->blend_func.pwl;
                else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                       rval = 
cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
                                        &cm->blend_func,
-                                       &dpp_base->regamma_params, false);
+                                       &dpp_base->regamma_params,
+                                       false);
                        m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
NULL;
                }
-               if (m_lut_params.pwl) {
-                       if (mpc->funcs->populate_lut)
-                               mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, 
m_lut_params, lut_bank_a, mpcc_id);
+
+               if (!m_lut_params.pwl) {
+                       lut_enable = false;
                }
-               if (mpc->funcs->program_lut_mode)
-                       mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, 
lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
+       } else {
+               lut_enable = false;
        }
 
+       if (mpc->funcs->program_lut_mode)
+               mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut_enable, 
lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
+       if (lut_enable && mpc->funcs->populate_lut)
+               mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, &m_lut_params, 
lut_bank_a, mpcc_id);
+
        /* Shaper */
-       if (cm->flags.bits.lut3d_enable) {
+       lut_enable = cm->flags.bits.shaper_enable != 0u;
+       if (lut_enable) {
                memset(&m_lut_params, 0, sizeof(m_lut_params));
                if (cm->shaper_func.type == TF_TYPE_HWPWL)
                        m_lut_params.pwl = &cm->shaper_func.pwl;
                else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
                        ASSERT(false);
-                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                       rval = 
cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
                                        &cm->shaper_func,
-                                       &dpp_base->regamma_params, true);
-                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
NULL;
-               }
-               if (m_lut_params.pwl) {
-                       if (mpc->funcs->mcm.populate_lut)
-                               mpc->funcs->mcm.populate_lut(mpc, m_lut_params, 
lut_bank_a, mpcc_id);
-                       if (mpc->funcs->program_lut_mode)
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
+                                       &dpp_base->shaper_params,
+                                       true);
+                       m_lut_params.pwl = rval ? &dpp_base->shaper_params : 
NULL;
                }
-       }
-
-       /* 3DLUT */
-       if (!lut3d_dma) {
-               /* SYSMEM (legacy lut3d_func) */
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
-               if (hubp->funcs->hubp_enable_3dlut_fl)
-                       hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
-
-               if (cm->lut3d_func.state.bits.initialized) {
-                       m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
-                       if (mpc->funcs->populate_lut)
-                               mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, 
m_lut_params, lut_bank_a, mpcc_id);
-                       if (mpc->funcs->program_lut_mode)
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
-                                               mpcc_id);
+               if (!m_lut_params.pwl) {
+                       lut_enable = false;
                }
        } else {
-               /* VIDMEM (3DLUT DMA Fast Load) */
+               lut_enable = false;
+       }
 
-               /* Select width based on the requested LUT size */
-               switch (cm->lut3d_dma.size) {
-               case CM_LUT_SIZE_333333:
-                       if 
(dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33)
-                               width = hubp_3dlut_fl_width_33;
-                       break;
-               case CM_LUT_SIZE_171717:
-                       width = hubp_3dlut_fl_width_17;
-                       break;
-               default:
-                       /* keep default hubp_3dlut_fl_width_transformed */
-                       break;
-               }
+       if (mpc->funcs->program_lut_mode)
+               mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, lut_enable, 
lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
+       if (lut_enable && mpc->funcs->populate_lut)
+               mpc->funcs->populate_lut(mpc, MCM_LUT_SHAPER, &m_lut_params, 
lut_bank_a, mpcc_id);
 
-               //check for support
-               if (mpc->funcs->mcm.is_config_supported &&
-                       !mpc->funcs->mcm.is_config_supported(width))
-                       return;
+       /* NOTE: Toggling from DMA->Host is not supported atomically as hardware
+        * blocks writes until 3DLUT FL mode is cleared from HUBP on VUpdate.
+        * Expectation is either option is used consistently.
+       */
 
-               if (mpc->funcs->program_lut_read_write_control)
-                       mpc->funcs->program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
+       /* 3DLUT */
+       lut_enable = cm->flags.bits.lut3d_enable != 0u;
+       if (lut_enable && cm->flags.bits.lut3d_dma_enable) {
+               /* Fast (DMA) Load Mode */
+               /* MPC */
                if (mpc->funcs->program_lut_mode)
-                       mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, 
lut3d_xable, lut_bank_a, mpcc_id);
+                       mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, 
lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id);
 
-               if (hubp->funcs->hubp_program_3dlut_fl_addr)
-                       hubp->funcs->hubp_program_3dlut_fl_addr(hubp, 
cm->lut3d_dma.addr);
-
-               /* bit_depth was previously zero-initialized in local_mcm,
-                * preserve identical behavior.
-                */
-               if (mpc->funcs->mcm.program_bit_depth)
-                       mpc->funcs->mcm.program_bit_depth(mpc, 0, mpcc_id);
-
-               switch (cm->lut3d_dma.swizzle) {
-               case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
-                       mode = hubp_3dlut_fl_mode_native_1;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
-                       mode = hubp_3dlut_fl_mode_native_2;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               case CM_LUT_1D_PACKED_LINEAR:
-                       mode = hubp_3dlut_fl_mode_transform;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
-                       break;
-               default:
-                       mode = hubp_3dlut_fl_mode_disable;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               }
-               if (hubp->funcs->hubp_program_3dlut_fl_mode)
-                       hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
+               /* only supports 12 bit */
+               if (mpc->funcs->program_lut_read_write_control)
+                       mpc->funcs->program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id);
 
-               if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
-                       
hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
+               if (mpc->funcs->update_3dlut_fast_load_select)
+                       mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 
primary_hubp->inst);
 
-               switch (cm->lut3d_dma.format) {
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
-                       format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-                       break;
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
-                       format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
-                       break;
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
-                       format = hubp_3dlut_fl_format_float_fp1_5_10;
-                       break;
-               default:
-                       break;
-               }
-               if (hubp->funcs->hubp_program_3dlut_fl_format)
-                       hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
-               if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
-                               mpc->funcs->mcm.program_bias_scale) {
-                       mpc->funcs->mcm.program_bias_scale(mpc,
-                               cm->lut3d_dma.bias,
-                               cm->lut3d_dma.scale,
-                               mpcc_id);
-                       hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
-                               cm->lut3d_dma.bias,
-                               cm->lut3d_dma.scale);
-               }
+               /* HUBP */
+               if (primary_hubp->inst == hubp->inst) {
+                       /* only program if this is the primary dpp pipe for the 
given plane */
+                       if (hubp->funcs->hubp_program_3dlut_fl_config)
+                               hubp->funcs->hubp_program_3dlut_fl_config(hubp, 
&cm->lut3d_dma);
 
-               /* component_order was previously hard-coded to RGBA in 
local_mcm,
-                * preserve identical behavior.
-                */
-               crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
-               crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
-               crossbar_bit_slice_cb_b = 
hubp_3dlut_fl_crossbar_bit_slice_32_47;
+                       if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
+                               
hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format);
 
-               if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
-                       hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
-                                       crossbar_bit_slice_cr_r,
-                                       crossbar_bit_slice_y_g,
-                                       crossbar_bit_slice_cb_b);
+                       if (hubp->funcs->hubp_program_3dlut_fl_addr)
+                               hubp->funcs->hubp_program_3dlut_fl_addr(hubp, 
&cm->lut3d_dma.addr);
 
-               if (mpc->funcs->mcm.program_lut_read_write_control)
-                       mpc->funcs->mcm.program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
+                       if (hubp->funcs->hubp_enable_3dlut_fl) {
+                               hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+                       } else {
+                               /* GPU memory only supports fast load path */
+                               BREAK_TO_DEBUGGER();
+                               lut_enable = false;
+                               result = false;
+                       }
+               } else {
+                       /* re-trigger primary HUBP to load 3DLUT */
+                       if (primary_hubp->funcs->hubp_enable_3dlut_fl) {
+                               
primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
+                       }
 
-               if (mpc->funcs->mcm.program_3dlut_size)
-                       mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
+                       /* clear FL setup on this pipe's HUBP */
+                       memset(&lut3d_dma, 0, sizeof(lut3d_dma));
+                       if (hubp->funcs->hubp_program_3dlut_fl_config)
+                               hubp->funcs->hubp_program_3dlut_fl_config(hubp, 
&lut3d_dma);
 
-               if (mpc->funcs->update_3dlut_fast_load_select)
-                       mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 
hubp->inst);
+                       if (hubp->funcs->hubp_enable_3dlut_fl)
+                               hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
+               }
+       } else {
+               /* Legacy (Host) Load Mode */
+               memset(&m_lut_params, 0, sizeof(m_lut_params));
 
-               if (hubp->funcs->hubp_enable_3dlut_fl)
-                       hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
-               else {
-                       if (mpc->funcs->program_lut_mode) {
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                       }
+               if (cm->flags.bits.lut3d_enable && 
cm->lut3d_func.state.bits.initialized) {
+                       m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
+               } else {
+                       lut_enable = false;
                }
-       }
-}
 
-void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
-       (void)dc;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+               /* MPC */
+               if (mpc->funcs->program_lut_mode)
+                       mpc->funcs->program_lut_mode(mpc,
+                                       MCM_LUT_3DLUT,
+                                       lut_enable,
+                                       lut_bank_a,
+                                       cm->lut3d_func.lut_3d.use_tetrahedral_9 
? CM_LUT_SIZE_999 : CM_LUT_SIZE_171717,
+                                       mpcc_id);
+
+               if (lut_enable) {
+                       if (mpc->funcs->program_lut_read_write_control)
+                               mpc->funcs->program_lut_read_write_control(mpc,
+                                               MCM_LUT_3DLUT,
+                                               lut_bank_a,
+                                               
cm->lut3d_func.lut_3d.use_12bits ? 12 : 10,
+                                               mpcc_id);
 
-       if (hubp->funcs->hubp_enable_3dlut_fl) {
-               hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
-       }
-}
+                       if (mpc->funcs->update_3dlut_fast_load_select)
+                               mpc->funcs->update_3dlut_fast_load_select(mpc, 
mpcc_id, 0xf);
 
-bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
-       struct mpc *mpc = dc->res_pool->mpc;
-       bool result;
-       const struct pwl_params *lut_params = NULL;
-       bool rval;
+                       if (mpc->funcs->populate_lut)
+                               mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, 
&m_lut_params, lut_bank_a, mpcc_id);
+               }
 
-       if (plane_state->cm.flags.bits.lut3d_dma_enable) {
-               dcn401_populate_mcm_luts(dc, pipe_ctx, &plane_state->cm, 
plane_state->lut_bank_a);
-               return true;
-       }
+               /* HUBP */
+               memset(&lut3d_dma, 0, sizeof(lut3d_dma));
+               if (hubp->funcs->hubp_program_3dlut_fl_config)
+                       hubp->funcs->hubp_program_3dlut_fl_config(hubp, 
&lut3d_dma);
 
-       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
-       pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-       // 1D LUT
-       if (plane_state->cm.blend_func.type == TF_TYPE_HWPWL)
-               lut_params = &plane_state->cm.blend_func.pwl;
-       else if (plane_state->cm.blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) 
{
-               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                                              
&plane_state->cm.blend_func,
-                                                              
&dpp_base->regamma_params, false);
-               lut_params = rval ? &dpp_base->regamma_params : NULL;
-       }
-       result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
-       lut_params = NULL;
-
-       // Shaper
-       if (plane_state->cm.shaper_func.type == TF_TYPE_HWPWL)
-               lut_params = &plane_state->cm.shaper_func.pwl;
-       else if (plane_state->cm.shaper_func.type == 
TF_TYPE_DISTRIBUTED_POINTS) {
-               // TODO: dpp_base replace
-               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                                              
&plane_state->cm.shaper_func,
-                                                              
&dpp_base->shaper_params, true);
-               lut_params = rval ? &dpp_base->shaper_params : NULL;
-       }
-       result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
-
-       // 3D
-       if (mpc->funcs->program_3dlut) {
-               if (plane_state->cm.lut3d_func.state.bits.initialized == 1)
-                       result &= mpc->funcs->program_3dlut(mpc, 
&plane_state->cm.lut3d_func.lut_3d, mpcc_id);
-               else
-                       result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+               if (hubp->funcs->hubp_enable_3dlut_fl)
+                       hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
        }
 
        return result;
@@ -2096,42 +2003,41 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx 
*pipe_ctx)
        if (!pipe_ctx)
                return;
 
-       struct pipe_ctx *wa_pipes[MAX_PIPES] = { NULL };
-       struct pipe_ctx *odm_pipe, *mpc_pipe;
-       int i, wa_pipe_ct = 0;
+       const struct pipe_ctx *otg_master_pipe_ctx = 
resource_get_otg_master(pipe_ctx);
+       struct timing_generator *tg = otg_master_pipe_ctx ?
+                       otg_master_pipe_ctx->stream_res.tg : NULL;
+       const struct pipe_ctx *primary_dpp_pipe_ctx = 
resource_is_pipe_type(pipe_ctx, DPP_PIPE) ?
+                       resource_get_primary_dpp_pipe(pipe_ctx) : pipe_ctx;
+       struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+                       primary_dpp_pipe_ctx->plane_res.hubp : NULL;
 
-       for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = 
odm_pipe->next_odm_pipe) {
-               for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = 
mpc_pipe->bottom_pipe) {
-                       if (mpc_pipe->plane_state &&
-                                       
mpc_pipe->plane_state->cm.flags.bits.lut3d_enable &&
-                                       
mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) {
-                               wa_pipes[wa_pipe_ct++] = mpc_pipe;
-                       }
-               }
+       if (!otg_master_pipe_ctx || !tg) {
+               return;
        }
 
-       if (wa_pipe_ct > 0) {
-               if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout)
-                       
pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, 
true);
+       if (primary_dpp_pipe_ctx &&
+                       primary_dpp_pipe_ctx->plane_state &&
+                       
primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_enable &&
+                       
primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_dma_enable) {
+               if (tg->funcs->set_vupdate_keepout)
+                       tg->funcs->set_vupdate_keepout(tg, true);
 
-               for (i = 0; i < wa_pipe_ct; ++i) {
-                       if 
(wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl)
-                               
wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp,
 true);
+               if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+                       primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, 
true);
                }
 
-               pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
-               if (pipe_ctx->stream_res.tg->funcs->wait_update_lock_status)
-                       
pipe_ctx->stream_res.tg->funcs->wait_update_lock_status(pipe_ctx->stream_res.tg,
 false);
+               tg->funcs->unlock(tg);
+               if (tg->funcs->wait_update_lock_status)
+                       tg->funcs->wait_update_lock_status(tg, false);
 
-               for (i = 0; i < wa_pipe_ct; ++i) {
-                       if 
(wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl)
-                               
wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp,
 true);
+               if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+                       primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, 
true);
                }
 
-               if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout)
-                       
pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, 
false);
+               if (tg->funcs->set_vupdate_keepout)
+                       tg->funcs->set_vupdate_keepout(tg, false);
        } else {
-               pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
+               tg->funcs->unlock(tg);
        }
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
index f90e25243ead..69c7dc73a29a 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
@@ -39,8 +39,7 @@ void dcn401_init_hw(struct dc *dc);
 bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
                                const struct dc_plane_state *plane_state);
 bool dcn401_set_output_transfer_func(struct set_output_transfer_func_params 
*params);
-void dcn401_trigger_3dlut_dma_load(struct dc *dc,
-                               struct pipe_ctx *pipe_ctx);
+void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx);
 void dcn401_calculate_dccg_tmds_div_value(struct pipe_ctx *pipe_ctx,
                                unsigned int *tmds_div);
 enum dc_status dcn401_enable_stream_timing(
@@ -48,10 +47,6 @@ enum dc_status dcn401_enable_stream_timing(
                                struct dc_state *context,
                                struct dc *dc);
 void dcn401_enable_stream(struct pipe_ctx *pipe_ctx);
-void dcn401_populate_mcm_luts(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               const struct dc_plane_cm *cm,
-               bool lut_bank_a);
 void dcn401_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
 
 void dcn401_disable_link_output(struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index f206e221f926..7039f40ea880 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -166,7 +166,6 @@ static const struct hwseq_private_funcs 
dcn401_private_funcs = {
        .calculate_dccg_k1_k2_values = NULL,
        .apply_single_controller_ctx_to_hw = 
dce110_apply_single_controller_ctx_to_hw,
        .reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
-       .populate_mcm_luts = NULL,
        .perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
        .program_pipe_sequence = dcn401_program_pipe_sequence,
        .dc_ip_request_cntl = dcn401_dc_ip_request_cntl,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
index 151a29bf0e9d..13580d9f9303 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
@@ -402,64 +402,6 @@ void dcn42_program_cm_hist(
                        plane_state->cm_hist_control, plane_state->color_space);
 }
 
-static void dc_get_lut_xbar(
-       enum hubp_3dlut_fl_crossbar_bit_slice *cr_r,
-       enum hubp_3dlut_fl_crossbar_bit_slice *y_g,
-       enum hubp_3dlut_fl_crossbar_bit_slice *cb_b)
-{
-       /* component_order was previously hard-coded to RGBA in local_mcm,
-        * preserve identical behavior.
-        */
-       *cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
-       *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
-       *cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
-}
-
-static void dc_get_lut_mode(
-       enum dc_cm_lut_swizzle swizzle,
-       enum hubp_3dlut_fl_mode *mode,
-       enum hubp_3dlut_fl_addressing_mode *addr_mode)
-{
-       switch (swizzle) {
-       case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
-               *mode = hubp_3dlut_fl_mode_native_1;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
-               *mode = hubp_3dlut_fl_mode_native_2;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       case CM_LUT_1D_PACKED_LINEAR:
-               *mode = hubp_3dlut_fl_mode_transform;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
-               break;
-       default:
-               *mode = hubp_3dlut_fl_mode_disable;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       }
-}
-
-static void dc_get_lut_format(
-       enum dc_cm_lut_pixel_format dc_format,
-       enum hubp_3dlut_fl_format *format)
-{
-       switch (dc_format) {
-       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
-               *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-               break;
-       case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
-               *format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
-               break;
-       case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
-               *format = hubp_3dlut_fl_format_float_fp1_5_10;
-               break;
-       default:
-               *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-               break;
-       }
-}
-
 static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
 {
        if (mpc->funcs->rmcm.power_on_shaper_3dlut &&
@@ -470,106 +412,17 @@ static bool dc_is_rmcm_3dlut_supported(struct hubp 
*hubp, struct mpc *mpc)
        return false;
 }
 
-static bool is_rmcm_3dlut_fl_supported(struct dc *dc)
-{
-       /* size was previously hard-coded to TRANSFORMED in local_mcm,
-        * which mapped to dim_17. Preserve identical behavior.
-        */
-       if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut)
-               return false;
-       return dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17 != 0u;
-}
-
-static void dcn42_set_mcm_location_post_blend(struct dc *dc, struct pipe_ctx 
*pipe_ctx, bool bPostBlend)
-{
-       struct mpc *mpc = dc->res_pool->mpc;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
-       if (!pipe_ctx->plane_state)
-               return;
-
-       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
-       pipe_ctx->plane_state->mcm_location = (bPostBlend) ?
-                                                                               
        MPCC_MOVABLE_CM_LOCATION_AFTER :
-                                                                               
        MPCC_MOVABLE_CM_LOCATION_BEFORE;
-}
-
-static void dcn42_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct 
pipe_ctx *pipe_ctx,
-               enum MCM_LUT_XABLE *shaper_xable,
-               enum MCM_LUT_XABLE *lut3d_xable,
-               enum MCM_LUT_XABLE *lut1d_xable)
-{
-       struct mpc *mpc = dc->res_pool->mpc;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
-       if (!pipe_ctx->plane_state)
-               return;
-
-       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
-       pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-
-       *lut1d_xable = pipe_ctx->plane_state->cm.flags.bits.blend_enable ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-       *shaper_xable = pipe_ctx->plane_state->cm.flags.bits.shaper_enable ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-       *lut3d_xable = (pipe_ctx->plane_state->cm.flags.bits.shaper_enable &&
-                       pipe_ctx->plane_state->cm.flags.bits.lut3d_enable) ?
-               MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-}
-
-static void fl_get_lut_mode(
-       enum dc_cm_lut_swizzle swizzle,
-       enum hubp_3dlut_fl_mode *mode,
-       enum hubp_3dlut_fl_addressing_mode *addr_mode,
-       enum hubp_3dlut_fl_width *width)
-{
-       /* size was previously hard-coded to TRANSFORMED in local_mcm,
-        * preserve identical behavior (transformed width).
-        */
-       *width = hubp_3dlut_fl_width_17;
-
-       switch (swizzle) {
-       case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
-               *mode = hubp_3dlut_fl_mode_native_1;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
-               *mode = hubp_3dlut_fl_mode_native_2;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       case CM_LUT_1D_PACKED_LINEAR:
-               *mode = hubp_3dlut_fl_mode_transform;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
-               break;
-       default:
-               *mode = hubp_3dlut_fl_mode_disable;
-               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-               break;
-       }
-}
-
 bool dcn42_program_rmcm_luts(
        struct hubp *hubp,
        struct pipe_ctx *pipe_ctx,
        const struct dc_plane_cm *cm,
        struct mpc *mpc,
-       bool lut_bank_a,
        int mpcc_id)
 {
        struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
        union mcm_lut_params m_lut_params = {0};
-       enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, 
lut1d_xable;
-               enum hubp_3dlut_fl_mode mode;
-       enum hubp_3dlut_fl_addressing_mode addr_mode;
-       enum hubp_3dlut_fl_format format = 
hubp_3dlut_fl_format_unorm_12msb_bitslice;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 
hubp_3dlut_fl_crossbar_bit_slice_16_31;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 
hubp_3dlut_fl_crossbar_bit_slice_0_15;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 
hubp_3dlut_fl_crossbar_bit_slice_32_47;
-       enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_17;
-
 
        struct dc *dc = hubp->ctx->dc;
-       struct hubp_fl_3dlut_config fl_config;
        struct mpc_fl_3dlut_config mpc_fl_config;
 
        struct dc_stream_state *stream = pipe_ctx->stream;
@@ -577,19 +430,24 @@ bool dcn42_program_rmcm_luts(
        // true->false when it can be allocated at DI time
        struct dc_rmcm_3dlut *rmcm_3dlut = dc_stream_get_3dlut_for_stream(dc, 
stream, false);
 
+       bool lut_enable = false;
+       bool lut_bank_a = true;
+
        //check to see current pipe is part of a stream with allocated rmcm 
3dlut
        if (!rmcm_3dlut)
                return false;
 
-       /* rmcm_tmz was previously zero-initialized in local_mcm,
-        * preserve identical behavior.
+       /* Determine the LUT bank currently active in HW and switch to the other
+        * bank to preserve double-buffering (mirrors dcn401_set_mcm_luts).
         */
-       rmcm_3dlut->protection_bits = 0;
+       if (mpc->funcs->rmcm.get_3dlut_mode)
+               mpc->funcs->rmcm.get_3dlut_mode(mpc, mpcc_id, &lut_enable, 
&lut_bank_a);
 
-       dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, 
&lut3d_xable, &lut1d_xable);
+       if (lut_enable)
+               lut_bank_a = !lut_bank_a;
 
        /* Shaper */
-       {
+       if (cm->flags.bits.shaper_enable) {
                memset(&m_lut_params, 0, sizeof(m_lut_params));
 
                if (cm->shaper_func.type == TF_TYPE_HWPWL) {
@@ -615,56 +473,19 @@ bool dcn42_program_rmcm_luts(
 
        /* 3DLUT */
        if (!cm->flags.bits.lut3d_dma_enable) {
-               /* SYSMEM path — no DMA 3DLUT available.
-                * Previously this was treated as a no-op for the DMA/VIDMEM
-                * programming, preserve identical behavior.
+               /* RMCM host (non-DMA) 3DLUT load is not implemented; fail fast
+                * instead of silently reporting success
                 */
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
+               BREAK_TO_DEBUGGER();
+               return false;
        } else {
-               /* VIDMEM (3DLUT DMA Fast Load) */
-
-               fl_get_lut_mode(cm->lut3d_dma.swizzle,
-                               &mode,
-                               &addr_mode,
-                               &width);
-
-               if (!dc_is_rmcm_3dlut_supported(hubp, mpc) ||
-                       !mpc->funcs->rmcm.is_config_supported(
-                               (width == hubp_3dlut_fl_width_17 ||
-                                width == hubp_3dlut_fl_width_transformed) ? 17 
: 33))
+               if (!dc_is_rmcm_3dlut_supported(hubp, mpc))
                        return false;
 
-               // setting native or transformed mode,
-               dc_get_lut_mode(cm->lut3d_dma.swizzle, &mode, &addr_mode);
-
                //seems to be only for the MCM
-               dc_get_lut_format(cm->lut3d_dma.format, &format);
-
-               dc_get_lut_xbar(
-                       &crossbar_bit_slice_cr_r,
-                       &crossbar_bit_slice_y_g,
-                       &crossbar_bit_slice_cb_b);
-
-               fl_config.mode                                  = mode;
-               fl_config.enabled                               = lut3d_xable 
!= MCM_LUT_DISABLE;
-               fl_config.address                               = 
cm->lut3d_dma.addr;
-               fl_config.format                                = format;
-               fl_config.crossbar_bit_slice_y_g  = crossbar_bit_slice_y_g;
-               fl_config.crossbar_bit_slice_cb_b = crossbar_bit_slice_cb_b;
-               fl_config.crossbar_bit_slice_cr_r = crossbar_bit_slice_cr_r;
-               fl_config.width                             = width;
-               fl_config.protection_bits               = 
rmcm_3dlut->protection_bits;
-               fl_config.addr_mode                         = addr_mode;
-               fl_config.layout                = cm->lut3d_dma.swizzle;
-               fl_config.bias  = cm->lut3d_dma.bias;
-               fl_config.scale = cm->lut3d_dma.scale;
-
-               mpc_fl_config.enabled                   = fl_config.enabled;
-               mpc_fl_config.width                 = width;
+               mpc_fl_config.enabled                   = 
cm->flags.bits.lut3d_enable != 0u;
+               mpc_fl_config.size                  = cm->lut3d_dma.size;
                mpc_fl_config.select_lut_bank_a = lut_bank_a;
-               /* bit_depth was previously zero-initialized in local_mcm,
-                * preserve identical behavior.
-                */
                mpc_fl_config.bit_depth             = 0;
                mpc_fl_config.hubp_index                = hubp->inst;
                mpc_fl_config.bias      = cm->lut3d_dma.bias;
@@ -676,7 +497,12 @@ bool dcn42_program_rmcm_luts(
                //2. program RMCM - 3dlut reg programming
                mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, 
mpcc_id);
 
-               hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config);
+               /* HUBP */
+               if (hubp->funcs->hubp_program_3dlut_fl_config)
+                       hubp->funcs->hubp_program_3dlut_fl_config(hubp, 
&cm->lut3d_dma);
+
+               if (hubp->funcs->hubp_program_3dlut_fl_addr)
+                       hubp->funcs->hubp_program_3dlut_fl_addr(hubp, 
&cm->lut3d_dma.addr);
 
                //3. power on the block
                mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true);
@@ -685,261 +511,31 @@ bool dcn42_program_rmcm_luts(
        return true;
 }
 
-void dcn42_populate_mcm_luts(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               const struct dc_plane_cm *cm,
-               bool lut_bank_a)
-{
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       int mpcc_id = hubp->inst;
-       struct mpc *mpc = dc->res_pool->mpc;
-       union mcm_lut_params m_lut_params;
-       const bool lut3d_dma = !!cm->flags.bits.lut3d_dma_enable;
-       enum hubp_3dlut_fl_format format = 0;
-       enum hubp_3dlut_fl_mode mode;
-       /* Width was previously hard-coded to TRANSFORMED via local_mcm build,
-        * preserve identical behavior.
-        */
-       enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_transformed;
-       enum hubp_3dlut_fl_addressing_mode addr_mode;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
-       enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
-       enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
-       enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
-       bool rval;
-
-       dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, 
&lut3d_xable, &lut1d_xable);
-
-       //MCM - setting its location (Before/After) blender
-       //mpc_mcm_post_blend was previously zero-initialized in local_mcm,
-       //preserve identical behavior.
-       dcn42_set_mcm_location_post_blend(
-               dc,
-               pipe_ctx,
-               false);
-
-       //RMCM - 3dLUT+Shaper
-       if (cm->flags.bits.rmcm_enable &&
-               is_rmcm_3dlut_fl_supported(dc))
-               dcn42_program_rmcm_luts(
-                       hubp,
-                       pipe_ctx,
-                       cm,
-                       mpc,
-                       lut_bank_a,
-                       mpcc_id);
-
-       /* 1D LUT */
-       {
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
-               if (cm->blend_func.type == TF_TYPE_HWPWL)
-                       m_lut_params.pwl = &cm->blend_func.pwl;
-               else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
-                                       &cm->blend_func,
-                                       &dpp_base->regamma_params, false);
-                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
NULL;
-               }
-               if (m_lut_params.pwl) {
-                       if (mpc->funcs->populate_lut)
-                               mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, 
m_lut_params, lut_bank_a, mpcc_id);
-               }
-               if (mpc->funcs->program_lut_mode)
-                       mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, 
lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
-       }
-
-       /* Shaper */
-       if (cm->flags.bits.lut3d_enable) {
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
-               if (cm->shaper_func.type == TF_TYPE_HWPWL)
-                       m_lut_params.pwl = &cm->shaper_func.pwl;
-               else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       ASSERT(false);
-                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
-                                       &cm->shaper_func,
-                                       &dpp_base->regamma_params, true);
-                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
NULL;
-               }
-               if (m_lut_params.pwl) {
-                       if (mpc->funcs->mcm.populate_lut)
-                               mpc->funcs->mcm.populate_lut(mpc, m_lut_params, 
lut_bank_a, mpcc_id);
-                       if (mpc->funcs->program_lut_mode)
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
-               }
-       }
-
-       /* 3DLUT */
-       if (!lut3d_dma) {
-               /* SYSMEM (legacy lut3d_func) */
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
-               if (hubp->funcs->hubp_enable_3dlut_fl)
-                       hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
-
-               if (cm->lut3d_func.state.bits.initialized) {
-                       m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
-                       if (mpc->funcs->populate_lut)
-                               mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, 
m_lut_params, lut_bank_a, mpcc_id);
-                       if (mpc->funcs->program_lut_mode)
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
-                                               mpcc_id);
-               }
-       } else {
-               /* VIDMEM (3DLUT DMA Fast Load) */
-
-               //check for support
-               if (mpc->funcs->mcm.is_config_supported &&
-                       !mpc->funcs->mcm.is_config_supported(width))
-                       return;
-
-               if (mpc->funcs->program_lut_read_write_control)
-                       mpc->funcs->program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
-               if (mpc->funcs->program_lut_mode)
-                       mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, 
lut3d_xable, lut_bank_a, mpcc_id);
-
-               if (hubp->funcs->hubp_program_3dlut_fl_addr)
-                       hubp->funcs->hubp_program_3dlut_fl_addr(hubp, 
cm->lut3d_dma.addr);
-
-               /* bit_depth was previously zero-initialized in local_mcm,
-                * preserve identical behavior.
-                */
-               if (mpc->funcs->mcm.program_bit_depth)
-                       mpc->funcs->mcm.program_bit_depth(mpc, 0, mpcc_id);
-
-               switch (cm->lut3d_dma.swizzle) {
-               case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
-                       mode = hubp_3dlut_fl_mode_native_1;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
-                       mode = hubp_3dlut_fl_mode_native_2;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               case CM_LUT_1D_PACKED_LINEAR:
-                       mode = hubp_3dlut_fl_mode_transform;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
-                       break;
-               default:
-                       mode = hubp_3dlut_fl_mode_disable;
-                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
-                       break;
-               }
-               if (hubp->funcs->hubp_program_3dlut_fl_mode)
-                       hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
-
-               if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
-                       
hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
-
-               switch (cm->lut3d_dma.format) {
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
-                       format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-                       break;
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
-                       format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
-                       break;
-               case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
-                       format = hubp_3dlut_fl_format_float_fp1_5_10;
-                       break;
-               default:
-                       break;
-               }
-               if (hubp->funcs->hubp_program_3dlut_fl_format)
-                       hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
-               if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
-                               mpc->funcs->mcm.program_bias_scale) {
-                       mpc->funcs->mcm.program_bias_scale(mpc,
-                               cm->lut3d_dma.bias,
-                               cm->lut3d_dma.scale,
-                               mpcc_id);
-                       hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
-                               cm->lut3d_dma.bias,
-                               cm->lut3d_dma.scale);
-               }
-
-               /* component_order was previously hard-coded to RGBA in 
local_mcm,
-                * preserve identical behavior.
-                */
-               crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
-               crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
-               crossbar_bit_slice_cb_b = 
hubp_3dlut_fl_crossbar_bit_slice_32_47;
-
-               if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
-                       hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
-                                       crossbar_bit_slice_cr_r,
-                                       crossbar_bit_slice_y_g,
-                                       crossbar_bit_slice_cb_b);
-
-               if (mpc->funcs->mcm.program_lut_read_write_control)
-                       mpc->funcs->mcm.program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
-
-               if (mpc->funcs->mcm.program_3dlut_size)
-                       mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
-
-               if (mpc->funcs->update_3dlut_fast_load_select)
-                       mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 
hubp->inst);
-
-               if (hubp->funcs->hubp_enable_3dlut_fl)
-                       hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
-               else {
-                       if (mpc->funcs->program_lut_mode) {
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                               mpc->funcs->program_lut_mode(mpc, 
MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
-                       }
-               }
-       }
-}
-
 bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
                                const struct dc_plane_state *plane_state)
 {
-       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
-       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-       struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
-       struct mpc *mpc = dc->res_pool->mpc;
        bool result;
-       const struct pwl_params *lut_params = NULL;
-       bool rval;
-
-       if (plane_state->cm.flags.bits.lut3d_dma_enable) {
-               dcn42_populate_mcm_luts(dc, pipe_ctx, &plane_state->cm, 
plane_state->lut_bank_a);
-               return true;
-       }
 
-       mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
-       pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-       // 1D LUT
-       if (plane_state->cm.blend_func.type == TF_TYPE_HWPWL)
-               lut_params = &plane_state->cm.blend_func.pwl;
-       else if (plane_state->cm.blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) 
{
-               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                               &plane_state->cm.blend_func,
-                               &dpp_base->regamma_params, false);
-               lut_params = rval ? &dpp_base->regamma_params : NULL;
-       }
-       result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
-       lut_params = NULL;
-
-       // Shaper
-       if (plane_state->cm.shaper_func.type == TF_TYPE_HWPWL)
-               lut_params = &plane_state->cm.shaper_func.pwl;
-       else if (plane_state->cm.shaper_func.type == 
TF_TYPE_DISTRIBUTED_POINTS) {
-               // TODO: dpp_base replace
-               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                               &plane_state->cm.shaper_func,
-                               &dpp_base->shaper_params, true);
-               lut_params = rval ? &dpp_base->shaper_params : NULL;
-       }
-       result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+       /* MCM */
+       result = dcn401_set_mcm_luts(pipe_ctx, plane_state);
 
-       // 3D
-       if (mpc->funcs->program_3dlut) {
-               if (plane_state->cm.lut3d_func.state.bits.initialized == 1)
-                       result &= mpc->funcs->program_3dlut(mpc, 
&plane_state->cm.lut3d_func.lut_3d, mpcc_id);
-               else
-                       result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+       /* RMCM */
+       {
+               struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+               struct hubp *hubp = pipe_ctx->plane_res.hubp;
+               const struct dc_plane_cm *cm = &plane_state->cm;
+               struct mpc *mpc = dc->res_pool->mpc;
+               int mpcc_id = hubp->inst;
+
+               if (cm->flags.bits.rmcm_enable && 
cm->flags.bits.lut3d_dma_enable) {
+                       /* TODO - move RMCM to its own block */
+                       dcn42_program_rmcm_luts(
+                               hubp,
+                               pipe_ctx,
+                               cm,
+                               mpc,
+                               mpcc_id);
+               }
        }
 
        return result;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
index c469e7535114..c4cfeed45b19 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
@@ -18,17 +18,11 @@ void dcn42_program_cm_hist(
 bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
        const struct dc_plane_state *plane_state);
 
-void dcn42_populate_mcm_luts(struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               const struct dc_plane_cm *cm,
-               bool lut_bank_a);
-
 bool dcn42_program_rmcm_luts(
        struct hubp *hubp,
        struct pipe_ctx *pipe_ctx,
        const struct dc_plane_cm *cm,
        struct mpc *mpc,
-       bool lut_bank_a,
        int mpcc_id);
 void dcn42_hardware_release(struct dc *dc);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
index 49c13611a518..ba12a97a220f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
@@ -155,8 +155,6 @@ static const struct hwseq_private_funcs dcn42_private_funcs 
= {
        .calculate_dccg_k1_k2_values = NULL,
        .apply_single_controller_ctx_to_hw = 
dce110_apply_single_controller_ctx_to_hw,
        .reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
-       .populate_mcm_luts = NULL,
-       .perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
        .program_cm_hist = dcn42_program_cm_hist,
        .dpp_root_clock_control = dcn35_dpp_root_clock_control,
        .dpstream_root_clock_control = dcn35_dpstream_root_clock_control,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
index 5f4f32d516d5..1c908964153b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
@@ -166,8 +166,6 @@ static const struct hwseq_private_funcs dcn60_private_funcs 
= {
        .calculate_dccg_k1_k2_values = NULL,
        .apply_single_controller_ctx_to_hw = 
dcn60_apply_single_controller_ctx_to_hw,
        .reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
-       .populate_mcm_luts = NULL,
-       .perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
        .program_cm_hist = dcn42_program_cm_hist,
        .program_pipe = dcn401_program_pipe,
        .program_pipe_sequence = dcn401_program_pipe_sequence,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h 
b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index c4296b8390f2..cdf2562a9a40 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -1506,7 +1506,7 @@ struct hw_sequencer_funcs {
        void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx,
                        enum dc_color_space colorspace,
                        uint16_t *matrix, int opp_id);
-       void (*trigger_3dlut_dma_load)(struct dc *dc, struct pipe_ctx 
*pipe_ctx);
+       void (*trigger_3dlut_dma_load)(struct pipe_ctx *pipe_ctx);
 
        /* VM Related */
        int (*init_sys_ctx)(struct dce_hwseq *hws,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h 
b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
index 31ace62a37d9..0f7881a21462 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
@@ -58,7 +58,6 @@ struct dc_state;
 struct dc_stream_status;
 struct dc_writeback_info;
 struct dchub_init_data;
-struct dc_plane_cm;
 struct dc_static_screen_params;
 struct resource_pool;
 struct resource_context;
@@ -218,10 +217,6 @@ struct hwseq_private_funcs {
        void (*reset_back_end_for_pipe)(struct dc *dc,
                        struct pipe_ctx *pipe_ctx,
                        struct dc_state *context);
-       void (*populate_mcm_luts)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx,
-                       const struct dc_plane_cm *cm,
-                       bool lut_bank_a);
        void (*perform_3dlut_wa_unlock)(struct pipe_ctx *pipe_ctx);
        void (*wait_for_pipe_update_if_needed)(struct dc *dc, struct pipe_ctx 
*pipe_ctx, bool is_surface_update_only);
        void (*set_wait_for_update_needed_for_pipe)(struct dc *dc, struct 
pipe_ctx *pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 6d6eda0e7e9d..9dc9317c28a4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode {
 enum hubp_3dlut_fl_width {
        hubp_3dlut_fl_width_17 = 17,
        hubp_3dlut_fl_width_33 = 33,
-       hubp_3dlut_fl_width_transformed    = 4916, //mpc default
+       hubp_3dlut_fl_width_17_transformed    = 4916, //mpc default
 };
 
 enum hubp_3dlut_fl_crossbar_bit_slice {
@@ -99,22 +99,6 @@ enum hubp_3dlut_fl_crossbar_bit_slice {
        hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3
 };
 
-struct hubp_fl_3dlut_config {
-       bool enabled;
-       enum hubp_3dlut_fl_width width;
-       enum hubp_3dlut_fl_mode mode;
-       enum hubp_3dlut_fl_format format;
-       uint16_t bias;
-       uint16_t scale;
-       struct dc_plane_address address;
-       enum hubp_3dlut_fl_addressing_mode addr_mode;
-       enum dc_cm_lut_swizzle layout;
-       uint8_t protection_bits;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
-       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
-};
-
 struct hubp {
        const struct hubp_funcs *funcs;
        struct dc_context *ctx;
@@ -289,24 +273,15 @@ struct hubp_funcs {
 
        void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
        void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, 
struct dml2_hubp_pipe_mcache_regs *mcache_regs);
-       void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t 
bias, uint16_t scale);
-       void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp,
-                       enum hubp_3dlut_fl_mode mode);
-       void (*hubp_program_3dlut_fl_format)(struct hubp *hubp,
-                       enum hubp_3dlut_fl_format format);
        void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp,
-               const struct dc_plane_address address);
+               const struct dc_plane_address *address);
+       void (*hubp_program_3dlut_fl_config)(struct hubp *hubp,
+               const struct dc_3dlut_dma *config);
        void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int 
refcyc_per_3dlut_group);
        void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable);
-       void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum 
hubp_3dlut_fl_addressing_mode addr_mode);
-       void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum 
hubp_3dlut_fl_width width);
-       void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t 
protection_bits);
        void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
-                       enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
+                       enum dc_cm_lut_pixel_format format);
        uint32_t (*hubp_get_3dlut_fl_done)(struct hubp *hubp);
-       void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct 
hubp_fl_3dlut_config *cfg);
        void (*hubp_clear_tiling)(struct hubp *hubp);
        uint32_t (*hubp_get_current_read_line)(struct hubp *hubp);
        uint32_t (*hubp_get_det_config_error)(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 54eb2eba68bf..d863f4bdccad 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -54,6 +54,7 @@
 #include "dc_hw_types.h"
 #include "hw_shared.h"
 #include "transform.h"
+#include "dc_types.h"
 
 #define MAX_MPCC 6
 #define MAX_OPP 6
@@ -101,13 +102,6 @@ enum mpcc_movable_cm_location {
        MPCC_MOVABLE_CM_LOCATION_AFTER,
 };
 
-enum MCM_LUT_XABLE {
-       MCM_LUT_DISABLE,
-       MCM_LUT_DISABLED = MCM_LUT_DISABLE,
-       MCM_LUT_ENABLE,
-       MCM_LUT_ENABLED = MCM_LUT_ENABLE,
-};
-
 enum MCM_LUT_ID {
        MCM_LUT_3DLUT,
        MCM_LUT_1DLUT,
@@ -116,7 +110,7 @@ enum MCM_LUT_ID {
 
 struct mpc_fl_3dlut_config {
        bool enabled;
-       uint16_t width;
+       enum dc_cm_lut_size size;
        bool select_lut_bank_a;
        uint16_t bit_depth;
        int hubp_index;
@@ -1075,8 +1069,11 @@ struct mpc_funcs {
        *
        * void
        */
-       void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const 
union mcm_lut_params params,
-                       bool lut_bank_a, int mpcc_id);
+       void (*populate_lut)(struct mpc *mpc,
+                       const enum MCM_LUT_ID id,
+                       const union mcm_lut_params *params,
+                       const bool lut_bank_a,
+                       const int mpcc_id);
 
        /**
        * @program_lut_read_write_control:
@@ -1087,13 +1084,18 @@ struct mpc_funcs {
        * - [in/out] mpc - MPC context.
        * - [in] id
        * - [in] lut_bank_a
+       * - [in] bit_depth
        * - [in] mpcc_id
        *
        * Return:
        *
        * void
        */
-       void (*program_lut_read_write_control)(struct mpc *mpc, const enum 
MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
+       void (*program_lut_read_write_control)(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const bool lut_bank_a,
+               const unsigned int bit_depth,
+               const int mpcc_id);
 
        /**
        * @program_lut_mode:
@@ -1103,33 +1105,44 @@ struct mpc_funcs {
        * Parameters:
        * - [in/out] mpc - MPC context.
        * - [in] id
-       * - [in] xable
+       * - [in] enable
        * - [in] lut_bank_a
+       * - [in] size
        * - [in] mpcc_id
        *
        * Return:
        *
        * void
        */
-       void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, 
const enum MCM_LUT_XABLE xable,
-                       bool lut_bank_a, int mpcc_id);
+       void (*program_lut_mode)(struct mpc *mpc,
+                       const enum MCM_LUT_ID id,
+                       const bool enable,
+                       const bool lut_bank_a,
+                       const enum dc_cm_lut_size size,
+                       const int mpcc_id);
 
-       /**
-        * @mcm:
-        *
-        * MPC MCM new HW sequential programming functions
-        */
-       struct {
-               void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int 
mpcc_id);
-               void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, 
uint16_t scale, int mpcc_id);
-               void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, 
int mpcc_id);
-               bool (*is_config_supported)(uint32_t width);
-               void (*program_lut_read_write_control)(struct mpc *mpc, const 
enum MCM_LUT_ID id,
-                       bool lut_bank_a, bool enabled, int mpcc_id);
 
-               void (*populate_lut)(struct mpc *mpc, const union 
mcm_lut_params params,
-                       bool lut_bank_a, int mpcc_id);
-       } mcm;
+       /**
+       * @get_lut_mode:
+       *
+       * Obtains enablement and ram bank status.
+       *
+       * Parameters:
+       * - [in/out] mpc - MPC context.
+       * - [in] id
+       * - [in] mpcc_id
+       * - [out] enable
+       * - [out] lut_bank_a
+       *
+       * Return:
+       *
+       * void
+       */
+       void (*get_lut_mode)(struct mpc *mpc,
+                       const enum MCM_LUT_ID id,
+                       const int mpcc_id,
+                       bool *enable,
+                       bool *lut_bank_a);
 
        /**
         * @rmcm:
@@ -1142,9 +1155,11 @@ struct mpc_funcs {
                void (*update_3dlut_fast_load_select)(struct mpc *mpc, int 
mpcc_id, int hubp_idx);
                void (*program_lut_read_write_control)(struct mpc *mpc, const 
enum MCM_LUT_ID id,
                        bool lut_bank_a, bool enabled, int mpcc_id);
-               void (*program_lut_mode)(struct mpc *mpc, const enum 
MCM_LUT_XABLE xable,
-                       bool lut_bank_a, int mpcc_id);
-               void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int 
mpcc_id);
+               void (*program_lut_mode)(struct mpc *mpc,
+                       bool enable,
+                       bool lut_bank_a,
+                       int mpcc_id);
+               void (*program_3dlut_size)(struct mpc *mpc, const enum 
dc_cm_lut_size size, int mpcc_id);
                void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, 
uint16_t scale, int mpcc_id);
                void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, 
int mpcc_id);
                bool (*is_config_supported)(uint32_t width);
@@ -1152,6 +1167,8 @@ struct mpc_funcs {
                void (*power_on_shaper_3dlut)(struct mpc *mpc, uint32_t 
mpcc_id, bool power_on);
                void (*populate_lut)(struct mpc *mpc, const union 
mcm_lut_params params,
                        bool lut_bank_a, int mpcc_id);
+               void (*get_3dlut_mode)(struct mpc *mpc, int mpcc_id,
+                       bool *enable, bool *lut_bank_a);
        } rmcm;
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
index d8a4e604a34e..df92d8008fe6 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
@@ -73,56 +73,15 @@ void mpc401_set_movable_cm_location(struct mpc *mpc, enum 
mpcc_movable_cm_locati
        }
 }
 
-static enum dc_lut_mode get3dlut_config(
-                       struct mpc *mpc,
-                       bool *is_17x17x17,
-                       bool *is_12bits_color_channel,
-                       int mpcc_id)
-{
-       uint32_t i_mode, i_enable_10bits, lut_size;
-       enum dc_lut_mode mode;
-       struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
-
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
-                       MPCC_MCM_3DLUT_MODE_CURRENT,  &i_mode);
-
-       REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
-                       MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
-
-       switch (i_mode) {
-       case 0:
-               mode = LUT_BYPASS;
-               break;
-       case 1:
-               mode = LUT_RAM_A;
-               break;
-       case 2:
-               mode = LUT_RAM_B;
-               break;
-       default:
-               mode = LUT_BYPASS;
-               break;
-       }
-       if (i_enable_10bits > 0)
-               *is_12bits_color_channel = false;
-       else
-               *is_12bits_color_channel = true;
-
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
-
-       if (lut_size == 0)
-               *is_17x17x17 = true;
-       else
-               *is_17x17x17 = false;
-
-       return mode;
-}
-
-void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const 
union mcm_lut_params params, bool lut_bank_a, int mpcc_id)
+void mpc401_populate_lut(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const union mcm_lut_params *params,
+               const bool lut_bank_a,
+               const int mpcc_id)
 {
        const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
-       const struct pwl_params *lut1d = params.pwl;
-       const struct pwl_params *lut_shaper = params.pwl;
+       const struct pwl_params *lut1d = params->pwl;
+       const struct pwl_params *lut_shaper = params->pwl;
        bool is_17x17x17;
        bool is_12bits_color_channel;
        const struct dc_rgb *lut0;
@@ -131,7 +90,7 @@ void mpc401_populate_lut(struct mpc *mpc, const enum 
MCM_LUT_ID id, const union
        const struct dc_rgb *lut3;
        int lut_size0;
        int lut_size;
-       const struct tetrahedral_params *lut3d = params.lut3d;
+       const struct tetrahedral_params *lut3d = params->lut3d;
 
        switch (id) {
        case MCM_LUT_1DLUT:
@@ -174,8 +133,6 @@ void mpc401_populate_lut(struct mpc *mpc, const enum 
MCM_LUT_ID id, const union
 
                mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
 
-               get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, 
mpcc_id);
-
                is_17x17x17 = !lut3d->use_tetrahedral_9;
                is_12bits_color_channel = lut3d->use_12bits;
                if (is_17x17x17) {
@@ -198,8 +155,6 @@ void mpc401_populate_lut(struct mpc *mpc, const enum 
MCM_LUT_ID id, const union
                                        sizeof(lut3d->tetrahedral_9.lut1[0]);
                        }
 
-               mpc32_select_3dlut_ram(mpc, next_mode,
-                                       is_12bits_color_channel, mpcc_id);
                mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
                if (is_12bits_color_channel)
                        mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
@@ -232,46 +187,69 @@ void mpc401_populate_lut(struct mpc *mpc, const enum 
MCM_LUT_ID id, const union
 
 }
 
+static uint32_t mpc401_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size 
cm_size)
+{
+       uint32_t size = 0;
+
+       switch (cm_size) {
+       case CM_LUT_SIZE_999:
+               size = 1;
+               break;
+       case CM_LUT_SIZE_171717:
+               size = 0;
+               break;
+       default:
+               /* invalid LUT size */
+               ASSERT(false);
+               size = 0;
+               break;
+       }
+
+       return size;
+}
+
 void mpc401_program_lut_mode(
                struct mpc *mpc,
                const enum MCM_LUT_ID id,
-               const enum MCM_LUT_XABLE xable,
-               bool lut_bank_a,
-               int mpcc_id)
+               const bool enable,
+               const bool lut_bank_a,
+               const enum dc_cm_lut_size size,
+               const int mpcc_id)
 {
+       uint32_t lut_size;
        struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
 
        switch (id) {
        case MCM_LUT_3DLUT:
-               switch (xable) {
-               case MCM_LUT_DISABLE:
+               if (enable) {
+                       lut_size = mpc401_cm_lut_size_to_3dlut_size(size);
+                       REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
+                                       MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2,
+                                       MPCC_MCM_3DLUT_SIZE, lut_size);
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_shaper_3dlut(mpc, mpcc_id, 
false);
                        REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], 
MPCC_MCM_3DLUT_MODE, 0);
-                       break;
-               case MCM_LUT_ENABLE:
-                       REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], 
MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2);
-                       break;
                }
                break;
        case MCM_LUT_SHAPER:
-               switch (xable) {
-               case MCM_LUT_DISABLE:
-                       REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 
MPCC_MCM_SHAPER_LUT_MODE, 0);
-                       break;
-               case MCM_LUT_ENABLE:
+               if (enable) {
                        REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 
MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
-                       break;
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_shaper_3dlut(mpc, mpcc_id, 
false);
+                       REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 
MPCC_MCM_SHAPER_LUT_MODE, 0);
                }
                break;
        case MCM_LUT_1DLUT:
-               switch (xable) {
-               case MCM_LUT_DISABLE:
-                       REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
-                                       MPCC_MCM_1DLUT_MODE, 0);
-                       break;
-               case MCM_LUT_ENABLE:
+               if (enable) {
                        REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
                                        MPCC_MCM_1DLUT_MODE, 2);
-                       break;
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
+                       REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                                       MPCC_MCM_1DLUT_MODE, 0);
                }
                REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
                                MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
@@ -279,14 +257,20 @@ void mpc401_program_lut_mode(
        }
 }
 
-void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum 
MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
+void mpc401_program_lut_read_write_control(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const bool lut_bank_a,
+               const unsigned int bit_depth,
+               const int mpcc_id)
 {
        struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
 
        switch (id) {
        case MCM_LUT_3DLUT:
                mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
-               REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 
MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
+               REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+                               MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 
: 0,
+                               MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
                break;
        case MCM_LUT_SHAPER:
                mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
@@ -605,6 +589,44 @@ void mpc401_get_gamut_remap(struct mpc *mpc,
                        coef_format, ARRAY_SIZE(arr_reg_val));
 }
 
+void mpc401_get_lut_mode(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const int mpcc_id,
+               bool *enable,
+               bool *lut_bank_a)
+{
+       struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
+
+       uint32_t lut_mode = 0;
+       uint32_t lut_select = 0;
+
+       *enable = false;
+       *lut_bank_a = true;
+
+       switch (id) {
+       case MCM_LUT_SHAPER:
+               REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id],
+                               MPCC_MCM_SHAPER_MODE_CURRENT, &lut_mode);
+               *enable = lut_mode != 0;
+               *lut_bank_a = lut_mode != 2;
+               break;
+       case MCM_LUT_1DLUT:
+               REG_GET_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                               MPCC_MCM_1DLUT_MODE_CURRENT, &lut_mode,
+                               MPCC_MCM_1DLUT_SELECT_CURRENT, &lut_select);
+               *enable = lut_mode != 0;
+               *lut_bank_a = lut_mode == 0 || lut_select == 0;
+               break;
+       case MCM_LUT_3DLUT:
+       default:
+               REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
+                               MPCC_MCM_3DLUT_MODE_CURRENT, &lut_mode);
+               *enable = lut_mode != 0;
+               *lut_bank_a = lut_mode != 2;
+               break;
+       }
+}
+
 static const struct mpc_funcs dcn401_mpc_funcs = {
        .read_mpcc_state = mpc1_read_mpcc_state,
        .insert_plane = mpc1_insert_plane,
@@ -643,6 +665,7 @@ static const struct mpc_funcs dcn401_mpc_funcs = {
        .populate_lut = mpc401_populate_lut,
        .program_lut_read_write_control = mpc401_program_lut_read_write_control,
        .program_lut_mode = mpc401_program_lut_mode,
+       .get_lut_mode = mpc401_get_lut_mode,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
index 3d00d9497ed2..75fa05ed2b22 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
@@ -206,21 +206,32 @@ void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
        int num_rmu);
 
 void mpc401_set_movable_cm_location(struct mpc *mpc, enum 
mpcc_movable_cm_location location, int mpcc_id);
-void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const 
union mcm_lut_params params,
-               bool lut_bank_a, int mpcc_id);
+void mpc401_populate_lut(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const union mcm_lut_params *params,
+               bool lut_bank_a,
+               int mpcc_id);
 
 void mpc401_program_lut_mode(
                struct mpc *mpc,
                const enum MCM_LUT_ID id,
-               const enum MCM_LUT_XABLE xable,
-               bool lut_bank_a,
-               int mpcc_id);
+               const bool enable,
+               const bool lut_bank_a,
+               const enum dc_cm_lut_size size,
+               const int mpcc_id);
+
+void mpc401_get_lut_mode(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const int mpcc_id,
+               bool *enable,
+               bool *lut_bank_a);
 
 void mpc401_program_lut_read_write_control(
                struct mpc *mpc,
                const enum MCM_LUT_ID id,
-               bool lut_bank_a,
-               int mpcc_id);
+               const bool lut_bank_a,
+               const unsigned int bit_depth,
+               const int mpcc_id);
 
 void mpc401_set_gamut_remap(
        struct mpc *mpc,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
index 38c0e8f96d40..5a888e1e1cc5 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
@@ -63,154 +63,6 @@ void mpc42_update_blending(
        mpcc->blnd_cfg = *blnd_cfg;
 }
 
-/* Shaper functions */
-void mpc42_power_on_shaper_3dlut(
-       struct mpc *mpc,
-       uint32_t mpcc_id,
-       bool power_on)
-{
-       uint32_t power_status_shaper = 2;
-       uint32_t power_status_3dlut  = 2;
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-       int max_retries = 10;
-
-       REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
-               MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
-       REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
-               MPCC_MCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1:0);
-       /* wait for memory to fully power up */
-       if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
-               REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 
MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
-               REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 
MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
-       }
-
-       /*read status is not mandatory, it is just for debugging*/
-       REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 
&power_status_shaper);
-       REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 
&power_status_3dlut);
-
-       if (power_status_shaper != 0 && power_on == true)
-               BREAK_TO_DEBUGGER();
-
-       if (power_status_3dlut != 0 && power_on == true)
-               BREAK_TO_DEBUGGER();
-}
-
-void mpc42_configure_shaper_lut(
-       struct mpc *mpc,
-       bool is_ram_a,
-       uint32_t mpcc_id)
-{
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
-       REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
-               MPCC_MCM_SHAPER_SCALE_B, 0x7000);
-       REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
-               MPCC_MCM_SHAPER_SCALE_G, 0x7000);
-       REG_UPDATE(MPCC_MCM_SHAPER_SCALE_R[mpcc_id],
-               MPCC_MCM_SHAPER_SCALE_R, 0x7000);
-       REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
-                       MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
-       REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
-                       MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
-       REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, 
MPCC_MCM_SHAPER_LUT_INDEX, 0);
-}
-
-
-void mpc42_program_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
-{
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-       uint32_t size = 0xff;
-
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
-
-       REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE,
-               (width == 33) ? 2 :
-               (width == 17) ? 0 : 2);
-
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
-}
-
-void mpc42_program_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, 
uint16_t scale, int mpcc_id)
-{
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
-       REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_R[mpcc_id],
-               MPCC_MCM_3DLUT_OUT_OFFSET_R, bias,
-               MPCC_MCM_3DLUT_OUT_SCALE_R, scale);
-
-       REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_G[mpcc_id],
-               MPCC_MCM_3DLUT_OUT_OFFSET_G, bias,
-               MPCC_MCM_3DLUT_OUT_SCALE_G, scale);
-
-       REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_B[mpcc_id],
-               MPCC_MCM_3DLUT_OUT_OFFSET_B, bias,
-               MPCC_MCM_3DLUT_OUT_SCALE_B, scale);
-}
-
-void mpc42_program_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_id)
-{
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
-       REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 
MPCC_MCM_3DLUT_WRITE_EN_MASK, 0xF);
-
-       //program bit_depth
-       REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
-               MPCC_MCM_3DLUT_30BIT_EN,
-               (bit_depth == 10) ? 1 : 0);
-}
-
-bool mpc42_is_config_supported(uint32_t width)
-{
-       if (width == 17)
-               return true;
-
-       return false;
-}
-
-void mpc42_populate_lut(struct mpc *mpc, const union mcm_lut_params params,
-       bool lut_bank_a, int mpcc_id)
-{
-       const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
-       const struct pwl_params *lut_shaper = params.pwl;
-
-       if (lut_shaper == NULL)
-               return;
-       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
-               mpc42_power_on_shaper_3dlut(mpc, mpcc_id, true);
-
-       mpc42_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
-
-       if (next_mode == LUT_RAM_A)
-               mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id);
-       else
-               mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id);
-
-       mpc32_program_shaper_lut(
-                       mpc, lut_shaper->rgb_resulted, 
lut_shaper->hw_points_num, mpcc_id);
-
-       mpc42_power_on_shaper_3dlut(mpc, mpcc_id, false);
-}
-
-void mpc42_program_lut_read_write_control(struct mpc *mpc, const enum 
MCM_LUT_ID id,
-       bool lut_bank_a, bool enabled, int mpcc_id)
-{
-       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
-       switch (id) {
-       case MCM_LUT_3DLUT:
-               REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE,
-                       (!enabled) ? 0 :
-                       (lut_bank_a) ? 1 : 2);
-               REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 
MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
-               break;
-       case MCM_LUT_SHAPER:
-               mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
-               break;
-       default:
-               break;
-       }
-}
-
 /* RMCM Shaper functions */
 void mpc42_power_on_rmcm_shaper_3dlut(
        struct mpc *mpc,
@@ -674,32 +526,47 @@ void mpc42_program_rmcm_lut_read_write_control(struct mpc 
*mpc, const enum MCM_L
        }
 }
 
-void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
-       bool lut_bank_a, int mpcc_id)
+void mpc42_program_lut_mode(struct mpc *mpc,
+       bool enable,
+       bool lut_bank_a,
+       int mpcc_id)
 {
        struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
 
-       switch (xable) {
-       case MCM_LUT_DISABLE:
+       if (enable) {
+               REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], 
MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+       } else {
                REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], 
MPC_RMCM_SHAPER_LUT_MODE, 0);
+       }
+}
+
+static uint32_t mpc42_get_rmcm_3dlut_width(
+               const enum dc_cm_lut_size size)
+{
+       uint32_t width = 0;
+
+       switch (size) {
+       case CM_LUT_SIZE_333333:
+               width = 2;
                break;
-       case MCM_LUT_ENABLE:
-               REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], 
MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+       case CM_LUT_SIZE_171717:
+       default:
+               width = 0;
                break;
        }
+
+       return width;
 }
 
-void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int 
mpcc_id)
+void mpc42_program_rmcm_3dlut_size(struct mpc *mpc,
+               const enum dc_cm_lut_size size,
+               int mpcc_id)
 {
        struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-       uint32_t size = 0xff;
-
-       REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
-
-       REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE,
-               (width == 33) ? 2 : 0);
+       uint32_t width = mpc42_get_rmcm_3dlut_width(size);
 
-       REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
+       REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id],
+                       MPC_RMCM_3DLUT_SIZE, width);
 }
 
 void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t 
bias, uint16_t scale, int mpcc_id)
@@ -731,14 +598,6 @@ void mpc42_program_rmcm_bit_depth(struct mpc *mpc, 
uint16_t bit_depth, int mpcc_
                (bit_depth == 10) ? 1 : 0);
 }
 
-bool mpc42_is_rmcm_config_supported(uint32_t width)
-{
-       if (width == 17 || width == 33)
-               return true;
-
-       return false;
-}
-
 void mpc42_set_fl_config(
        struct mpc *mpc,
        struct mpc_fl_3dlut_config *cfg,
@@ -746,6 +605,7 @@ void mpc42_set_fl_config(
 {
        struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
 
+       uint32_t width = mpc42_get_rmcm_3dlut_width(cfg->size);
        /*
        From: Jie Zhou
 
@@ -786,7 +646,7 @@ void mpc42_set_fl_config(
 
        //width
        REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id],
-               MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0,
+               MPC_RMCM_3DLUT_SIZE, width,
                MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : 
(cfg->select_lut_bank_a) ? 1 : 2);
 
        //connect to hubp
@@ -799,181 +659,23 @@ void mpc42_set_fl_config(
        REG_UPDATE(MPC_RMCM_CNTL[mpcc_id], MPC_RMCM_CNTL, cfg->enabled ? 0 : 
0xF);
 }
 
-//static void rmcm_program_gamut_remap(
-//     struct mpc *mpc,
-//     unsigned int mpcc_id,
-//     const uint16_t *regval,
-//     enum mpcc_gamut_remap_id gamut_remap_block_id,
-//     enum mpcc_gamut_remap_mode_select mode_select)
-//{
-//     struct color_matrices_reg gamut_regs;
-//     struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-//
-//     if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
-//             gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
-//             gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
-//             mpc_program_gamut_remap(mpc, mpcc_id, regval, 
gamut_remap_block_id, mode_select);
-//             return;
-//     }
-//     if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP) {
-//
-//             if (regval == NULL || mode_select == 
MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-//                     REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0,
-//                             MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-//                     return;
-//             }
-//
-//             gamut_regs.shifts.csc_c11 = 
mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
-//             gamut_regs.masks.csc_c11 = 
mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
-//             gamut_regs.shifts.csc_c12 = 
mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
-//             gamut_regs.masks.csc_c12 = 
mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
-//
-//             switch (mode_select) {
-//             case MPCC_GAMUT_REMAP_MODE_SELECT_1:
-//                     gamut_regs.csc_c11_c12 = 
REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
-//                     gamut_regs.csc_c33_c34 = 
REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
-//                     break;
-//             case MPCC_GAMUT_REMAP_MODE_SELECT_2:
-//                     gamut_regs.csc_c11_c12 = 
REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
-//                     gamut_regs.csc_c33_c34 = 
REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
-//                     break;
-//             default:
-//                     break;
-//             }
-//
-//             cm_helper_program_color_matrices(
-//                     mpc->ctx,
-//                     regval,
-//                     &gamut_regs);
-//
-//             //select coefficient set to use, set A (MODE_1) or set B 
(MODE_2)
-//             REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, 
MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-//     }
-//}
-
-//static bool is_mpc_legacy_gamut_id(enum mpcc_gamut_remap_id 
gamut_remap_block_id)
-//{
-//     if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
-//             gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
-//             gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
-//             return true;
-//     }
-//     return false;
-//}
-//static void program_gamut_remap(
-//     struct mpc *mpc,
-//     unsigned int mpcc_id,
-//     const uint16_t *regval,
-//     enum mpcc_gamut_remap_id gamut_remap_block_id,
-//     enum mpcc_gamut_remap_mode_select mode_select)
-//{
-//     if (is_mpc_legacy_gamut_id(gamut_remap_block_id))
-//             mpc_program_gamut_remap(mpc, mpcc_id, regval, 
gamut_remap_block_id, mode_select);
-//     else
-//             rmcm_program_gamut_remap(mpc, mpcc_id, regval, 
gamut_remap_block_id, mode_select);
-//}
-
-//void mpc42_set_gamut_remap(
-//     struct mpc *mpc,
-//     int mpcc_id,
-//     const struct mpc_grph_gamut_adjustment *adjust)
-//{
-//     struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-//     unsigned int i = 0;
-//     uint32_t mode_select = 0;
-//
-//     if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
-//             /* Bypass / Disable if type is bypass or hw */
-//             program_gamut_remap(mpc, mpcc_id, NULL,
-//                     adjust->mpcc_gamut_remap_block_id, 
MPCC_GAMUT_REMAP_MODE_SELECT_0);
-//     } else {
-//             struct fixed31_32 arr_matrix[12];
-//             uint16_t arr_reg_val[12];
-//
-//             for (i = 0; i < 12; i++)
-//                     arr_matrix[i] = adjust->temperature_matrix[i];
-//
-//             convert_float_matrix(arr_reg_val, arr_matrix, 12);
-//
-//             if (is_mpc_legacy_gamut_id(adjust->mpcc_gamut_remap_block_id))
-//                     REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
-//                             MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
-//             else
-//                     REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id],
-//                             MPC_RMCM_GAMUT_REMAP_MODE_CURRENT, 
&mode_select);
-//
-//             //If current set in use not set A (MODE_1), then use set A, 
otherwise use set B
-//             if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
-//                     mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
-//             else
-//                     mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
-//
-//             program_gamut_remap(mpc, mpcc_id, arr_reg_val,
-//                     adjust->mpcc_gamut_remap_block_id, mode_select);
-//     }
-//}
-
-//static void read_gamut_remap(struct mpc *mpc,
-//     int mpcc_id,
-//     uint16_t *regval,
-//     enum mpcc_gamut_remap_id gamut_remap_block_id,
-//     uint32_t *mode_select)
-//{
-//     struct color_matrices_reg gamut_regs = {0};
-//     struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-//
-//     if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) {
-//             mpc_read_gamut_remap(mpc, mpcc_id, regval, 
gamut_remap_block_id, mode_select);
-//     }
-//     if (gamut_remap_block_id == MPCC_RMCM_GAMUT_REMAP) {
-//             //current coefficient set in use
-//             REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 
MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-//
-//             gamut_regs.shifts.csc_c11 = 
mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
-//             gamut_regs.masks.csc_c11 = 
mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
-//             gamut_regs.shifts.csc_c12 = 
mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
-//             gamut_regs.masks.csc_c12 = 
mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
-//
-//             switch (*mode_select) {
-//             case MPCC_GAMUT_REMAP_MODE_SELECT_1:
-//                     gamut_regs.csc_c11_c12 = 
REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
-//                     gamut_regs.csc_c33_c34 = 
REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
-//                     break;
-//             case MPCC_GAMUT_REMAP_MODE_SELECT_2:
-//                     gamut_regs.csc_c11_c12 = 
REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
-//                     gamut_regs.csc_c33_c34 = 
REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
-//                     break;
-//             default:
-//                     break;
-//             }
-//     }
-//
-//     if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-//             cm_helper_read_color_matrices(
-//                     mpc42->base.ctx,
-//                     regval,
-//                     &gamut_regs);
-//     }
-//}
-
-//void mpc42_get_gamut_remap(struct mpc *mpc,
-//     int mpcc_id,
-//     struct mpc_grph_gamut_adjustment *adjust)
-//{
-//     uint16_t arr_reg_val[12] = {0};
-//     uint32_t mode_select;
-//
-//     read_gamut_remap(mpc, mpcc_id, arr_reg_val, 
adjust->mpcc_gamut_remap_block_id, &mode_select);
-//
-//     if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-//             adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-//             return;
-//     }
-//
-//     adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-//     convert_hw_matrix(adjust->temperature_matrix,
-//             arr_reg_val, ARRAY_SIZE(arr_reg_val));
-//}
+void mpc42_get_rmcm_3dlut_mode(
+       struct mpc *mpc,
+       int mpcc_id,
+       bool *enable,
+       bool *lut_bank_a)
+{
+       struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+       uint32_t mode_current   = 0;
+
+       REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_MODE_CURRENT, 
&mode_current);
+
+       /* MPC_RMCM_3DLUT_MODE encoding:
+        *   0 -> disabled, 1 -> bank A, 2 -> bank B
+        */
+       *enable     = mode_current != 0;
+       *lut_bank_a = mode_current != 2;
+}
 
 void mpc42_read_mpcc_state(
                struct mpc *mpc,
@@ -1071,14 +773,7 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
        .populate_lut = mpc401_populate_lut,
        .program_lut_read_write_control = mpc401_program_lut_read_write_control,
        .program_lut_mode = mpc401_program_lut_mode,
-       .mcm = {
-               .program_lut_read_write_control = 
mpc42_program_lut_read_write_control,
-               .program_3dlut_size = mpc42_program_3dlut_size,
-               .program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
-               .program_bit_depth = mpc42_program_bit_depth,
-               .is_config_supported = mpc42_is_config_supported,
-               .populate_lut = mpc42_populate_lut,
-       },
+       .get_lut_mode = mpc401_get_lut_mode,
        .rmcm = {
                .enable_3dlut_fl = mpc42_enable_3dlut_fl,
                .update_3dlut_fast_load_select = 
mpc42_update_3dlut_fast_load_select,
@@ -1087,10 +782,10 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
                .program_3dlut_size = mpc42_program_rmcm_3dlut_size,
                .program_bias_scale = 
mpc42_program_rmcm_3dlut_fast_load_bias_scale,
                .program_bit_depth = mpc42_program_rmcm_bit_depth,
-               .is_config_supported = mpc42_is_rmcm_config_supported,
                .power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
                .populate_lut = mpc42_populate_rmcm_lut,
                .fl_3dlut_configure = mpc42_set_fl_config,
+               .get_3dlut_mode = mpc42_get_rmcm_3dlut_mode,
        },
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
index 12a12c28e553..af3b90af5396 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
@@ -884,49 +884,6 @@ void dcn42_mpc_construct(struct dcn42_mpc *mpc401,
 
 void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
 
-void mpc42_program_shaper_lutb_settings(
-       struct mpc *mpc,
-       const struct pwl_params *params,
-       uint32_t mpcc_id);
-void mpc42_program_shaper_luta_settings(
-               struct mpc *mpc,
-               const struct pwl_params *params,
-               uint32_t mpcc_id);
-void mpc42_configure_shaper_lut(
-               struct mpc *mpc,
-               bool is_ram_a,
-               uint32_t mpcc_id);
-void mpc42_power_on_shaper_3dlut(
-               struct mpc *mpc,
-               uint32_t mpcc_id,
-               bool power_on);
-void mpc42_program_3dlut_size(
-               struct mpc *mpc,
-               uint32_t width,
-               int mpcc_id);
-void mpc42_program_3dlut_fl_bias_scale(
-               struct mpc *mpc,
-               uint16_t bias,
-               uint16_t scale,
-               int mpcc_id);
-void mpc42_program_bit_depth(
-               struct mpc *mpc,
-               uint16_t bit_depth,
-               int mpcc_id);
-void mpc42_populate_lut(
-               struct mpc *mpc,
-               const union mcm_lut_params params,
-               bool lut_bank_a,
-               int mpcc_id);
-void mpc42_program_lut_read_write_control(
-               struct mpc *mpc,
-               const enum MCM_LUT_ID id,
-               bool lut_bank_a,
-               bool enabled,
-               int mpcc_id);
-
-bool mpc42_is_config_supported(uint32_t width);
-
 /* RMCM */
 void mpc42_program_rmcm_shaper_lut(
                struct mpc *mpc,
@@ -970,12 +927,12 @@ void mpc42_program_rmcm_lut_read_write_control(
                int mpcc_id);
 void mpc42_program_lut_mode(
                struct mpc *mpc,
-               const enum MCM_LUT_XABLE xable,
+               bool enable,
                bool lut_bank_a,
                int mpcc_id);
 void mpc42_program_rmcm_3dlut_size(
                struct mpc *mpc,
-               uint32_t width,
+               const enum dc_cm_lut_size size,
                int mpcc_id);
 void mpc42_program_rmcm_3dlut_fast_load_bias_scale(
                struct mpc *mpc,
@@ -987,13 +944,17 @@ void mpc42_program_rmcm_bit_depth(
                uint16_t bit_depth,
                int mpcc_id);
 
-bool mpc42_is_rmcm_config_supported(uint32_t width);
-
 void mpc42_set_fl_config(
        struct mpc *mpc,
        struct mpc_fl_3dlut_config *cfg,
        int mpcc_id);
 
+void mpc42_get_rmcm_3dlut_mode(
+       struct mpc *mpc,
+       int mpcc_id,
+       bool *enable,
+       bool *lut_bank_a);
+
 void mpc42_read_mpcc_state(
                struct mpc *mpc,
                int mpcc_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
index f8a878ead67d..2c0b92854a9c 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
@@ -139,165 +139,123 @@ void mpc60_program_rmcm_lut_read_write_control(struct 
mpc *mpc, const enum MCM_L
        }
 }
 
-void mpc60_select_3dlut_ram(
-       struct mpc *mpc,
-       enum dc_lut_mode mode,
-       bool is_color_channel_12bits,
-       uint32_t mpcc_id)
+static void mpc60_program_lut_read_write_control(struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const bool lut_bank_a,
+               const unsigned int bit_depth,
+               const int mpcc_id)
 {
-       (void)mode;
        struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
 
-       REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
-               MPCC_MCM_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0 : 
1);
+       switch (id) {
+       case MCM_LUT_3DLUT:
+               mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
+               REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+                               MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 
: 0);
+               break;
+       case MCM_LUT_SHAPER:
+               mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
+               break;
+       case MCM_LUT_1DLUT:
+               mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id);
+               break;
+       }
 }
 
-static enum dc_lut_mode get3dlut_config(
-       struct mpc *mpc,
-       bool *is_17x17x17,
-       bool *is_12bits_color_channel,
-       int mpcc_id)
+static uint32_t mpc60_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size 
cm_size)
 {
-       uint32_t i_mode, i_enable_10bits, lut_size;
-       enum dc_lut_mode mode;
-       struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
+       uint32_t size = 0;
 
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
-               MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
-
-       REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
-               MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
-
-       switch (i_mode) {
-       case 0:
-               mode = LUT_BYPASS;
-               break;
-       case 1:
-               mode = LUT_RAM_A;
+       switch (cm_size) {
+       case CM_LUT_SIZE_999:
+               size = 1;
                break;
-       case 2:
-               mode = LUT_RAM_B;
+       case CM_LUT_SIZE_171717:
+               size = 0;
                break;
        default:
-               mode = LUT_BYPASS;
+               /* invalid LUT size for MCM */
+               ASSERT(false);
+               size = 0;
                break;
        }
-       if (i_enable_10bits > 0)
-               *is_12bits_color_channel = false;
-       else
-               *is_12bits_color_channel = true;
-
-       REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
-
-       if (lut_size == 0)
-               *is_17x17x17 = true;
-       else
-               *is_17x17x17 = false;
-
-       return mode;
-}
-
-bool mpc60_program_3dlut(
-       struct mpc *mpc,
-       const struct tetrahedral_params *params,
-       int mpcc_id)
-{
-       enum dc_lut_mode mode;
-       bool is_17x17x17;
-       bool is_12bits_color_channel;
-       const struct dc_rgb *lut0;
-       const struct dc_rgb *lut1;
-       const struct dc_rgb *lut2;
-       const struct dc_rgb *lut3;
-       int lut_size0;
-       int lut_size;
-
-       if (params == NULL) {
-               mpc32_set_3dlut_mode(mpc, LUT_BYPASS, false, false, mpcc_id);
-               return false;
-       }
-       mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
-
-       mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, 
mpcc_id);
-
-       if (mode == LUT_BYPASS || mode == LUT_RAM_B)
-               mode = LUT_RAM_A;
-       else
-               mode = LUT_RAM_B;
-
-       is_17x17x17 = !params->use_tetrahedral_9;
-       is_12bits_color_channel = params->use_12bits;
-       if (is_17x17x17) {
-               lut0 = params->tetrahedral_17.lut0;
-               lut1 = params->tetrahedral_17.lut1;
-               lut2 = params->tetrahedral_17.lut2;
-               lut3 = params->tetrahedral_17.lut3;
-               lut_size0 = sizeof(params->tetrahedral_17.lut0) /
-                       sizeof(params->tetrahedral_17.lut0[0]);
-               lut_size = sizeof(params->tetrahedral_17.lut1) /
-                       sizeof(params->tetrahedral_17.lut1[0]);
-       } else {
-               lut0 = params->tetrahedral_9.lut0;
-               lut1 = params->tetrahedral_9.lut1;
-               lut2 = params->tetrahedral_9.lut2;
-               lut3 = params->tetrahedral_9.lut3;
-               lut_size0 = sizeof(params->tetrahedral_9.lut0) /
-                       sizeof(params->tetrahedral_9.lut0[0]);
-               lut_size = sizeof(params->tetrahedral_9.lut1) /
-                       sizeof(params->tetrahedral_9.lut1[0]);
-       }
 
-       mpc60_select_3dlut_ram(mpc, mode,
-                               is_12bits_color_channel, mpcc_id);
-       mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
-       if (is_12bits_color_channel)
-               mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
-       else
-               mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id);
-
-       mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id);
-       if (is_12bits_color_channel)
-               mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id);
-       else
-               mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id);
-
-       mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id);
-       if (is_12bits_color_channel)
-               mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id);
-       else
-               mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id);
-
-       mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id);
-       if (is_12bits_color_channel)
-               mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id);
-       else
-               mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id);
-
-       mpc32_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
-               is_17x17x17, mpcc_id);
-
-       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
-               mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
-
-       return true;
+       return size;
 }
 
-void mpc60_program_lut_read_write_control(struct mpc *mpc, const enum 
MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
+static void mpc60_program_lut_mode(
+               struct mpc *mpc,
+               const enum MCM_LUT_ID id,
+               const bool enable,
+               const bool lut_bank_a,
+               const enum dc_cm_lut_size size,
+               const int mpcc_id)
 {
+       uint32_t lut_size;
+       struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
 
        switch (id) {
        case MCM_LUT_3DLUT:
-               mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
+               if (enable) {
+                       lut_size = mpc60_cm_lut_size_to_3dlut_size(size);
+                       REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
+                                       MPCC_MCM_3DLUT_MODE, 1,
+                                       MPCC_MCM_3DLUT_SIZE, lut_size);
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_shaper_3dlut(mpc, mpcc_id, 
false);
+                       REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], 
MPCC_MCM_3DLUT_MODE, 0);
+               }
                break;
        case MCM_LUT_SHAPER:
-               mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
+               if (enable) {
+                       REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 
MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_shaper_3dlut(mpc, mpcc_id, 
false);
+                       REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 
MPCC_MCM_SHAPER_LUT_MODE, 0);
+               }
                break;
        case MCM_LUT_1DLUT:
-               mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id);
+               if (enable) {
+                       REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                                       MPCC_MCM_1DLUT_MODE, 2);
+               } else {
+                       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+                               mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
+                       REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                                       MPCC_MCM_1DLUT_MODE, 0);
+               }
+               REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                               MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
                break;
        }
 }
 
+static bool mpc60_program_3dlut(
+       struct mpc *mpc,
+       const struct tetrahedral_params *params,
+       int mpcc_id)
+{
+       union mcm_lut_params lut_params = { 0 };
+       lut_params.lut3d = params;
+
+       mpc60_program_lut_read_write_control(mpc,
+                       MCM_LUT_3DLUT,
+                       true,
+                       params->use_12bits ? 12 : 10,
+                       mpcc_id);
+       mpc401_populate_lut(mpc, MCM_LUT_3DLUT, &lut_params, true, mpcc_id);
+       mpc60_program_lut_mode(mpc,
+               MCM_LUT_3DLUT,
+               true,
+               true,
+               params->use_tetrahedral_9 ? CM_LUT_SIZE_999 : 
CM_LUT_SIZE_171717,
+               mpcc_id);
+
+       return true;
+}
+
 static const struct mpc_funcs dcn60_mpc_funcs = {
        .read_mpcc_state = mpc1_read_mpcc_state,
        .insert_plane = mpc60_insert_plane,
@@ -328,15 +286,8 @@ static const struct mpc_funcs dcn60_mpc_funcs = {
        .get_3dlut_fast_load_status = mpc401_get_3dlut_fast_load_status,
        .populate_lut = mpc401_populate_lut,
        .program_lut_read_write_control = mpc60_program_lut_read_write_control,
-       .program_lut_mode = mpc401_program_lut_mode,
-       .mcm = {
-               .program_lut_read_write_control = 
mpc42_program_lut_read_write_control,
-               .program_3dlut_size = mpc42_program_3dlut_size,
-               .program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
-               .program_bit_depth = mpc42_program_bit_depth,
-               .is_config_supported = mpc42_is_config_supported,
-               .populate_lut = mpc42_populate_lut,
-       },
+       .program_lut_mode = mpc60_program_lut_mode,
+       .get_lut_mode = mpc401_get_lut_mode,
        .rmcm = {
                .enable_3dlut_fl = mpc42_enable_3dlut_fl,
                .update_3dlut_fast_load_select = 
mpc42_update_3dlut_fast_load_select,
@@ -345,9 +296,9 @@ static const struct mpc_funcs dcn60_mpc_funcs = {
                .program_3dlut_size = mpc42_program_rmcm_3dlut_size,
                .program_bias_scale = 
mpc42_program_rmcm_3dlut_fast_load_bias_scale,
                .program_bit_depth = mpc42_program_rmcm_bit_depth,
-               .is_config_supported = mpc42_is_rmcm_config_supported,
                .power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
                .populate_lut = mpc42_populate_rmcm_lut,
+               .get_3dlut_mode = mpc42_get_rmcm_3dlut_mode,
        },
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
index 76d5c721f742..640a322d15c1 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
@@ -469,19 +469,4 @@ void mpc60_program_rmcm_lut_read_write_control(struct mpc 
*mpc,
        bool lut_bank_a,
        bool enabled,
        int mpcc_id);
-
-void mpc60_select_3dlut_ram(struct mpc *mpc,
-       enum dc_lut_mode mode,
-       bool is_color_channel_12bits,
-       uint32_t mpcc_id);
-
-bool mpc60_program_3dlut(struct mpc *mpc,
-       const struct tetrahedral_params *params,
-       int mpcc_id);
-
-void mpc60_program_lut_read_write_control(struct mpc *mpc,
-       const enum MCM_LUT_ID id,
-       bool lut_bank_a,
-       int mpcc_id);
-
 #endif /* DCN60_MPC_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
index 6296330e2450..6370d3903eb5 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
@@ -704,6 +704,7 @@ static const struct resource_caps res_cap_dcn42 = {
        .num_vmid = 16,
        .num_mpc_3dlut = 2,
        .num_dsc = 4,
+       .num_rmcm = 2,
 };
 
 static const struct dc_plane_cap plane_cap = {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
index b441d6d2d36b..4b7668abf4dc 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
@@ -584,6 +584,7 @@ static const struct resource_caps res_cap_dcn6_0 = {
        .num_mpc_3dlut = 4,
        .num_dsc = 4,
        .num_aux = 4,
+       .num_rmcm = 2,
 };
 
 static const struct dc_plane_cap plane_cap = {
-- 
2.34.1

Reply via email to