]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Fix Color Manager (3DLUT, Shaper, Blend)
authorDillon Varone <Dillon.Varone@amd.com>
Thu, 19 Mar 2026 15:57:08 +0000 (11:57 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 May 2026 13:56:52 +0000 (09:56 -0400)
[WHY & HOW]
The original refactor and fixes are causing regressions.
Revert them for now until they can be resolved

Fixes: e56e3cff2a1b ("drm/amd/display: Sync dcn42 with DC 3.2.373")
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
19 files changed:
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c

index 211d08ab1e9394bf1c4068f4ffbf579c7d726dd2..c7036e2c5c516dd84bb2c31b97570e345246aa41 100644 (file)
@@ -2961,27 +2961,16 @@ static struct surface_update_descriptor det_surface_update(
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
        }
 
-       if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
+       if (u->blend_tf || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
                update_flags->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->surface->cm.flags.bits.lut3d_enable)) {
+       if (u->lut3d_func || u->func_shaper) {
                update_flags->bits.lut_3d = 1;
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
        }
 
-       if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable &&
-                       u->cm->flags.bits.lut3d_enable && u->surface->cm.flags.bits.lut3d_enable) {
-               /* Toggling 3DLUT loading between DMA and Host is illegal */
-               BREAK_TO_DEBUGGER();
-       }
-
-       if (u->cm && u->cm->flags.bits.lut3d_enable && !u->cm->flags.bits.lut3d_dma_enable) {
-               /* Host loading 3DLUT requires full update but only stream lock  */
-               elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_STREAM);
-       }
-
        if (u->hdr_mult.value)
                if (u->hdr_mult.value != u->surface->hdr_mult.value) {
                        // TODO: Should be fast?
@@ -3000,6 +2989,20 @@ static struct surface_update_descriptor det_surface_update(
                update_flags->bits.cm_hist_change = 1;
                elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
        }
+       if (u->cm2_params) {
+               if (u->cm2_params->component_settings.shaper_3dlut_setting != u->surface->mcm_shaper_3dlut_setting
+                               || u->cm2_params->component_settings.lut1d_enable != u->surface->mcm_lut1d_enable
+                               || u->cm2_params->cm2_luts.lut3d_data.lut3d_src != u->surface->mcm_luts.lut3d_data.lut3d_src) {
+                       update_flags->bits.mcm_transfer_function_enable_change = 1;
+                       elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
+               }
+       }
+
+       if (update_flags->bits.lut_3d &&
+                       u->surface->mcm_luts.lut3d_data.lut3d_src != DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+               elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
+       }
+
        if (check_config->enable_legacy_fast_update &&
                        (update_flags->bits.gamma_change ||
                        update_flags->bits.gamut_remap_change ||
@@ -3311,12 +3314,24 @@ static void copy_surface_update_to_plane(
                        sizeof(struct dc_transfer_func_distributed_points));
        }
 
-       /* Shaper, 3DLUT, 1DLUT */
-       if (srf_update->cm) {
-               memcpy(&surface->cm, srf_update->cm,
-                               sizeof(surface->cm));
+       if (srf_update->cm2_params) {
+               surface->mcm_shaper_3dlut_setting = srf_update->cm2_params->component_settings.shaper_3dlut_setting;
+               surface->mcm_lut1d_enable = srf_update->cm2_params->component_settings.lut1d_enable;
+               surface->mcm_luts = srf_update->cm2_params->cm2_luts;
+       }
+
+       if (srf_update->func_shaper) {
+               memcpy(&surface->in_shaper_func, srf_update->func_shaper,
+               sizeof(surface->in_shaper_func));
+
+               if (surface->mcm_shaper_3dlut_setting >= DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER)
+                       surface->mcm_luts.shaper = &surface->in_shaper_func;
        }
 
+       if (srf_update->lut3d_func)
+               memcpy(&surface->lut3d_func, srf_update->lut3d_func,
+               sizeof(surface->lut3d_func));
+
        if (srf_update->hdr_mult.value)
                surface->hdr_mult =
                                srf_update->hdr_mult;
@@ -3325,6 +3340,17 @@ static void copy_surface_update_to_plane(
                surface->sdr_white_level_nits =
                                srf_update->sdr_white_level_nits;
 
+       if (srf_update->blend_tf) {
+               memcpy(&surface->blend_tf, srf_update->blend_tf,
+               sizeof(surface->blend_tf));
+
+               if (surface->mcm_lut1d_enable)
+                       surface->mcm_luts.lut1d_func = &surface->blend_tf;
+       }
+
+       if (srf_update->cm2_params || srf_update->blend_tf)
+               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;
@@ -4618,9 +4644,11 @@ static void commit_planes_for_stream(struct dc *dc,
                                if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
                                        continue;
 
-                               if (srf_updates[i].cm &&
-                                               srf_updates[i].cm->flags.bits.lut3d_enable &&
-                                               srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
+                               if (srf_updates[i].cm2_params &&
+                                               srf_updates[i].cm2_params->cm2_luts.lut3d_data.lut3d_src ==
+                                                               DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM &&
+                                               srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting ==
+                                                               DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT &&
                                                dc->hwss.trigger_3dlut_dma_load)
                                        dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx);
 
@@ -6864,7 +6892,7 @@ bool dc_capture_register_software_state(struct dc *dc, struct dc_register_softwa
                        struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 
                        /* MPCC blending tree and mode control - capture actual blend configuration */
-                       state->mpc.mpcc_mode[i] = (plane_state->cm.blend_func.type != TF_TYPE_BYPASS) ? 1 : 0;
+                       state->mpc.mpcc_mode[i] = (plane_state->blend_tf.type != TF_TYPE_BYPASS) ? 1 : 0;
                        state->mpc.mpcc_alpha_blend_mode[i] = plane_state->per_pixel_alpha ? 1 : 0;
                        state->mpc.mpcc_alpha_multiplied_mode[i] = plane_state->pre_multiplied_alpha ? 1 : 0;
                        state->mpc.mpcc_blnd_active_overlap_only[i] = 0; /* Default - no overlap restriction */
index 83a5e91062442753257bd30127ef0743af8ffbc8..9090935763ae4b2da923fd2a41e5779c7f4ba063 100644 (file)
@@ -39,7 +39,6 @@
 #include "abm.h"
 #include "dcn10/dcn10_hubbub.h"
 #include "dce/dmub_hw_lock_mgr.h"
-#include "custom_float.h"
 #include "link_service.h"
 
 #define MAX_NUM_MCACHE 8
index 16ff43b58e00c6532a0ea3bac9fcd56be163105d..5f84038714c0e2051d7b1c0b028ea048041a6c6b 100644 (file)
@@ -1002,6 +1002,7 @@ void dc_stream_release_3dlut_for_stream(
        if (rmcm_3dlut) {
                rmcm_3dlut->isInUse = false;
                rmcm_3dlut->stream  = NULL;
+               rmcm_3dlut->protection_bits = 0;
        }
 }
 
@@ -1013,6 +1014,7 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
        for (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;
        }
 }
 
index 86da619c3721a1aae09a008d66538f9daf31c034..ddaf4fee3b638d1131b544cb47d66820a3a836ac 100644 (file)
@@ -1407,50 +1407,15 @@ 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;
 };
-
-/* 3DLUT DMA (Fast Load) params */
-struct dc_3dlut_dma {
-       struct dc_plane_address addr;
-       enum dc_cm_lut_swizzle swizzle;
-       enum dc_cm_lut_pixel_format format;
-       uint16_t bias; /* FP1.5.10 */
-       uint16_t scale; /* FP1.5.10 */
-       enum dc_cm_lut_size size;
-};
-
-/* color manager */
-union dc_plane_cm_flags {
-       unsigned int all;
-       struct {
-               unsigned int shaper_enable    : 1;
-               unsigned int lut3d_enable     : 1;
-               unsigned int blend_enable     : 1;
-               /* whether legacy (lut3d_func) or DMA is valid */
-               unsigned int lut3d_dma_enable : 1;
-               /* RMCM lut to be used instead of MCM */
-               unsigned int rmcm_enable         : 1;
-               unsigned int reserved: 27;
-       } bits;
-};
-
-struct dc_plane_cm {
-       struct kref refcount;
-       struct dc_transfer_func shaper_func;
-       union {
-               struct dc_3dlut lut3d_func;
-               struct dc_3dlut_dma lut3d_dma;
-       };
-       struct dc_transfer_func blend_func;
-       union dc_plane_cm_flags flags;
-};
-
 /*
  * This structure is filled in by dc_surface_get_status and contains
  * the last requested address and the currently active address so the called
@@ -1532,18 +1497,14 @@ struct dc_plane_state {
        struct fixed31_32 hdr_mult;
        struct colorspace_transform gamut_remap_matrix;
 
+       // TODO: No longer used, remove
+       struct dc_hdr_static_metadata hdr_static_ctx;
+
        enum dc_color_space color_space;
 
-       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;
-       enum mpcc_movable_cm_location mcm_location;
-       struct dc_plane_cm cm;
 
        struct dc_transfer_func *gamcor_tf;
        enum surface_pixel_format format;
@@ -1580,6 +1541,11 @@ struct dc_plane_state {
 
        bool is_statically_allocated;
        enum chroma_cositing cositing;
+       enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
+       bool mcm_lut1d_enable;
+       struct dc_cm2_func_luts mcm_luts;
+       bool lut_bank_a;
+       enum mpcc_movable_cm_location mcm_location;
        struct dc_csc_transform cursor_csc_color_matrix;
        bool adaptive_sharpness_en;
        int adaptive_sharpness_policy;
@@ -1958,10 +1924,6 @@ struct dc_3dlut *dc_create_3dlut_func(void);
 void dc_3dlut_func_release(struct dc_3dlut *lut);
 void dc_3dlut_func_retain(struct dc_3dlut *lut);
 
-struct dc_plane_cm *dc_plane_cm_create(void);
-void dc_plane_cm_release(struct dc_plane_cm *cm);
-void dc_plane_cm_retain(struct dc_plane_cm *cm);
-
 void dc_post_update_surfaces_to_stream(
                struct dc *dc);
 
index 476db257d4ee1a940075e4259c43562b222ebccd..12ce4a059231985b8469386943a6fce481e56e47 100644 (file)
@@ -1523,28 +1523,4 @@ struct dc_validation_dpia_set {
        uint32_t required_bw;
 };
 
-enum dc_cm_lut_swizzle {
-       CM_LUT_3D_SWIZZLE_LINEAR_RGB,
-       CM_LUT_3D_SWIZZLE_LINEAR_BGR,
-       CM_LUT_1D_PACKED_LINEAR
-};
-
-enum dc_cm_lut_pixel_format {
-       CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB,
-       CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB,
-       CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB,
-       CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB,
-       CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10,
-       CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10
-};
-
-enum dc_cm_lut_size {
-       CM_LUT_SIZE_NONE,
-       CM_LUT_SIZE_999,
-       CM_LUT_SIZE_171717,
-       CM_LUT_SIZE_333333,
-       CM_LUT_SIZE_454545,
-       CM_LUT_SIZE_656565,
-};
-
 #endif /* DC_TYPES_H_ */
index 5a816442deee939907ed14435e2f9256ae4af37e..3c7a6569b692f992120e23b89029fe10352c941e 100644 (file)
        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,169 +72,96 @@ int hubp401_get_3dlut_fl_done(struct hubp *hubp)
        return ret;
 }
 
-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)
+void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode)
 {
-       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;
-       }
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
 }
 
-void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
-               const enum dc_cm_lut_pixel_format format)
+void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       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;
+       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width);
+}
 
-       hubp401_get_3dlut_fl_xbar_map(format,
-                       &bit_slice_y_g,
-                       &bit_slice_cb_b,
-                       &bit_slice_cr_r);
+void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits)
+{
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       REG_UPDATE_3(HUBP_3DLUT_CONTROL,
-                       HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
-                       HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b,
-                       HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
+       REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
 }
 
-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)
+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)
 {
-       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;
-       }
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       return width;
+       REG_UPDATE_3(HUBP_3DLUT_CONTROL,
+                       HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
+                       HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b,
+                       HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
 }
 
-static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format(
-               const enum dc_cm_lut_pixel_format dc_format)
+void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale)
 {
-       enum hubp_3dlut_fl_format hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
-
-       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;
-       }
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       return hubp_format;
+       REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale);
 }
 
-static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode(
-               const enum dc_cm_lut_swizzle swizzle)
+void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode)
 {
-       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;
-       }
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       return addr_mode;
+       REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
 }
 
-static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode(
-               const enum dc_cm_lut_swizzle swizzle)
+void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format)
 {
-       enum hubp_3dlut_fl_mode mode;
-
-       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;
-       }
+       struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-       return mode;
+       REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
 }
 
-void hubp401_program_3dlut_fl_config(struct hubp *hubp,
-               const struct dc_3dlut_dma *config)
+void hubp401_program_3dlut_fl_config(
+       struct hubp *hubp,
+       struct hubp_fl_3dlut_config *cfg)
 {
        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);
+       uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
+       uint32_t width = {cfg->width};
+
+       if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR)
+               width = (cfg->width == 17) ? 4916 : 35940;
 
        REG_UPDATE_2(_3DLUT_FL_CONFIG,
-                       HUBP0_3DLUT_FL_MODE, mode,
-                       HUBP0_3DLUT_FL_FORMAT, format);
+               HUBP0_3DLUT_FL_MODE, cfg->mode,
+               HUBP0_3DLUT_FL_FORMAT, cfg->format);
 
        REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
-                       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);
+               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);
 }
 
 void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
@@ -1135,13 +1062,19 @@ 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
 };
 
index 043948f64b862ebb13f90464f8951f35827c7bbf..4570b8016de5a9953511d449c59b16bf7b9fff85 100644 (file)
@@ -328,17 +328,32 @@ int 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,
-               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);
+
+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);
 
 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_config(struct hubp *hubp,
-               const struct dc_3dlut_dma *config);
+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_clear_tiling(struct hubp *hubp);
 
index ad6badcceb12a4c0b3cb1de93b27637c534f7d0d..e4602c3ddc66246c686dad4d15594d3e8ac3033a 100644 (file)
@@ -311,84 +311,19 @@ 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,
-               const enum dc_cm_lut_pixel_format format)
+       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)
 {
        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,
@@ -670,10 +605,15 @@ 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,
index 88bb1337ab9d62a5ab021f8cf8f89710b9e19073..f0e614136228c575d5e5e3e8110baca7b2fdd538 100644 (file)
@@ -58,11 +58,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,
-               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_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_read_state(struct hubp *hubp);
 
index 828f0198011575738d04802e57312a747f98dfe7..237a19a27ce1a38e3ae3156ac2fa9fb2721d1926 100644 (file)
@@ -95,6 +95,10 @@ void dcn401_program_gamut_remap(struct pipe_ctx *pipe_ctx)
        unsigned int mpcc_id = pipe_ctx->plane_res.mpcc_inst;
        struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
 
+       //For now assert if location is not pre-blend
+       if (pipe_ctx->plane_state)
+               ASSERT(pipe_ctx->plane_state->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;
@@ -374,180 +378,300 @@ void dcn401_init_hw(struct dc *dc)
        }
 }
 
-void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
+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)dc;
-       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
+       bool lut1d_enable = false;
+       struct mpc *mpc = dc->res_pool->mpc;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
 
-       if (hubp->funcs->hubp_enable_3dlut_fl) {
-               hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+       if (!pipe_ctx->plane_state)
+               return;
+       shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
+       lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
+       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 = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+
+       switch (shaper_3dlut_setting) {
+       case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
+               *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
+               break;
+       case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
+               *lut3d_xable = MCM_LUT_DISABLE;
+               *shaper_xable = MCM_LUT_ENABLE;
+               break;
+       case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
+               *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
+               break;
        }
 }
 
-bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
-                               const struct dc_plane_state *plane_state)
+void dcn401_populate_mcm_luts(struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               struct dc_cm2_func_luts mcm_luts,
+               bool lut_bank_a)
 {
-       struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
        struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
        struct hubp *hubp = pipe_ctx->plane_res.hubp;
-       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;
-       struct dc_3dlut_dma lut3d_dma;
-       bool lut_enable;
-       bool lut_bank_a;
+       enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
+       enum hubp_3dlut_fl_format format = 0;
+       enum hubp_3dlut_fl_mode mode;
+       enum hubp_3dlut_fl_width width = 0;
+       enum hubp_3dlut_fl_addressing_mode addr_mode;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
+       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;
-       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);
-       }
-
-       /* 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);
+       dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
 
        /* 1D LUT */
-       lut_enable = cm->flags.bits.blend_enable;
-       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(plane_state->ctx,
-                                       &cm->blend_func,
-                                       &dpp_base->regamma_params,
-                                       false);
+       if (mcm_luts.lut1d_func) {
+               memset(&m_lut_params, 0, sizeof(m_lut_params));
+               if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
+                       m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
+               else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                                       mcm_luts.lut1d_func,
+                                       &dpp_base->regamma_params, false);
                        m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
                }
-
-               if (!m_lut_params.pwl) {
-                       lut_enable = false;
+               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);
                }
-       } else {
-               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);
        }
 
-       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 */
-       lut_enable = cm->flags.bits.shaper_enable;
-       if (lut_enable) {
+       if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_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) {
+               if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
+                       m_lut_params.pwl = &mcm_luts.shaper->pwl;
+               else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
                        ASSERT(false);
-                       rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                       &cm->shaper_func,
-                                       &dpp_base->shaper_params,
-                                       true);
-                       m_lut_params.pwl = rval ? &dpp_base->shaper_params : NULL;
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                                       mcm_luts.shaper,
+                                       &dpp_base->regamma_params, true);
+                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
                }
-               if (!m_lut_params.pwl) {
-                       lut_enable = false;
+               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);
                }
-       } else {
-               lut_enable = false;
        }
 
-       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);
+       /* 3DLUT */
+       switch (lut3d_src) {
+       case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+               memset(&m_lut_params, 0, sizeof(m_lut_params));
+               if (hubp->funcs->hubp_enable_3dlut_fl)
+                       hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
 
-       /* 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 (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
+                       m_lut_params.lut3d = &mcm_luts.lut3d_data.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);
+               }
+               break;
+       case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+               switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
+#if defined(CONFIG_DRM_AMD_DC_DCN4_2)
+               case DC_CM2_GPU_MEM_SIZE_333333:
+                       if (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33)
+                               width = hubp_3dlut_fl_width_33;
+                       break;
+#endif
+               case DC_CM2_GPU_MEM_SIZE_171717:
+                       width = hubp_3dlut_fl_width_17;
+                       break;
+               case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
+                       width = hubp_3dlut_fl_width_transformed;
+                       break;
+               default:
+                       //TODO: handle default case
+                       break;
+               }
 
-       /* 3DLUT */
-       lut_enable = cm->flags.bits.lut3d_enable;
-       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, lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id);
+               //check for support
+               if (mpc->funcs->mcm.is_config_supported &&
+                       !mpc->funcs->mcm.is_config_supported(width))
+                       break;
 
-               /* 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);
+                       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 (mpc->funcs->update_3dlut_fast_load_select)
-                       mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
+               if (hubp->funcs->hubp_program_3dlut_fl_addr)
+                       hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr);
 
-               /* HUBP */
-               if (hubp->funcs->hubp_program_3dlut_fl_config)
-                       hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
+               if (mpc->funcs->mcm.program_bit_depth)
+                       mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
 
-               if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
-                       hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format);
+               switch (mcm_luts.lut3d_data.gpu_mem_params.layout) {
+               case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+                       mode = hubp_3dlut_fl_mode_native_1;
+                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+                       break;
+               case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+                       mode = hubp_3dlut_fl_mode_native_2;
+                       addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+                       break;
+               case DC_CM2_GPU_MEM_LAYOUT_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_addr)
-                       hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
+               if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
+                       hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
 
-               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;
+               switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
+               case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+                       format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+                       break;
+               case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+                       format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+                       break;
+               case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+                       format = hubp_3dlut_fl_format_float_fp1_5_10;
+                       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,
+                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
+                               mpcc_id);
+                       hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
+                                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+                                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
                }
-       } else {
-               /* Legacy (Host) Load Mode */
-               memset(&m_lut_params, 0, sizeof(m_lut_params));
 
-               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;
+               //navi 4x has a bug and r and blue are swapped and need to be worked around here in
+               //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
+               switch (mcm_luts.lut3d_data.gpu_mem_params.component_order) {
+               case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
+               default:
+                       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;
+                       break;
                }
 
-               /* 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_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->update_3dlut_fast_load_select)
-                               mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 0xf);
+               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->populate_lut)
-                               mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, &m_lut_params, lut_bank_a, mpcc_id);
-               }
+               if (mpc->funcs->mcm.program_3dlut_size)
+                       mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
 
-               /* 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);
+                       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);
+                       }
+               }
+               break;
+
+       }
+}
+
+void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       (void)dc;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+
+       if (hubp->funcs->hubp_enable_3dlut_fl) {
+               hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+       }
+}
+
+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 (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+               dcn401_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, 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->blend_tf.type == TF_TYPE_HWPWL)
+               lut_params = &plane_state->blend_tf.pwl;
+       else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                              &plane_state->blend_tf,
+                                                              &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->in_shaper_func.type == TF_TYPE_HWPWL)
+               lut_params = &plane_state->in_shaper_func.pwl;
+       else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+               // TODO: dpp_base replace
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                              &plane_state->in_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->lut3d_func.state.bits.initialized == 1)
+                       result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
+               else
+                       result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
        }
 
        return result;
@@ -1828,9 +1952,10 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
 
        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) {
+                       if (mpc_pipe->plane_state && mpc_pipe->plane_state->mcm_luts.lut3d_data.lut3d_src
+                                               == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM
+                                       && mpc_pipe->plane_state->mcm_shaper_3dlut_setting
+                                               == DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT) {
                                wa_pipes[wa_pipe_ct++] = mpc_pipe;
                        }
                }
index 3c28a840c17cfd6ae63f0b4615771175cae4d619..f63162453e9b541f1c4c5ecd3dda9e0570189181 100644 (file)
@@ -393,6 +393,68 @@ void dcn42_program_cm_hist(
                        plane_state->cm_hist_control, plane_state->color_space);
 }
 
+static void dc_get_lut_xbar(
+       enum dc_cm2_gpu_mem_pixel_component_order order,
+       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)
+{
+       switch (order) {
+       case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
+               *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;
+               break;
+       case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA:
+               *cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+               *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+               *cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+               break;
+       }
+}
+
+static void dc_get_lut_mode(
+       enum dc_cm2_gpu_mem_layout layout,
+       enum hubp_3dlut_fl_mode *mode,
+       enum hubp_3dlut_fl_addressing_mode *addr_mode)
+{
+       switch (layout) {
+       case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+               *mode = hubp_3dlut_fl_mode_native_1;
+               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+               break;
+       case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+               *mode = hubp_3dlut_fl_mode_native_2;
+               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+               break;
+       case DC_CM2_GPU_MEM_LAYOUT_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_cm2_gpu_mem_format dc_format,
+       enum hubp_3dlut_fl_format *format)
+{
+       switch (dc_format) {
+       case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+               *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+               break;
+       case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+               *format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+               break;
+       case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+               *format = hubp_3dlut_fl_format_float_fp1_5_10;
+               break;
+       }
+}
+
 static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
 {
        if (mpc->funcs->rmcm.power_on_shaper_3dlut &&
@@ -403,17 +465,119 @@ 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, enum dc_cm2_gpu_mem_size size)
+{
+       if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut)
+               return false;
+       if (size == DC_CM2_GPU_MEM_SIZE_171717)
+               return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17);
+       else if (size == DC_CM2_GPU_MEM_SIZE_333333)
+               return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33);
+       return false;
+}
+
+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)
+{
+       enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
+       bool lut1d_enable = false;
+       struct mpc *mpc = dc->res_pool->mpc;
+       int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+
+       if (!pipe_ctx->plane_state)
+               return;
+       shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
+       lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
+       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 = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+
+       switch (shaper_3dlut_setting) {
+       case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
+               *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
+               break;
+       case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
+               *lut3d_xable = MCM_LUT_DISABLE;
+               *shaper_xable = MCM_LUT_ENABLE;
+               break;
+       case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
+               *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
+               break;
+       }
+}
+
+static void fl_get_lut_mode(
+       enum dc_cm2_gpu_mem_layout layout,
+       enum dc_cm2_gpu_mem_size   size,
+       enum hubp_3dlut_fl_mode *mode,
+       enum hubp_3dlut_fl_addressing_mode *addr_mode,
+       enum hubp_3dlut_fl_width *width)
+{
+       *width = hubp_3dlut_fl_width_17;
+
+       if (size == DC_CM2_GPU_MEM_SIZE_333333)
+               *width = hubp_3dlut_fl_width_33;
+
+       switch (layout) {
+       case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
+               *mode = hubp_3dlut_fl_mode_native_1;
+               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+               break;
+       case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
+               *mode = hubp_3dlut_fl_mode_native_2;
+               *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+               break;
+       case DC_CM2_GPU_MEM_LAYOUT_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,
+       enum dc_cm2_transfer_func_source lut3d_src,
+       struct dc_cm2_func_luts *mcm_luts,
        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;
@@ -421,23 +585,25 @@ 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_bank_a = true; // TODO get from HW
-
        //check to see current pipe is part of a stream with allocated rmcm 3dlut
        if (!rmcm_3dlut)
                return false;
 
+       rmcm_3dlut->protection_bits = mcm_luts->lut3d_data.rmcm_tmz;
+
+       dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
+
        /* Shaper */
-       if (cm->flags.bits.shaper_enable) {
+       if (mcm_luts->shaper) {
                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) {
+               if (mcm_luts->shaper->type == TF_TYPE_HWPWL) {
+                       m_lut_params.pwl = &mcm_luts->shaper->pwl;
+               } else if (mcm_luts->shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
                        ASSERT(false);
                        cm_helper_translate_curve_to_hw_format(
                                        dc->ctx,
-                                       &cm->shaper_func,
+                                       mcm_luts->shaper,
                                        &dpp_base->shaper_params, true);
                        m_lut_params.pwl = &dpp_base->shaper_params;
                }
@@ -453,21 +619,58 @@ bool dcn42_program_rmcm_luts(
        }
 
        /* 3DLUT */
-       if (!cm->flags.bits.lut3d_dma_enable) {
+       switch (lut3d_src) {
+       case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
                memset(&m_lut_params, 0, sizeof(m_lut_params));
                // Don't know what to do in this case.
-       } else {
-               if (!dc_is_rmcm_3dlut_supported(hubp, mpc))
+               //case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+               break;
+       case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+               fl_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout,
+                               mcm_luts->lut3d_data.gpu_mem_params.size,
+                               &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))
                        return false;
 
+               // setting native or transformed mode,
+               dc_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
+
                //seems to be only for the MCM
-               mpc_fl_config.enabled                   = cm->flags.bits.lut3d_enable;
-               mpc_fl_config.size                  = cm->lut3d_dma.size;
+               dc_get_lut_format(mcm_luts->lut3d_data.gpu_mem_params.format_params.format, &format);
+
+               dc_get_lut_xbar(
+                       mcm_luts->lut3d_data.gpu_mem_params.component_order,
+                       &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                               = mcm_luts->lut3d_data.gpu_mem_params.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                = mcm_luts->lut3d_data.gpu_mem_params.layout;
+               fl_config.bias  = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
+               fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
+
+               mpc_fl_config.enabled                   = fl_config.enabled;
+               mpc_fl_config.width                 = width;
                mpc_fl_config.select_lut_bank_a = lut_bank_a;
-               mpc_fl_config.bit_depth             = 0;
+               mpc_fl_config.bit_depth             = mcm_luts->lut3d_data.gpu_mem_params.bit_depth;
                mpc_fl_config.hubp_index                = hubp->inst;
-               mpc_fl_config.bias      = cm->lut3d_dma.bias;
-               mpc_fl_config.scale     = cm->lut3d_dma.scale;
+               mpc_fl_config.bias      = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
+               mpc_fl_config.scale     = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
 
                //1. power down the block
                mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, false);
@@ -475,44 +678,268 @@ bool dcn42_program_rmcm_luts(
                //2. program RMCM - 3dlut reg programming
                mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, mpcc_id);
 
-               /* 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);
+               hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config);
 
                //3. power on the block
                mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true);
+
+               break;
+       default:
+               return false;
        }
 
        return true;
 }
 
-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,
+               struct dc_cm2_func_luts mcm_luts,
+               bool lut_bank_a)
 {
-       struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+       struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
        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;
-       bool result;
-
-       /* MCM */
-       result = dcn401_set_mcm_luts(pipe_ctx, plane_state);
-
-       /* RMCM */
-       if (cm->flags.bits.rmcm_enable && cm->flags.bits.lut3d_dma_enable) {
-               /* TODO - move RMCM to its own block */
+       struct mpc *mpc = dc->res_pool->mpc;
+       union mcm_lut_params m_lut_params;
+       enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
+       enum hubp_3dlut_fl_format format = 0;
+       enum hubp_3dlut_fl_mode mode;
+       enum hubp_3dlut_fl_width width = 0;
+       enum hubp_3dlut_fl_addressing_mode addr_mode;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
+       enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
+       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
+       //set to post blend (true)
+       dcn42_set_mcm_location_post_blend(
+               dc,
+               pipe_ctx,
+               mcm_luts.lut3d_data.mpc_mcm_post_blend);
+
+       //RMCM - 3dLUT+Shaper
+       if (mcm_luts.lut3d_data.rmcm_3dlut_enable &&
+               is_rmcm_3dlut_fl_supported(dc, mcm_luts.lut3d_data.gpu_mem_params.size)) {
                dcn42_program_rmcm_luts(
                        hubp,
                        pipe_ctx,
-                       cm,
+                       lut3d_src,
+                       &mcm_luts,
                        mpc,
+                       lut_bank_a,
                        mpcc_id);
        }
 
+       /* 1D LUT */
+       if (mcm_luts.lut1d_func) {
+               memset(&m_lut_params, 0, sizeof(m_lut_params));
+               if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
+                       m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
+               else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                                       mcm_luts.lut1d_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 (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) {
+               memset(&m_lut_params, 0, sizeof(m_lut_params));
+               if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
+                       m_lut_params.pwl = &mcm_luts.shaper->pwl;
+               else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
+                       ASSERT(false);
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+                                       mcm_luts.shaper,
+                                       &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 */
+       switch (lut3d_src) {
+       case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
+               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 (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
+                       m_lut_params.lut3d = &mcm_luts.lut3d_data.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);
+               }
+               break;
+       case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
+               switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
+               case DC_CM2_GPU_MEM_SIZE_333333:
+                       width = hubp_3dlut_fl_width_33;
+                       break;
+               case DC_CM2_GPU_MEM_SIZE_171717:
+                       width = hubp_3dlut_fl_width_17;
+                       break;
+               case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
+                       width = hubp_3dlut_fl_width_transformed;
+                       break;
+               default:
+                       //TODO: Handle default case
+                       break;
+               }
+
+               //check for support
+               if (mpc->funcs->mcm.is_config_supported &&
+                       !mpc->funcs->mcm.is_config_supported(width))
+                       break;
+
+               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, mcm_luts.lut3d_data.gpu_mem_params.addr);
+
+               if (mpc->funcs->mcm.program_bit_depth)
+                       mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
+
+               dc_get_lut_mode(mcm_luts.lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
+               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 (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
+               case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
+                       format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+                       break;
+               case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
+                       format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+                       break;
+               case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
+                       format = hubp_3dlut_fl_format_float_fp1_5_10;
+                       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,
+                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
+                               mpcc_id);
+                       hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
+                                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
+                                               mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
+               }
+
+               //navi 4x has a bug and r and blue are swapped and need to be worked around here in
+               //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
+               dc_get_lut_xbar(
+                       mcm_luts.lut3d_data.gpu_mem_params.component_order,
+                       &crossbar_bit_slice_cr_r,
+                       &crossbar_bit_slice_y_g,
+                       &crossbar_bit_slice_cb_b);
+
+               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);
+                       }
+               }
+               break;
+       }
+}
+
+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->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
+               dcn42_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, 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->blend_tf.type == TF_TYPE_HWPWL)
+               lut_params = &plane_state->blend_tf.pwl;
+       else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                               &plane_state->blend_tf,
+                               &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->in_shaper_func.type == TF_TYPE_HWPWL)
+               lut_params = &plane_state->in_shaper_func.pwl;
+       else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
+               // TODO: dpp_base replace
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                               &plane_state->in_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->lut3d_func.state.bits.initialized == 1)
+                       result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
+               else
+                       result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+       }
+
        return result;
 }
 void dcn42_hardware_release(struct dc *dc)
index c4cfeed45b1905bcea1a3218262a3f63ae899f48..0539ee0ffaee380a74300761c92e3e790124d30f 100644 (file)
@@ -18,11 +18,18 @@ 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,
+               struct dc_cm2_func_luts mcm_luts,
+               bool lut_bank_a);
+
 bool dcn42_program_rmcm_luts(
        struct hubp *hubp,
        struct pipe_ctx *pipe_ctx,
-       const struct dc_plane_cm *cm,
+       enum dc_cm2_transfer_func_source lut3d_src,
+       struct dc_cm2_func_luts *mcm_luts,
        struct mpc *mpc,
+       bool lut_bank_a,
        int mpcc_id);
 void dcn42_hardware_release(struct dc *dc);
 
index 71f6c5350e5ede6c2b3da3d37ee2b7c11b110ab7..0530b214c4b6d51d18385b0065f0fda28f36d79b 100644 (file)
@@ -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_17_transformed    = 4916, //mpc default
+       hubp_3dlut_fl_width_transformed    = 4916, //mpc default
 };
 
 enum hubp_3dlut_fl_crossbar_bit_slice {
@@ -99,6 +99,22 @@ 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_cm2_gpu_mem_layout 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;
@@ -273,15 +289,24 @@ 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);
-       void (*hubp_program_3dlut_fl_config)(struct hubp *hubp,
-               const struct dc_3dlut_dma *config);
+               const struct dc_plane_address address);
        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 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);
        int (*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);
index f5617674bea8ef85832edd1237186dcd5b3c3e3d..54eb2eba68bf43470b425e4804ac9d1bf0c5e040 100644 (file)
@@ -54,7 +54,6 @@
 #include "dc_hw_types.h"
 #include "hw_shared.h"
 #include "transform.h"
-#include "dc_types.h"
 
 #define MAX_MPCC 6
 #define MAX_OPP 6
@@ -102,6 +101,13 @@ 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,
@@ -110,7 +116,7 @@ enum MCM_LUT_ID {
 
 struct mpc_fl_3dlut_config {
        bool enabled;
-       enum dc_cm_lut_size size;
+       uint16_t width;
        bool select_lut_bank_a;
        uint16_t bit_depth;
        int hubp_index;
@@ -1069,11 +1075,8 @@ struct mpc_funcs {
        *
        * void
        */
-       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);
+       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);
 
        /**
        * @program_lut_read_write_control:
@@ -1084,18 +1087,13 @@ 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,
-               const bool lut_bank_a,
-               const unsigned int bit_depth,
-               const int mpcc_id);
+       void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
 
        /**
        * @program_lut_mode:
@@ -1105,44 +1103,33 @@ struct mpc_funcs {
        * Parameters:
        * - [in/out] mpc - MPC context.
        * - [in] id
-       * - [in] enable
+       * - [in] xable
        * - [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 bool enable,
-                       const bool lut_bank_a,
-                       const enum dc_cm_lut_size size,
-                       const int mpcc_id);
-
+       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);
 
        /**
-       * @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);
+        * @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;
 
        /**
         * @rmcm:
@@ -1155,11 +1142,9 @@ 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,
-                       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_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_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);
index e0617db2d0c1ded44021c14249c0b29860fd309c..ce1ee2062e41d240513258002c8359f2802b32a2 100644 (file)
@@ -73,15 +73,56 @@ void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_locati
        }
 }
 
-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)
+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)
 {
        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;
@@ -90,7 +131,7 @@ void mpc401_populate_lut(struct mpc *mpc,
        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:
@@ -133,6 +174,8 @@ void mpc401_populate_lut(struct mpc *mpc,
 
                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) {
@@ -155,6 +198,8 @@ void mpc401_populate_lut(struct mpc *mpc,
                                        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);
@@ -187,69 +232,46 @@ void mpc401_populate_lut(struct mpc *mpc,
 
 }
 
-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 bool enable,
-               const bool lut_bank_a,
-               const enum dc_cm_lut_size size,
-               const int mpcc_id)
+               const enum MCM_LUT_XABLE xable,
+               bool lut_bank_a,
+               int mpcc_id)
 {
-       uint32_t lut_size;
        struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
 
        switch (id) {
        case MCM_LUT_3DLUT:
-               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);
+               switch (xable) {
+               case MCM_LUT_DISABLE:
                        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:
-               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);
+               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:
+                       REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+                       break;
                }
                break;
        case MCM_LUT_1DLUT:
-               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);
+               switch (xable) {
+               case MCM_LUT_DISABLE:
                        REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
                                        MPCC_MCM_1DLUT_MODE, 0);
+                       break;
+               case MCM_LUT_ENABLE:
+                       REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+                                       MPCC_MCM_1DLUT_MODE, 2);
+                       break;
                }
                REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
                                MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
@@ -257,20 +279,14 @@ void mpc401_program_lut_mode(
        }
 }
 
-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)
+void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, 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_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);
+               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);
@@ -562,44 +578,6 @@ void mpc401_get_gamut_remap(struct mpc *mpc,
                arr_reg_val, 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,
@@ -638,7 +616,6 @@ 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,
 };
 
 
index c16560c84453e4910701ea922be89b0b7b54f2cf..6d842d7b95c7e4258cb39722368cb3c83db12f4c 100644 (file)
@@ -206,32 +206,21 @@ 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 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);
+               const enum MCM_LUT_XABLE xable,
+               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);
+               bool lut_bank_a,
+               int mpcc_id);
 
 void mpc401_set_gamut_remap(
        struct mpc *mpc,
index 507dbdbea60084464089c57b44329edf072a06de..38c0e8f96d40e4f3f10a0331c845f3431238087e 100644 (file)
@@ -63,6 +63,154 @@ 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,
@@ -526,47 +674,32 @@ void mpc42_program_rmcm_lut_read_write_control(struct mpc *mpc, const enum MCM_L
        }
 }
 
-void mpc42_program_lut_mode(struct mpc *mpc,
-       bool enable,
-       bool lut_bank_a,
-       int mpcc_id)
+void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
+       bool lut_bank_a, int mpcc_id)
 {
        struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
 
-       if (enable) {
-               REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
-       } else {
+       switch (xable) {
+       case MCM_LUT_DISABLE:
                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 CM_LUT_SIZE_171717:
-       default:
-               width = 0;
+       case MCM_LUT_ENABLE:
+               REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
                break;
        }
-
-       return width;
 }
 
-void mpc42_program_rmcm_3dlut_size(struct mpc *mpc,
-               const enum dc_cm_lut_size size,
-               int mpcc_id)
+void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
 {
        struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-       uint32_t width = mpc42_get_rmcm_3dlut_width(size);
+       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);
+       REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE,
+               (width == 33) ? 2 : 0);
+
+       REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
 }
 
 void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
@@ -598,6 +731,14 @@ 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,
@@ -605,7 +746,6 @@ 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
 
@@ -646,7 +786,7 @@ void mpc42_set_fl_config(
 
        //width
        REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id],
-               MPC_RMCM_3DLUT_SIZE, width,
+               MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0,
                MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : (cfg->select_lut_bank_a) ? 1 : 2);
 
        //connect to hubp
@@ -659,6 +799,182 @@ 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_read_mpcc_state(
                struct mpc *mpc,
                int mpcc_inst,
@@ -755,7 +1071,14 @@ 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,
-       .get_lut_mode = mpc401_get_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,
+       },
        .rmcm = {
                .enable_3dlut_fl = mpc42_enable_3dlut_fl,
                .update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select,
@@ -764,6 +1087,7 @@ 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,
index a5f7f4f2bb3bcce4a80dff6ff4dd730ef8de1e02..12a12c28e5537e7835ad10aeaf54942892a4f3b5 100644 (file)
@@ -884,6 +884,49 @@ 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,
@@ -927,12 +970,12 @@ void mpc42_program_rmcm_lut_read_write_control(
                int mpcc_id);
 void mpc42_program_lut_mode(
                struct mpc *mpc,
-               bool enable,
+               const enum MCM_LUT_XABLE xable,
                bool lut_bank_a,
                int mpcc_id);
 void mpc42_program_rmcm_3dlut_size(
                struct mpc *mpc,
-               const enum dc_cm_lut_size size,
+               uint32_t width,
                int mpcc_id);
 void mpc42_program_rmcm_3dlut_fast_load_bias_scale(
                struct mpc *mpc,
@@ -944,6 +987,8 @@ 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,
index ce26816b3e65cd72ee0b6c1380eaf0fb7956a611..c013a6483f5d915b48f49a79ff32277a31ad1bbc 100644 (file)
@@ -666,7 +666,6 @@ 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 = {