From: <Roman.Li@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Harry Wentland <harry.wentland@amd.com>,
Leo Li <sunpeng.li@amd.com>,
Aurabindo Pillai <aurabindo.pillai@amd.com>,
Roman Li <roman.li@amd.com>, Wayne Lin <wayne.lin@amd.com>,
Tom Chung <chiahsuan.chung@amd.com>,
"Fangzhi Zuo" <jerry.zuo@amd.com>,
Dan Wheeler <daniel.wheeler@amd.com>, Ray Wu <Ray.Wu@amd.com>,
Ivan Lipski <ivan.lipski@amd.com>, Alex Hung <alex.hung@amd.com>,
James Lin <PingLei.Lin@amd.com>,
Chenyu Chen <Chen-Yu.Chen@amd.com>,
Rafal Ostrowski <rafal.ostrowski@amd.com>,
"Dillon Varone" <dillon.varone@amd.com>
Subject: [PATCH 40/41] drm/amd/display: Migrate color manager HW and fix MCM blend LUT issues
Date: Fri, 31 Jul 2026 17:13:01 -0400 [thread overview]
Message-ID: <20260731211302.3040343-41-Roman.Li@amd.com> (raw)
In-Reply-To: <20260731211302.3040343-1-Roman.Li@amd.com>
From: Rafal Ostrowski <rafal.ostrowski@amd.com>
Combine two related color manager improvements:
1. Migrate MCM/RMCM, shaper and 3DLUT HW programming to dc_plane_cm
- Continue convergence with upstream Color Manager refactor
- Migrate MCM/RMCM, shaper and 3DLUT programming for dcn401+ to dc_plane_cm
- Unify MCM programming across both legacy and 3DLUT DMA paths
- Add 3DLUT DMA broadcast support for multi-pipe planes
2. Reprogram MCM blend LUT on blend_enable falling edge
- Fix issue where SDR desktop remained desaturated after video playback
- Detect blend_enable falling edge (1->0) in surface update detection
- Force MCM LUT reprogramming on blend state change
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Rafal Ostrowski <rafal.ostrowski@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 66 +--
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 18 +
.../gpu/drm/amd/display/dc/core/dc_stream.c | 3 +-
drivers/gpu/drm/amd/display/dc/dc.h | 12 +-
.../amd/display/dc/hubp/dcn401/dcn401_hubp.c | 201 +++++---
.../amd/display/dc/hubp/dcn401/dcn401_hubp.h | 23 +-
.../amd/display/dc/hubp/dcn42/dcn42_hubp.c | 78 ++-
.../amd/display/dc/hubp/dcn42/dcn42_hubp.h | 10 +-
.../amd/display/dc/hubp/dcn50/dcn50_hubp.c | 10 +-
.../amd/display/dc/hubp/dcn60/dcn60_hubp.c | 7 +-
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 428 ++++++---------
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 7 +-
.../amd/display/dc/hwss/dcn401/dcn401_init.c | 1 -
.../amd/display/dc/hwss/dcn42/dcn42_hwseq.c | 488 ++----------------
.../amd/display/dc/hwss/dcn42/dcn42_hwseq.h | 6 -
.../amd/display/dc/hwss/dcn42/dcn42_init.c | 2 -
.../amd/display/dc/hwss/dcn60/dcn60_init.c | 2 -
.../drm/amd/display/dc/hwss/hw_sequencer.h | 2 +-
.../display/dc/hwss/hw_sequencer_private.h | 5 -
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 35 +-
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 81 +--
.../amd/display/dc/mpc/dcn401/dcn401_mpc.c | 177 ++++---
.../amd/display/dc/mpc/dcn401/dcn401_mpc.h | 25 +-
.../drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c | 405 ++-------------
.../drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h | 55 +-
.../drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c | 235 ++++-----
.../drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h | 15 -
.../dc/resource/dcn42/dcn42_resource.c | 1 +
.../dc/resource/dcn60/dcn60_resource.c | 1 +
29 files changed, 778 insertions(+), 1621 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 7f378b5e896c..68f228014305 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3027,13 +3027,14 @@ static struct dc_update_descriptor det_surface_update(
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
- if ((u->cm && u->cm->flags.bits.blend_enable) ||
+ if ((u->cm && (u->cm->flags.bits.blend_enable ||
+ u->cm->flags.bits.blend_enable != u->surface->cm.flags.bits.blend_enable)) ||
(u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
update_bits->gamma_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
- if (u->cm && (u->cm->flags.bits.lut3d_enable || u->cm->flags.bits.shaper_enable)) {
+ if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) {
update_bits->lut_3d = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
@@ -3075,25 +3076,12 @@ static struct dc_update_descriptor det_surface_update(
}
};
- if (u->cm->flags.bits.shaper_enable != u->surface->cm.flags.bits.shaper_enable
- || u->cm->flags.bits.blend_enable != u->surface->cm.flags.bits.blend_enable
- || u->cm->flags.bits.lut3d_enable != u->surface->cm.flags.bits.lut3d_enable
- || u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable) {
- update_bits->mcm_transfer_function_enable_change = 1;
- elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
- }
-
if ((u->cm->flags.all != blend_only_flags.all && u->cm->flags.all != 0) ||
(u->surface->cm.flags.all != blend_only_flags.all && u->surface->cm.flags.all != 0)) {
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
}
- if (update_bits->lut_3d &&
- !u->surface->cm.flags.bits.lut3d_dma_enable) {
- elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
- }
-
if (check_config->enable_legacy_fast_update &&
(update_bits->gamma_change ||
update_bits->gamut_remap_change ||
@@ -3446,46 +3434,6 @@ static void copy_surface_update_to_plane(
memcpy(&surface->cm, srf_update->cm, sizeof(surface->cm));
surface->cm.refcount = refcount;
-#ifndef TRIM_CM2
- /* Populate mcm_luts from cm for legacy consumers (dml2, hwseq) */
- surface->mcm_luts.lut1d_func = &surface->cm.blend_func;
- surface->mcm_luts.shaper = &surface->cm.shaper_func;
- if (srf_update->cm->flags.bits.lut3d_dma_enable) {
- surface->mcm_luts.lut3d_data.lut3d_src = DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM;
- surface->mcm_luts.lut3d_data.gpu_mem_params.addr = surface->cm.lut3d_dma.addr;
- surface->mcm_luts.lut3d_data.gpu_mem_params.layout =
- (surface->cm.lut3d_dma.swizzle == CM_LUT_3D_SWIZZLE_LINEAR_RGB) ?
- DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB :
- (surface->cm.lut3d_dma.swizzle == CM_LUT_3D_SWIZZLE_LINEAR_BGR) ?
- DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR :
- DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR;
- surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.format =
- (surface->cm.lut3d_dma.format == CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB) ?
- DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB :
- (surface->cm.lut3d_dma.format == CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB) ?
- DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB :
- DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10;
- surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias =
- surface->cm.lut3d_dma.bias;
- surface->mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale =
- surface->cm.lut3d_dma.scale;
- surface->mcm_luts.lut3d_data.gpu_mem_params.component_order =
- DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA;
- surface->mcm_luts.lut3d_data.gpu_mem_params.size = DC_CM2_GPU_MEM_SIZE_TRANSFORMED;
- surface->mcm_luts.lut3d_data.mpc_3dlut_enable = (srf_update->cm->flags.bits.lut3d_enable != 0);
- } else {
- surface->mcm_luts.lut3d_data.lut3d_src = DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM;
- surface->mcm_luts.lut3d_data.lut3d_func = &surface->cm.lut3d_func;
- }
-
- if (srf_update->cm->flags.bits.shaper_enable &&
- srf_update->cm->flags.bits.lut3d_enable)
- surface->mcm_shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT;
- else if (srf_update->cm->flags.bits.shaper_enable)
- surface->mcm_shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER;
- else
- surface->mcm_shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
-#endif /* TRIM_CM2 */
}
if (srf_update->hdr_mult.value)
@@ -3496,12 +3444,6 @@ static void copy_surface_update_to_plane(
surface->sdr_white_level_nits =
srf_update->sdr_white_level_nits;
- if (srf_update->cm &&
- (srf_update->cm->flags.bits.blend_enable ||
- srf_update->cm->flags.bits.shaper_enable ||
- srf_update->cm->flags.bits.lut3d_enable))
- surface->lut_bank_a = !surface->lut_bank_a;
-
if (srf_update->input_csc_color_matrix)
surface->input_csc_color_matrix =
*srf_update->input_csc_color_matrix;
@@ -5243,7 +5185,7 @@ static void commit_planes_for_stream(struct dc *dc,
srf_updates[i].cm->flags.bits.lut3d_enable &&
srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
dc->hwss.trigger_3dlut_dma_load)
- dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx);
+ dc->hwss.trigger_3dlut_dma_load(pipe_ctx);
/*program triple buffer after lock based on flip type*/
if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 8878652434d2..76e3509f73c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -1457,6 +1457,24 @@ void hwss_build_fast_sequence(struct dc *dc,
(*num_steps)++;
}
+ if (current_mpc_pipe->plane_state->update_bits.hdr_mult) {
+ struct fixed31_32 multiplier = current_mpc_pipe->plane_state->hdr_mult;
+ uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
+ struct custom_float_format fmt;
+
+ fmt.exponenta_bits = 6;
+ fmt.mantissa_bits = 12;
+ fmt.sign = true;
+
+ if (!dc_fixpt_eq(multiplier, dc_fixpt_from_int(0)) && // check != 0
+ convert_to_custom_float_format(multiplier, &fmt, &hw_mult)) {
+ block_sequence[*num_steps].params.dpp_set_hdr_multiplier_params.dpp = current_mpc_pipe->plane_res.dpp;
+ block_sequence[*num_steps].params.dpp_set_hdr_multiplier_params.hw_mult = hw_mult;
+ block_sequence[*num_steps].func = DPP_SET_HDR_MULTIPLIER;
+ (*num_steps)++;
+ }
+ }
+
if (dc->hwss.program_gamut_remap &&
(current_mpc_pipe->plane_state->update_bits.gamut_remap_change ||
current_mpc_pipe->stream->update_flags.bits.gamut_remap)) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index ce5b9e82db8d..9f3068e899e1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -991,6 +991,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream)
}
}
+/* TODO - move to per plane ownership? */
/*
* dc_stream_get_3dlut()
* Requirements:
@@ -1042,7 +1043,6 @@ void dc_stream_release_3dlut_for_stream(
if (rmcm_3dlut) {
rmcm_3dlut->isInUse = false;
rmcm_3dlut->stream = NULL;
- rmcm_3dlut->protection_bits = 0;
}
}
@@ -1054,7 +1054,6 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
for (unsigned int i = 0; i < num_rmcm; i++) {
dc->res_pool->rmcm_3dlut[i].isInUse = false;
dc->res_pool->rmcm_3dlut[i].stream = NULL;
- dc->res_pool->rmcm_3dlut[i].protection_bits = 0;
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 683b5fb1945d..b2fd3a94f067 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1459,6 +1459,7 @@ struct dc_transfer_func {
enum dc_transfer_func_predefined tf;
/* FP16 1.0 reference level in nits, default is 80 nits, only for PQ*/
uint32_t sdr_ref_white_level;
+ struct fixed31_32 hdr_multiplier;
union {
struct pwl_params pwl;
struct dc_transfer_func_distributed_points tf_pts;
@@ -1509,13 +1510,11 @@ struct lut_mem_mapping {
struct dc_rmcm_3dlut {
bool isInUse;
const struct dc_stream_state *stream;
- uint8_t protection_bits;
};
struct dc_3dlut {
struct kref refcount;
struct tetrahedral_params lut_3d;
- struct fixed31_32 hdr_multiplier;
union dc_3dlut_state state;
};
@@ -1595,7 +1594,6 @@ struct pipe_update_bits {
uint32_t stereo_format_change:1;
uint32_t lut_3d:1;
uint32_t tmz_changed:1;
- uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */
uint32_t full_update:1;
uint32_t sdr_white_level_nits:1;
uint32_t cm_hist_change:1;
@@ -1640,7 +1638,6 @@ static inline void dc_pipe_update_bits_set_full(struct pipe_update_bits *flags)
flags->stereo_format_change = 1;
flags->lut_3d = 1;
flags->tmz_changed = 1;
- flags->mcm_transfer_function_enable_change = 1;
flags->full_update = 1;
flags->sdr_white_level_nits = 1;
flags->cm_hist_change = 1;
@@ -1674,7 +1671,6 @@ static inline bool dc_pipe_update_bits_is_any_set(const struct pipe_update_bits
flags->stereo_format_change ||
flags->lut_3d ||
flags->tmz_changed ||
- flags->mcm_transfer_function_enable_change ||
flags->full_update ||
flags->sdr_white_level_nits ||
flags->cm_hist_change;
@@ -1709,18 +1705,16 @@ struct dc_plane_state {
enum dc_color_space color_space;
#ifndef TRIM_CM2
- // TODO: No longer used, remove
+ bool lut_bank_a;
struct dc_hdr_static_metadata hdr_static_ctx;
-
struct dc_3dlut lut3d_func;
struct dc_transfer_func in_shaper_func;
struct dc_transfer_func blend_tf;
enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
bool mcm_lut1d_enable;
struct dc_cm2_func_luts mcm_luts;
-#endif /* TRIM_CM2 */
- bool lut_bank_a;
enum mpcc_movable_cm_location mcm_location;
+#endif /* TRIM_CM2 */
struct dc_plane_cm cm;
struct dc_transfer_func *gamcor_tf;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index 9965cf572354..a2e0bafb711a 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -41,12 +41,12 @@
hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
void hubp401_program_3dlut_fl_addr(struct hubp *hubp,
- const struct dc_plane_address address)
+ const struct dc_plane_address *address)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address.lut3d.addr.high_part);
- REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part);
+ REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address->lut3d.addr.high_part);
+ REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address->lut3d.addr.low_part);
}
void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group)
@@ -72,33 +72,46 @@ uint32_t hubp401_get_3dlut_fl_done(struct hubp *hubp)
return ret;
}
-void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode)
+static void hubp401_get_3dlut_fl_xbar_map(
+ const enum dc_cm_lut_pixel_format format,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-
- REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
-}
-
-void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width)
-{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-
- REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width);
+ switch (format) {
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+ /* BGRA */
+ *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ break;
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+ default:
+ /* RGBA */
+ *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ break;
+ }
}
-void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits)
+void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
+ const enum dc_cm_lut_pixel_format format)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
- REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
-}
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r = 0;
-void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r)
-{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ hubp401_get_3dlut_fl_xbar_map(format,
+ &bit_slice_y_g,
+ &bit_slice_cb_b,
+ &bit_slice_cr_r);
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
@@ -106,62 +119,122 @@ void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
}
-void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale)
+static enum hubp_3dlut_fl_width hubp401_get_3dlut_fl_width(
+ const enum dc_cm_lut_size size,
+ const enum dc_cm_lut_swizzle swizzle)
{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ enum hubp_3dlut_fl_width width = 0;
+
+ switch (size) {
+ case CM_LUT_SIZE_333333:
+ ASSERT(swizzle != CM_LUT_1D_PACKED_LINEAR);
+ width = hubp_3dlut_fl_width_33;
+ break;
+ case CM_LUT_SIZE_171717:
+ if (swizzle != CM_LUT_1D_PACKED_LINEAR) {
+ width = hubp_3dlut_fl_width_17;
+ } else {
+ width = hubp_3dlut_fl_width_17_transformed;
+ }
+ break;
+ default:
+ width = 0;
+ break;
+ }
- REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale);
+ return width;
}
-void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode)
+static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format(
+ const enum dc_cm_lut_pixel_format dc_format)
{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ enum hubp_3dlut_fl_format hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
+ switch (dc_format) {
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+ hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
+ break;
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+ hubp_format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
+ break;
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+ hubp_format = hubp_3dlut_fl_format_float_fp1_5_10;
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+
+ return hubp_format;
}
-void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format)
+static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode(
+ const enum dc_cm_lut_swizzle swizzle)
{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ enum hubp_3dlut_fl_addressing_mode addr_mode;
+
+ switch (swizzle) {
+ case CM_LUT_1D_PACKED_LINEAR:
+ addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
+ break;
+ case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
+ case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
+ default:
+ addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
+ break;
+ }
- REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
+ return addr_mode;
}
-void hubp401_program_3dlut_fl_config(
- struct hubp *hubp,
- struct hubp_fl_3dlut_config *cfg)
+static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode(
+ const enum dc_cm_lut_swizzle swizzle)
{
- struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ enum hubp_3dlut_fl_mode mode;
- uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
- uint32_t width = {cfg->width};
+ switch (swizzle) {
+ case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
+ mode = hubp_3dlut_fl_mode_native_1;
+ break;
+ case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
+ mode = hubp_3dlut_fl_mode_native_2;
+ break;
+ case CM_LUT_1D_PACKED_LINEAR:
+ mode = hubp_3dlut_fl_mode_transform;
+ break;
+ default:
+ mode = hubp_3dlut_fl_mode_disable;
+ break;
+ }
- if (cfg->layout == CM_LUT_1D_PACKED_LINEAR)
- width = (cfg->width == 17) ? 4916 : 35940;
+ return mode;
+}
+
+void hubp401_program_3dlut_fl_config(struct hubp *hubp,
+ const struct dc_3dlut_dma *config)
+{
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+ enum hubp_3dlut_fl_width width = hubp401_get_3dlut_fl_width(config->size, config->swizzle);
+ enum hubp_3dlut_fl_format format = hubp401_get_3dlut_fl_format(config->format);
+ enum hubp_3dlut_fl_addressing_mode addr_mode = hubp401_get_3dlut_fl_addr_mode(config->swizzle);
+ enum hubp_3dlut_fl_mode mode = hubp401_get_3dlut_fl_mode(config->swizzle);
REG_UPDATE_2(_3DLUT_FL_CONFIG,
- HUBP0_3DLUT_FL_MODE, cfg->mode,
- HUBP0_3DLUT_FL_FORMAT, cfg->format);
+ HUBP0_3DLUT_FL_MODE, mode,
+ HUBP0_3DLUT_FL_FORMAT, format);
REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
- HUBP0_3DLUT_FL_BIAS, cfg->bias,
- HUBP0_3DLUT_FL_SCALE, cfg->scale);
-
- REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
- HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
- REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
- HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
-
- //cross bar
- REG_UPDATE_8(HUBP_3DLUT_CONTROL,
- HUBP_3DLUT_MPC_WIDTH, mpc_width,
- HUBP_3DLUT_WIDTH, width,
- HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
- HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
- HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
- HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
- HUBP_3DLUT_TMZ, cfg->protection_bits,
- HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
+ HUBP0_3DLUT_FL_BIAS, config->bias,
+ HUBP0_3DLUT_FL_SCALE, config->scale);
+
+ REG_UPDATE_3(HUBP_3DLUT_CONTROL,
+ HUBP_3DLUT_WIDTH, width,
+ HUBP_3DLUT_ADDRESSING_MODE, addr_mode,
+ HUBP_3DLUT_TMZ, config->addr.tmz_surface);
}
void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
@@ -1062,19 +1135,13 @@ static struct hubp_funcs dcn401_hubp_funcs = {
.hubp_update_mall_sel = hubp401_update_mall_sel,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
- .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
- .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
- .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+ .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
- .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
- .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
- .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
- .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_read_reg_state = hubp3_read_reg_state
};
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
index 4116834c552d..adf343837652 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
@@ -328,32 +328,17 @@ uint32_t hubp401_get_3dlut_fl_done(struct hubp *hubp);
void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable);
-void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale);
-
void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
-
-void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits);
-
-void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width);
-
-void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
+ const enum dc_cm_lut_pixel_format format);
void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable);
void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group);
-void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address address);
+void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address *address);
-void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format);
-
-void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode);
-
-void hubp401_program_3dlut_fl_config(
- struct hubp *hubp,
- struct hubp_fl_3dlut_config *cfg);
+void hubp401_program_3dlut_fl_config(struct hubp *hubp,
+ const struct dc_3dlut_dma *config);
void hubp401_clear_tiling(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
index 94730f3cff42..86e49eb84a54 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
@@ -317,19 +317,84 @@ static void hubp42_program_surface_config(
hubp42_program_pixel_format(hubp, format);
}
+static void hubp42_get_3dlut_fl_xbar_map(
+ const enum dc_cm_lut_pixel_format format,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
+ enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
+{
+ switch (format) {
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
+ case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
+ /* BGRA */
+ *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ break;
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
+ case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
+ default:
+ /* RGBA */
+ *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
+ *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
+ *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ break;
+ }
+}
+
void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b)
+ const enum dc_cm_lut_pixel_format format)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0;
+ enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0;
+
+ hubp42_get_3dlut_fl_xbar_map(format,
+ &bit_slice_g,
+ &bit_slice_b,
+ &bit_slice_r);
+
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
}
+static uint32_t hubp42_get_3dlut_fl_mpc_width(
+ const enum dc_cm_lut_size size)
+{
+ uint32_t width = 0;
+
+ switch (size) {
+ case CM_LUT_SIZE_333333:
+ width = 1;
+ break;
+ case CM_LUT_SIZE_171717:
+ default:
+ width = 0;
+ break;
+ }
+
+ return width;
+}
+
+void hubp42_program_3dlut_fl_config(struct hubp *hubp,
+ const struct dc_3dlut_dma *config)
+{
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+ uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size);
+
+ REG_UPDATE(HUBP_3DLUT_CONTROL,
+ HUBP_3DLUT_MPC_WIDTH, mpc_width);
+
+ hubp401_program_3dlut_fl_config(hubp, config);
+}
+
static bool hubp42_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
@@ -660,15 +725,10 @@ struct hubp_funcs dcn42_hubp_funcs = {
.hubp_set_flip_int = hubp1_set_flip_int,
.hubp_in_blank = hubp1_in_blank,
.program_extended_blank = hubp31_program_extended_blank_value,
- .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
- .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
- .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+ .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
- .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
- .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
- .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp3_clear_tiling,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
index ba4a58c353dd..3a030e5e517e 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
@@ -79,11 +79,11 @@ bool hubp42_construct(
const struct dcn_hubp2_shift *hubp_shift,
const struct dcn_hubp2_mask *hubp_mask);
-void hubp42_program_3dlut_fl_crossbar(
- struct hubp *hubp,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b);
+void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
+ const enum dc_cm_lut_pixel_format format);
+
+void hubp42_program_3dlut_fl_config(struct hubp *hubp,
+ const struct dc_3dlut_dma *config);
void hubp42_read_state(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
index e704ce5cd0a0..0230f03590cf 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn50/dcn50_hubp.c
@@ -7,6 +7,7 @@
#include "reg_helper.h"
#include "basics/conversion.h"
#include "dcn50_hubp.h"
+#include "dcn42/dcn42_hubp.h"
#define REG(reg)\
hubp2->hubp_regs->reg
@@ -500,16 +501,11 @@ static struct hubp_funcs dcn50_hubp_funcs = {
.hubp_update_mall_sel = hubp401_update_mall_sel,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
- .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
- .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
- .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+ .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
- .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
- .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
- .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
- .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
+ .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
.hubp_read_reg_state = hubp3_read_reg_state
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
index 1065303f1d72..d22fe26aae62 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn60/dcn60_hubp.c
@@ -441,15 +441,10 @@ static struct hubp_funcs dcn60_hubp_funcs = {
.hubp_update_mall_sel = NULL,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
- .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
- .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
- .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
+ .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
- .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
- .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
- .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 904780e02f70..51596f445a09 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -99,10 +99,6 @@ void dcn401_program_gamut_remap(struct program_gamut_remap_params *params)
unsigned int i = 0;
struct mpc_grph_gamut_adjustment mpc_adjust;
- //For now assert if location is not pre-blend
- if (plane)
- ASSERT(plane->mcm_location == MPCC_MOVABLE_CM_LOCATION_BEFORE);
-
// program MPCC_MCM_FIRST_GAMUT_REMAP
memset(&mpc_adjust, 0, sizeof(mpc_adjust));
mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -413,289 +409,200 @@ void dcn401_init_hw(struct dc *dc)
}
}
-static void dcn401_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx,
- enum MCM_LUT_XABLE *shaper_xable,
- enum MCM_LUT_XABLE *lut3d_xable,
- enum MCM_LUT_XABLE *lut1d_xable)
+void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx)
{
- struct mpc *mpc = dc->res_pool->mpc;
- int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
- if (!pipe_ctx->plane_state)
- return;
+ const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx);
+ struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+ primary_dpp_pipe_ctx->plane_res.hubp : NULL;
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
- pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-
- *lut1d_xable = pipe_ctx->plane_state->cm.flags.bits.blend_enable ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
- *shaper_xable = pipe_ctx->plane_state->cm.flags.bits.shaper_enable ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
- *lut3d_xable = (pipe_ctx->plane_state->cm.flags.bits.shaper_enable &&
- pipe_ctx->plane_state->cm.flags.bits.lut3d_enable) ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
+ if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
+ }
}
-void dcn401_populate_mcm_luts(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
- bool lut_bank_a)
+bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
+ const struct dc_plane_state *plane_state)
{
+ struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+ const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx);
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+ primary_dpp_pipe_ctx->plane_res.hubp : hubp; /* fall back to current pipe */
+ const struct dc_plane_cm *cm = &plane_state->cm;
int mpcc_id = hubp->inst;
struct mpc *mpc = dc->res_pool->mpc;
union mcm_lut_params m_lut_params;
- const bool lut3d_dma = !!cm->flags.bits.lut3d_dma_enable;
- enum hubp_3dlut_fl_format format = 0;
- enum hubp_3dlut_fl_mode mode;
- /* Width was previously hard-coded to TRANSFORMED via local_mcm build,
- * preserve identical behavior.
- */
- enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_transformed;
- enum hubp_3dlut_fl_addressing_mode addr_mode;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
- enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
- enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
- enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
+ struct dc_3dlut_dma lut3d_dma;
+ bool lut_enable;
+ bool lut_bank_a;
bool rval;
+ bool result = true;
+
+ /* decide LUT bank based on current in use */
+ mpc->funcs->get_lut_mode(mpc, MCM_LUT_1DLUT, mpcc_id, &lut_enable, &lut_bank_a);
+ if (!lut_enable) {
+ mpc->funcs->get_lut_mode(mpc, MCM_LUT_SHAPER, mpcc_id, &lut_enable, &lut_bank_a);
+ }
+ if (!lut_enable) {
+ mpc->funcs->get_lut_mode(mpc, MCM_LUT_3DLUT, mpcc_id, &lut_enable, &lut_bank_a);
+ }
- dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
+ /* switch to the next bank */
+ if (lut_enable) {
+ lut_bank_a = !lut_bank_a;
+ }
+
+ /* MCM location fixed to pre-blend */
+ mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
/* 1D LUT */
- {
- memset(&m_lut_params, 0, sizeof(m_lut_params));
+ lut_enable = cm->flags.bits.blend_enable != 0u;
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
+ if (lut_enable) {
if (cm->blend_func.type == TF_TYPE_HWPWL)
m_lut_params.pwl = &cm->blend_func.pwl;
else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&cm->blend_func,
- &dpp_base->regamma_params, false);
+ &dpp_base->regamma_params,
+ false);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
- if (m_lut_params.pwl) {
- if (mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
+
+ if (!m_lut_params.pwl) {
+ lut_enable = false;
}
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
+ } else {
+ lut_enable = false;
}
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
+ if (lut_enable && mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, &m_lut_params, lut_bank_a, mpcc_id);
+
/* Shaper */
- if (cm->flags.bits.lut3d_enable) {
+ lut_enable = cm->flags.bits.shaper_enable != 0u;
+ if (lut_enable) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (cm->shaper_func.type == TF_TYPE_HWPWL)
m_lut_params.pwl = &cm->shaper_func.pwl;
else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
- rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
+ rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&cm->shaper_func,
- &dpp_base->regamma_params, true);
- m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
- }
- if (m_lut_params.pwl) {
- if (mpc->funcs->mcm.populate_lut)
- mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
+ &dpp_base->shaper_params,
+ true);
+ m_lut_params.pwl = rval ? &dpp_base->shaper_params : NULL;
}
- }
-
- /* 3DLUT */
- if (!lut3d_dma) {
- /* SYSMEM (legacy lut3d_func) */
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (hubp->funcs->hubp_enable_3dlut_fl)
- hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
-
- if (cm->lut3d_func.state.bits.initialized) {
- m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
- if (mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
- mpcc_id);
+ if (!m_lut_params.pwl) {
+ lut_enable = false;
}
} else {
- /* VIDMEM (3DLUT DMA Fast Load) */
+ lut_enable = false;
+ }
- /* Select width based on the requested LUT size */
- switch (cm->lut3d_dma.size) {
- case CM_LUT_SIZE_333333:
- if (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33)
- width = hubp_3dlut_fl_width_33;
- break;
- case CM_LUT_SIZE_171717:
- width = hubp_3dlut_fl_width_17;
- break;
- default:
- /* keep default hubp_3dlut_fl_width_transformed */
- break;
- }
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
+ if (lut_enable && mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_SHAPER, &m_lut_params, lut_bank_a, mpcc_id);
- //check for support
- if (mpc->funcs->mcm.is_config_supported &&
- !mpc->funcs->mcm.is_config_supported(width))
- return;
+ /* NOTE: Toggling from DMA->Host is not supported atomically as hardware
+ * blocks writes until 3DLUT FL mode is cleared from HUBP on VUpdate.
+ * Expectation is either option is used consistently.
+ */
- if (mpc->funcs->program_lut_read_write_control)
- mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
+ /* 3DLUT */
+ lut_enable = cm->flags.bits.lut3d_enable != 0u;
+ if (lut_enable && cm->flags.bits.lut3d_dma_enable) {
+ /* Fast (DMA) Load Mode */
+ /* MPC */
if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
+ mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id);
- if (hubp->funcs->hubp_program_3dlut_fl_addr)
- hubp->funcs->hubp_program_3dlut_fl_addr(hubp, cm->lut3d_dma.addr);
-
- /* bit_depth was previously zero-initialized in local_mcm,
- * preserve identical behavior.
- */
- if (mpc->funcs->mcm.program_bit_depth)
- mpc->funcs->mcm.program_bit_depth(mpc, 0, mpcc_id);
-
- switch (cm->lut3d_dma.swizzle) {
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- mode = hubp_3dlut_fl_mode_native_1;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- mode = hubp_3dlut_fl_mode_native_2;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_1D_PACKED_LINEAR:
- mode = hubp_3dlut_fl_mode_transform;
- addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
- break;
- default:
- mode = hubp_3dlut_fl_mode_disable;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- }
- if (hubp->funcs->hubp_program_3dlut_fl_mode)
- hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
+ /* only supports 12 bit */
+ if (mpc->funcs->program_lut_read_write_control)
+ mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id);
- if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
- hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
+ if (mpc->funcs->update_3dlut_fast_load_select)
+ mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, primary_hubp->inst);
- switch (cm->lut3d_dma.format) {
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- format = hubp_3dlut_fl_format_float_fp1_5_10;
- break;
- default:
- break;
- }
- if (hubp->funcs->hubp_program_3dlut_fl_format)
- hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
- if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
- mpc->funcs->mcm.program_bias_scale) {
- mpc->funcs->mcm.program_bias_scale(mpc,
- cm->lut3d_dma.bias,
- cm->lut3d_dma.scale,
- mpcc_id);
- hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
- cm->lut3d_dma.bias,
- cm->lut3d_dma.scale);
- }
+ /* HUBP */
+ if (primary_hubp->inst == hubp->inst) {
+ /* only program if this is the primary dpp pipe for the given plane */
+ if (hubp->funcs->hubp_program_3dlut_fl_config)
+ hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
- /* component_order was previously hard-coded to RGBA in local_mcm,
- * preserve identical behavior.
- */
- crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
+ if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
+ hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format);
- if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
- hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
- crossbar_bit_slice_cr_r,
- crossbar_bit_slice_y_g,
- crossbar_bit_slice_cb_b);
+ if (hubp->funcs->hubp_program_3dlut_fl_addr)
+ hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
- if (mpc->funcs->mcm.program_lut_read_write_control)
- mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
+ if (hubp->funcs->hubp_enable_3dlut_fl) {
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
+ } else {
+ /* GPU memory only supports fast load path */
+ BREAK_TO_DEBUGGER();
+ lut_enable = false;
+ result = false;
+ }
+ } else {
+ /* re-trigger primary HUBP to load 3DLUT */
+ if (primary_hubp->funcs->hubp_enable_3dlut_fl) {
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
+ }
- if (mpc->funcs->mcm.program_3dlut_size)
- mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
+ /* clear FL setup on this pipe's HUBP */
+ memset(&lut3d_dma, 0, sizeof(lut3d_dma));
+ if (hubp->funcs->hubp_program_3dlut_fl_config)
+ hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma);
- if (mpc->funcs->update_3dlut_fast_load_select)
- mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
+ if (hubp->funcs->hubp_enable_3dlut_fl)
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
+ }
+ } else {
+ /* Legacy (Host) Load Mode */
+ memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (hubp->funcs->hubp_enable_3dlut_fl)
- hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
- else {
- if (mpc->funcs->program_lut_mode) {
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- }
+ if (cm->flags.bits.lut3d_enable && cm->lut3d_func.state.bits.initialized) {
+ m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
+ } else {
+ lut_enable = false;
}
- }
-}
-void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
-{
- (void)dc;
- struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ /* MPC */
+ if (mpc->funcs->program_lut_mode)
+ mpc->funcs->program_lut_mode(mpc,
+ MCM_LUT_3DLUT,
+ lut_enable,
+ lut_bank_a,
+ cm->lut3d_func.lut_3d.use_tetrahedral_9 ? CM_LUT_SIZE_999 : CM_LUT_SIZE_171717,
+ mpcc_id);
+
+ if (lut_enable) {
+ if (mpc->funcs->program_lut_read_write_control)
+ mpc->funcs->program_lut_read_write_control(mpc,
+ MCM_LUT_3DLUT,
+ lut_bank_a,
+ cm->lut3d_func.lut_3d.use_12bits ? 12 : 10,
+ mpcc_id);
- if (hubp->funcs->hubp_enable_3dlut_fl) {
- hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
- }
-}
+ if (mpc->funcs->update_3dlut_fast_load_select)
+ mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 0xf);
-bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
- const struct dc_plane_state *plane_state)
-{
- struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
- int mpcc_id = pipe_ctx->plane_res.hubp->inst;
- struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
- struct mpc *mpc = dc->res_pool->mpc;
- bool result;
- const struct pwl_params *lut_params = NULL;
- bool rval;
+ if (mpc->funcs->populate_lut)
+ mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, &m_lut_params, lut_bank_a, mpcc_id);
+ }
- if (plane_state->cm.flags.bits.lut3d_dma_enable) {
- dcn401_populate_mcm_luts(dc, pipe_ctx, &plane_state->cm, plane_state->lut_bank_a);
- return true;
- }
+ /* HUBP */
+ memset(&lut3d_dma, 0, sizeof(lut3d_dma));
+ if (hubp->funcs->hubp_program_3dlut_fl_config)
+ hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma);
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
- pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
- // 1D LUT
- if (plane_state->cm.blend_func.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->cm.blend_func.pwl;
- else if (plane_state->cm.blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->cm.blend_func,
- &dpp_base->regamma_params, false);
- lut_params = rval ? &dpp_base->regamma_params : NULL;
- }
- result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
- lut_params = NULL;
-
- // Shaper
- if (plane_state->cm.shaper_func.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->cm.shaper_func.pwl;
- else if (plane_state->cm.shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- // TODO: dpp_base replace
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->cm.shaper_func,
- &dpp_base->shaper_params, true);
- lut_params = rval ? &dpp_base->shaper_params : NULL;
- }
- result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
-
- // 3D
- if (mpc->funcs->program_3dlut) {
- if (plane_state->cm.lut3d_func.state.bits.initialized == 1)
- result &= mpc->funcs->program_3dlut(mpc, &plane_state->cm.lut3d_func.lut_3d, mpcc_id);
- else
- result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+ if (hubp->funcs->hubp_enable_3dlut_fl)
+ hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
}
return result;
@@ -2096,42 +2003,41 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
if (!pipe_ctx)
return;
- struct pipe_ctx *wa_pipes[MAX_PIPES] = { NULL };
- struct pipe_ctx *odm_pipe, *mpc_pipe;
- int i, wa_pipe_ct = 0;
+ const struct pipe_ctx *otg_master_pipe_ctx = resource_get_otg_master(pipe_ctx);
+ struct timing_generator *tg = otg_master_pipe_ctx ?
+ otg_master_pipe_ctx->stream_res.tg : NULL;
+ const struct pipe_ctx *primary_dpp_pipe_ctx = resource_is_pipe_type(pipe_ctx, DPP_PIPE) ?
+ resource_get_primary_dpp_pipe(pipe_ctx) : pipe_ctx;
+ struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
+ primary_dpp_pipe_ctx->plane_res.hubp : NULL;
- for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) {
- for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) {
- if (mpc_pipe->plane_state &&
- mpc_pipe->plane_state->cm.flags.bits.lut3d_enable &&
- mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) {
- wa_pipes[wa_pipe_ct++] = mpc_pipe;
- }
- }
+ if (!otg_master_pipe_ctx || !tg) {
+ return;
}
- if (wa_pipe_ct > 0) {
- if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout)
- pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, true);
+ if (primary_dpp_pipe_ctx &&
+ primary_dpp_pipe_ctx->plane_state &&
+ primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_enable &&
+ primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_dma_enable) {
+ if (tg->funcs->set_vupdate_keepout)
+ tg->funcs->set_vupdate_keepout(tg, true);
- for (i = 0; i < wa_pipe_ct; ++i) {
- if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl)
- wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true);
+ if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
}
- pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
- if (pipe_ctx->stream_res.tg->funcs->wait_update_lock_status)
- pipe_ctx->stream_res.tg->funcs->wait_update_lock_status(pipe_ctx->stream_res.tg, false);
+ tg->funcs->unlock(tg);
+ if (tg->funcs->wait_update_lock_status)
+ tg->funcs->wait_update_lock_status(tg, false);
- for (i = 0; i < wa_pipe_ct; ++i) {
- if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl)
- wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true);
+ if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
}
- if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout)
- pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, false);
+ if (tg->funcs->set_vupdate_keepout)
+ tg->funcs->set_vupdate_keepout(tg, false);
} else {
- pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
+ tg->funcs->unlock(tg);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
index f90e25243ead..69c7dc73a29a 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
@@ -39,8 +39,7 @@ void dcn401_init_hw(struct dc *dc);
bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
bool dcn401_set_output_transfer_func(struct set_output_transfer_func_params *params);
-void dcn401_trigger_3dlut_dma_load(struct dc *dc,
- struct pipe_ctx *pipe_ctx);
+void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx);
void dcn401_calculate_dccg_tmds_div_value(struct pipe_ctx *pipe_ctx,
unsigned int *tmds_div);
enum dc_status dcn401_enable_stream_timing(
@@ -48,10 +47,6 @@ enum dc_status dcn401_enable_stream_timing(
struct dc_state *context,
struct dc *dc);
void dcn401_enable_stream(struct pipe_ctx *pipe_ctx);
-void dcn401_populate_mcm_luts(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
- bool lut_bank_a);
void dcn401_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
void dcn401_disable_link_output(struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index f206e221f926..7039f40ea880 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -166,7 +166,6 @@ static const struct hwseq_private_funcs dcn401_private_funcs = {
.calculate_dccg_k1_k2_values = NULL,
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
- .populate_mcm_luts = NULL,
.perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
.program_pipe_sequence = dcn401_program_pipe_sequence,
.dc_ip_request_cntl = dcn401_dc_ip_request_cntl,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
index 151a29bf0e9d..13580d9f9303 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
@@ -402,64 +402,6 @@ void dcn42_program_cm_hist(
plane_state->cm_hist_control, plane_state->color_space);
}
-static void dc_get_lut_xbar(
- enum hubp_3dlut_fl_crossbar_bit_slice *cr_r,
- enum hubp_3dlut_fl_crossbar_bit_slice *y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice *cb_b)
-{
- /* component_order was previously hard-coded to RGBA in local_mcm,
- * preserve identical behavior.
- */
- *cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- *cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
-}
-
-static void dc_get_lut_mode(
- enum dc_cm_lut_swizzle swizzle,
- enum hubp_3dlut_fl_mode *mode,
- enum hubp_3dlut_fl_addressing_mode *addr_mode)
-{
- switch (swizzle) {
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- *mode = hubp_3dlut_fl_mode_native_1;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- *mode = hubp_3dlut_fl_mode_native_2;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_1D_PACKED_LINEAR:
- *mode = hubp_3dlut_fl_mode_transform;
- *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
- break;
- default:
- *mode = hubp_3dlut_fl_mode_disable;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- }
-}
-
-static void dc_get_lut_format(
- enum dc_cm_lut_pixel_format dc_format,
- enum hubp_3dlut_fl_format *format)
-{
- switch (dc_format) {
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- *format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- *format = hubp_3dlut_fl_format_float_fp1_5_10;
- break;
- default:
- *format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- break;
- }
-}
-
static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
{
if (mpc->funcs->rmcm.power_on_shaper_3dlut &&
@@ -470,106 +412,17 @@ static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
return false;
}
-static bool is_rmcm_3dlut_fl_supported(struct dc *dc)
-{
- /* size was previously hard-coded to TRANSFORMED in local_mcm,
- * which mapped to dim_17. Preserve identical behavior.
- */
- if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut)
- return false;
- return dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17 != 0u;
-}
-
-static void dcn42_set_mcm_location_post_blend(struct dc *dc, struct pipe_ctx *pipe_ctx, bool bPostBlend)
-{
- struct mpc *mpc = dc->res_pool->mpc;
- int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
- if (!pipe_ctx->plane_state)
- return;
-
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
- pipe_ctx->plane_state->mcm_location = (bPostBlend) ?
- MPCC_MOVABLE_CM_LOCATION_AFTER :
- MPCC_MOVABLE_CM_LOCATION_BEFORE;
-}
-
-static void dcn42_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx,
- enum MCM_LUT_XABLE *shaper_xable,
- enum MCM_LUT_XABLE *lut3d_xable,
- enum MCM_LUT_XABLE *lut1d_xable)
-{
- struct mpc *mpc = dc->res_pool->mpc;
- int mpcc_id = pipe_ctx->plane_res.hubp->inst;
-
- if (!pipe_ctx->plane_state)
- return;
-
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
- pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
-
- *lut1d_xable = pipe_ctx->plane_state->cm.flags.bits.blend_enable ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
- *shaper_xable = pipe_ctx->plane_state->cm.flags.bits.shaper_enable ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
- *lut3d_xable = (pipe_ctx->plane_state->cm.flags.bits.shaper_enable &&
- pipe_ctx->plane_state->cm.flags.bits.lut3d_enable) ?
- MCM_LUT_ENABLE : MCM_LUT_DISABLE;
-}
-
-static void fl_get_lut_mode(
- enum dc_cm_lut_swizzle swizzle,
- enum hubp_3dlut_fl_mode *mode,
- enum hubp_3dlut_fl_addressing_mode *addr_mode,
- enum hubp_3dlut_fl_width *width)
-{
- /* size was previously hard-coded to TRANSFORMED in local_mcm,
- * preserve identical behavior (transformed width).
- */
- *width = hubp_3dlut_fl_width_17;
-
- switch (swizzle) {
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- *mode = hubp_3dlut_fl_mode_native_1;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- *mode = hubp_3dlut_fl_mode_native_2;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_1D_PACKED_LINEAR:
- *mode = hubp_3dlut_fl_mode_transform;
- *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
- break;
- default:
- *mode = hubp_3dlut_fl_mode_disable;
- *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- }
-}
-
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
const struct dc_plane_cm *cm,
struct mpc *mpc,
- bool lut_bank_a,
int mpcc_id)
{
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
union mcm_lut_params m_lut_params = {0};
- enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, lut1d_xable;
- enum hubp_3dlut_fl_mode mode;
- enum hubp_3dlut_fl_addressing_mode addr_mode;
- enum hubp_3dlut_fl_format format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
- enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_17;
-
struct dc *dc = hubp->ctx->dc;
- struct hubp_fl_3dlut_config fl_config;
struct mpc_fl_3dlut_config mpc_fl_config;
struct dc_stream_state *stream = pipe_ctx->stream;
@@ -577,19 +430,24 @@ bool dcn42_program_rmcm_luts(
// true->false when it can be allocated at DI time
struct dc_rmcm_3dlut *rmcm_3dlut = dc_stream_get_3dlut_for_stream(dc, stream, false);
+ bool lut_enable = false;
+ bool lut_bank_a = true;
+
//check to see current pipe is part of a stream with allocated rmcm 3dlut
if (!rmcm_3dlut)
return false;
- /* rmcm_tmz was previously zero-initialized in local_mcm,
- * preserve identical behavior.
+ /* Determine the LUT bank currently active in HW and switch to the other
+ * bank to preserve double-buffering (mirrors dcn401_set_mcm_luts).
*/
- rmcm_3dlut->protection_bits = 0;
+ if (mpc->funcs->rmcm.get_3dlut_mode)
+ mpc->funcs->rmcm.get_3dlut_mode(mpc, mpcc_id, &lut_enable, &lut_bank_a);
- dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
+ if (lut_enable)
+ lut_bank_a = !lut_bank_a;
/* Shaper */
- {
+ if (cm->flags.bits.shaper_enable) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (cm->shaper_func.type == TF_TYPE_HWPWL) {
@@ -615,56 +473,19 @@ bool dcn42_program_rmcm_luts(
/* 3DLUT */
if (!cm->flags.bits.lut3d_dma_enable) {
- /* SYSMEM path — no DMA 3DLUT available.
- * Previously this was treated as a no-op for the DMA/VIDMEM
- * programming, preserve identical behavior.
+ /* RMCM host (non-DMA) 3DLUT load is not implemented; fail fast
+ * instead of silently reporting success
*/
- memset(&m_lut_params, 0, sizeof(m_lut_params));
+ BREAK_TO_DEBUGGER();
+ return false;
} else {
- /* VIDMEM (3DLUT DMA Fast Load) */
-
- fl_get_lut_mode(cm->lut3d_dma.swizzle,
- &mode,
- &addr_mode,
- &width);
-
- if (!dc_is_rmcm_3dlut_supported(hubp, mpc) ||
- !mpc->funcs->rmcm.is_config_supported(
- (width == hubp_3dlut_fl_width_17 ||
- width == hubp_3dlut_fl_width_transformed) ? 17 : 33))
+ if (!dc_is_rmcm_3dlut_supported(hubp, mpc))
return false;
- // setting native or transformed mode,
- dc_get_lut_mode(cm->lut3d_dma.swizzle, &mode, &addr_mode);
-
//seems to be only for the MCM
- dc_get_lut_format(cm->lut3d_dma.format, &format);
-
- dc_get_lut_xbar(
- &crossbar_bit_slice_cr_r,
- &crossbar_bit_slice_y_g,
- &crossbar_bit_slice_cb_b);
-
- fl_config.mode = mode;
- fl_config.enabled = lut3d_xable != MCM_LUT_DISABLE;
- fl_config.address = cm->lut3d_dma.addr;
- fl_config.format = format;
- fl_config.crossbar_bit_slice_y_g = crossbar_bit_slice_y_g;
- fl_config.crossbar_bit_slice_cb_b = crossbar_bit_slice_cb_b;
- fl_config.crossbar_bit_slice_cr_r = crossbar_bit_slice_cr_r;
- fl_config.width = width;
- fl_config.protection_bits = rmcm_3dlut->protection_bits;
- fl_config.addr_mode = addr_mode;
- fl_config.layout = cm->lut3d_dma.swizzle;
- fl_config.bias = cm->lut3d_dma.bias;
- fl_config.scale = cm->lut3d_dma.scale;
-
- mpc_fl_config.enabled = fl_config.enabled;
- mpc_fl_config.width = width;
+ mpc_fl_config.enabled = cm->flags.bits.lut3d_enable != 0u;
+ mpc_fl_config.size = cm->lut3d_dma.size;
mpc_fl_config.select_lut_bank_a = lut_bank_a;
- /* bit_depth was previously zero-initialized in local_mcm,
- * preserve identical behavior.
- */
mpc_fl_config.bit_depth = 0;
mpc_fl_config.hubp_index = hubp->inst;
mpc_fl_config.bias = cm->lut3d_dma.bias;
@@ -676,7 +497,12 @@ bool dcn42_program_rmcm_luts(
//2. program RMCM - 3dlut reg programming
mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, mpcc_id);
- hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config);
+ /* HUBP */
+ if (hubp->funcs->hubp_program_3dlut_fl_config)
+ hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
+
+ if (hubp->funcs->hubp_program_3dlut_fl_addr)
+ hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
//3. power on the block
mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true);
@@ -685,261 +511,31 @@ bool dcn42_program_rmcm_luts(
return true;
}
-void dcn42_populate_mcm_luts(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
- bool lut_bank_a)
-{
- struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
- struct hubp *hubp = pipe_ctx->plane_res.hubp;
- int mpcc_id = hubp->inst;
- struct mpc *mpc = dc->res_pool->mpc;
- union mcm_lut_params m_lut_params;
- const bool lut3d_dma = !!cm->flags.bits.lut3d_dma_enable;
- enum hubp_3dlut_fl_format format = 0;
- enum hubp_3dlut_fl_mode mode;
- /* Width was previously hard-coded to TRANSFORMED via local_mcm build,
- * preserve identical behavior.
- */
- enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_transformed;
- enum hubp_3dlut_fl_addressing_mode addr_mode;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
- enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
- enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
- enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
- bool rval;
-
- dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
-
- //MCM - setting its location (Before/After) blender
- //mpc_mcm_post_blend was previously zero-initialized in local_mcm,
- //preserve identical behavior.
- dcn42_set_mcm_location_post_blend(
- dc,
- pipe_ctx,
- false);
-
- //RMCM - 3dLUT+Shaper
- if (cm->flags.bits.rmcm_enable &&
- is_rmcm_3dlut_fl_supported(dc))
- dcn42_program_rmcm_luts(
- hubp,
- pipe_ctx,
- cm,
- mpc,
- lut_bank_a,
- mpcc_id);
-
- /* 1D LUT */
- {
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (cm->blend_func.type == TF_TYPE_HWPWL)
- m_lut_params.pwl = &cm->blend_func.pwl;
- else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
- &cm->blend_func,
- &dpp_base->regamma_params, false);
- m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
- }
- if (m_lut_params.pwl) {
- if (mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
- }
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
- }
-
- /* Shaper */
- if (cm->flags.bits.lut3d_enable) {
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (cm->shaper_func.type == TF_TYPE_HWPWL)
- m_lut_params.pwl = &cm->shaper_func.pwl;
- else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- ASSERT(false);
- rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
- &cm->shaper_func,
- &dpp_base->regamma_params, true);
- m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
- }
- if (m_lut_params.pwl) {
- if (mpc->funcs->mcm.populate_lut)
- mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
- }
- }
-
- /* 3DLUT */
- if (!lut3d_dma) {
- /* SYSMEM (legacy lut3d_func) */
- memset(&m_lut_params, 0, sizeof(m_lut_params));
- if (hubp->funcs->hubp_enable_3dlut_fl)
- hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
-
- if (cm->lut3d_func.state.bits.initialized) {
- m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
- if (mpc->funcs->populate_lut)
- mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
- mpcc_id);
- }
- } else {
- /* VIDMEM (3DLUT DMA Fast Load) */
-
- //check for support
- if (mpc->funcs->mcm.is_config_supported &&
- !mpc->funcs->mcm.is_config_supported(width))
- return;
-
- if (mpc->funcs->program_lut_read_write_control)
- mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
- if (mpc->funcs->program_lut_mode)
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
-
- if (hubp->funcs->hubp_program_3dlut_fl_addr)
- hubp->funcs->hubp_program_3dlut_fl_addr(hubp, cm->lut3d_dma.addr);
-
- /* bit_depth was previously zero-initialized in local_mcm,
- * preserve identical behavior.
- */
- if (mpc->funcs->mcm.program_bit_depth)
- mpc->funcs->mcm.program_bit_depth(mpc, 0, mpcc_id);
-
- switch (cm->lut3d_dma.swizzle) {
- case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
- mode = hubp_3dlut_fl_mode_native_1;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
- mode = hubp_3dlut_fl_mode_native_2;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- case CM_LUT_1D_PACKED_LINEAR:
- mode = hubp_3dlut_fl_mode_transform;
- addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
- break;
- default:
- mode = hubp_3dlut_fl_mode_disable;
- addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
- break;
- }
- if (hubp->funcs->hubp_program_3dlut_fl_mode)
- hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
-
- if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
- hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
-
- switch (cm->lut3d_dma.format) {
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
- format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
- format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
- break;
- case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
- format = hubp_3dlut_fl_format_float_fp1_5_10;
- break;
- default:
- break;
- }
- if (hubp->funcs->hubp_program_3dlut_fl_format)
- hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
- if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
- mpc->funcs->mcm.program_bias_scale) {
- mpc->funcs->mcm.program_bias_scale(mpc,
- cm->lut3d_dma.bias,
- cm->lut3d_dma.scale,
- mpcc_id);
- hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
- cm->lut3d_dma.bias,
- cm->lut3d_dma.scale);
- }
-
- /* component_order was previously hard-coded to RGBA in local_mcm,
- * preserve identical behavior.
- */
- crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
- crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
- crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
-
- if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
- hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
- crossbar_bit_slice_cr_r,
- crossbar_bit_slice_y_g,
- crossbar_bit_slice_cb_b);
-
- if (mpc->funcs->mcm.program_lut_read_write_control)
- mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
-
- if (mpc->funcs->mcm.program_3dlut_size)
- mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
-
- if (mpc->funcs->update_3dlut_fast_load_select)
- mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
-
- if (hubp->funcs->hubp_enable_3dlut_fl)
- hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
- else {
- if (mpc->funcs->program_lut_mode) {
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
- }
- }
- }
-}
-
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state)
{
- struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
- int mpcc_id = pipe_ctx->plane_res.hubp->inst;
- struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
- struct mpc *mpc = dc->res_pool->mpc;
bool result;
- const struct pwl_params *lut_params = NULL;
- bool rval;
-
- if (plane_state->cm.flags.bits.lut3d_dma_enable) {
- dcn42_populate_mcm_luts(dc, pipe_ctx, &plane_state->cm, plane_state->lut_bank_a);
- return true;
- }
- mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
- pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
- // 1D LUT
- if (plane_state->cm.blend_func.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->cm.blend_func.pwl;
- else if (plane_state->cm.blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->cm.blend_func,
- &dpp_base->regamma_params, false);
- lut_params = rval ? &dpp_base->regamma_params : NULL;
- }
- result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
- lut_params = NULL;
-
- // Shaper
- if (plane_state->cm.shaper_func.type == TF_TYPE_HWPWL)
- lut_params = &plane_state->cm.shaper_func.pwl;
- else if (plane_state->cm.shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
- // TODO: dpp_base replace
- rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->cm.shaper_func,
- &dpp_base->shaper_params, true);
- lut_params = rval ? &dpp_base->shaper_params : NULL;
- }
- result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+ /* MCM */
+ result = dcn401_set_mcm_luts(pipe_ctx, plane_state);
- // 3D
- if (mpc->funcs->program_3dlut) {
- if (plane_state->cm.lut3d_func.state.bits.initialized == 1)
- result &= mpc->funcs->program_3dlut(mpc, &plane_state->cm.lut3d_func.lut_3d, mpcc_id);
- else
- result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
+ /* RMCM */
+ {
+ struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ const struct dc_plane_cm *cm = &plane_state->cm;
+ struct mpc *mpc = dc->res_pool->mpc;
+ int mpcc_id = hubp->inst;
+
+ if (cm->flags.bits.rmcm_enable && cm->flags.bits.lut3d_dma_enable) {
+ /* TODO - move RMCM to its own block */
+ dcn42_program_rmcm_luts(
+ hubp,
+ pipe_ctx,
+ cm,
+ mpc,
+ mpcc_id);
+ }
}
return result;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
index c469e7535114..c4cfeed45b19 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
@@ -18,17 +18,11 @@ void dcn42_program_cm_hist(
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
-void dcn42_populate_mcm_luts(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
- bool lut_bank_a);
-
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
const struct dc_plane_cm *cm,
struct mpc *mpc,
- bool lut_bank_a,
int mpcc_id);
void dcn42_hardware_release(struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
index 49c13611a518..ba12a97a220f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
@@ -155,8 +155,6 @@ static const struct hwseq_private_funcs dcn42_private_funcs = {
.calculate_dccg_k1_k2_values = NULL,
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
- .populate_mcm_luts = NULL,
- .perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
.program_cm_hist = dcn42_program_cm_hist,
.dpp_root_clock_control = dcn35_dpp_root_clock_control,
.dpstream_root_clock_control = dcn35_dpstream_root_clock_control,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
index 5f4f32d516d5..1c908964153b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
@@ -166,8 +166,6 @@ static const struct hwseq_private_funcs dcn60_private_funcs = {
.calculate_dccg_k1_k2_values = NULL,
.apply_single_controller_ctx_to_hw = dcn60_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn401_reset_back_end_for_pipe,
- .populate_mcm_luts = NULL,
- .perform_3dlut_wa_unlock = dcn401_perform_3dlut_wa_unlock,
.program_cm_hist = dcn42_program_cm_hist,
.program_pipe = dcn401_program_pipe,
.program_pipe_sequence = dcn401_program_pipe_sequence,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index c4296b8390f2..cdf2562a9a40 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -1506,7 +1506,7 @@ struct hw_sequencer_funcs {
void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace,
uint16_t *matrix, int opp_id);
- void (*trigger_3dlut_dma_load)(struct dc *dc, struct pipe_ctx *pipe_ctx);
+ void (*trigger_3dlut_dma_load)(struct pipe_ctx *pipe_ctx);
/* VM Related */
int (*init_sys_ctx)(struct dce_hwseq *hws,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
index 31ace62a37d9..0f7881a21462 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
@@ -58,7 +58,6 @@ struct dc_state;
struct dc_stream_status;
struct dc_writeback_info;
struct dchub_init_data;
-struct dc_plane_cm;
struct dc_static_screen_params;
struct resource_pool;
struct resource_context;
@@ -218,10 +217,6 @@ struct hwseq_private_funcs {
void (*reset_back_end_for_pipe)(struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_state *context);
- void (*populate_mcm_luts)(struct dc *dc,
- struct pipe_ctx *pipe_ctx,
- const struct dc_plane_cm *cm,
- bool lut_bank_a);
void (*perform_3dlut_wa_unlock)(struct pipe_ctx *pipe_ctx);
void (*wait_for_pipe_update_if_needed)(struct dc *dc, struct pipe_ctx *pipe_ctx, bool is_surface_update_only);
void (*set_wait_for_update_needed_for_pipe)(struct dc *dc, struct pipe_ctx *pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 6d6eda0e7e9d..9dc9317c28a4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode {
enum hubp_3dlut_fl_width {
hubp_3dlut_fl_width_17 = 17,
hubp_3dlut_fl_width_33 = 33,
- hubp_3dlut_fl_width_transformed = 4916, //mpc default
+ hubp_3dlut_fl_width_17_transformed = 4916, //mpc default
};
enum hubp_3dlut_fl_crossbar_bit_slice {
@@ -99,22 +99,6 @@ enum hubp_3dlut_fl_crossbar_bit_slice {
hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3
};
-struct hubp_fl_3dlut_config {
- bool enabled;
- enum hubp_3dlut_fl_width width;
- enum hubp_3dlut_fl_mode mode;
- enum hubp_3dlut_fl_format format;
- uint16_t bias;
- uint16_t scale;
- struct dc_plane_address address;
- enum hubp_3dlut_fl_addressing_mode addr_mode;
- enum dc_cm_lut_swizzle layout;
- uint8_t protection_bits;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
- enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
-};
-
struct hubp {
const struct hubp_funcs *funcs;
struct dc_context *ctx;
@@ -289,24 +273,15 @@ struct hubp_funcs {
void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, struct dml2_hubp_pipe_mcache_regs *mcache_regs);
- void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t bias, uint16_t scale);
- void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp,
- enum hubp_3dlut_fl_mode mode);
- void (*hubp_program_3dlut_fl_format)(struct hubp *hubp,
- enum hubp_3dlut_fl_format format);
void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp,
- const struct dc_plane_address address);
+ const struct dc_plane_address *address);
+ void (*hubp_program_3dlut_fl_config)(struct hubp *hubp,
+ const struct dc_3dlut_dma *config);
void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int refcyc_per_3dlut_group);
void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable);
- void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
- void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum hubp_3dlut_fl_width width);
- void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t protection_bits);
void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
- enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
+ enum dc_cm_lut_pixel_format format);
uint32_t (*hubp_get_3dlut_fl_done)(struct hubp *hubp);
- void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg);
void (*hubp_clear_tiling)(struct hubp *hubp);
uint32_t (*hubp_get_current_read_line)(struct hubp *hubp);
uint32_t (*hubp_get_det_config_error)(struct hubp *hubp);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 54eb2eba68bf..d863f4bdccad 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -54,6 +54,7 @@
#include "dc_hw_types.h"
#include "hw_shared.h"
#include "transform.h"
+#include "dc_types.h"
#define MAX_MPCC 6
#define MAX_OPP 6
@@ -101,13 +102,6 @@ enum mpcc_movable_cm_location {
MPCC_MOVABLE_CM_LOCATION_AFTER,
};
-enum MCM_LUT_XABLE {
- MCM_LUT_DISABLE,
- MCM_LUT_DISABLED = MCM_LUT_DISABLE,
- MCM_LUT_ENABLE,
- MCM_LUT_ENABLED = MCM_LUT_ENABLE,
-};
-
enum MCM_LUT_ID {
MCM_LUT_3DLUT,
MCM_LUT_1DLUT,
@@ -116,7 +110,7 @@ enum MCM_LUT_ID {
struct mpc_fl_3dlut_config {
bool enabled;
- uint16_t width;
+ enum dc_cm_lut_size size;
bool select_lut_bank_a;
uint16_t bit_depth;
int hubp_index;
@@ -1075,8 +1069,11 @@ struct mpc_funcs {
*
* void
*/
- void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
- bool lut_bank_a, int mpcc_id);
+ void (*populate_lut)(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const union mcm_lut_params *params,
+ const bool lut_bank_a,
+ const int mpcc_id);
/**
* @program_lut_read_write_control:
@@ -1087,13 +1084,18 @@ struct mpc_funcs {
* - [in/out] mpc - MPC context.
* - [in] id
* - [in] lut_bank_a
+ * - [in] bit_depth
* - [in] mpcc_id
*
* Return:
*
* void
*/
- void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
+ void (*program_lut_read_write_control)(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const bool lut_bank_a,
+ const unsigned int bit_depth,
+ const int mpcc_id);
/**
* @program_lut_mode:
@@ -1103,33 +1105,44 @@ struct mpc_funcs {
* Parameters:
* - [in/out] mpc - MPC context.
* - [in] id
- * - [in] xable
+ * - [in] enable
* - [in] lut_bank_a
+ * - [in] size
* - [in] mpcc_id
*
* Return:
*
* void
*/
- void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable,
- bool lut_bank_a, int mpcc_id);
+ void (*program_lut_mode)(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const bool enable,
+ const bool lut_bank_a,
+ const enum dc_cm_lut_size size,
+ const int mpcc_id);
- /**
- * @mcm:
- *
- * MPC MCM new HW sequential programming functions
- */
- struct {
- void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
- void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
- void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
- bool (*is_config_supported)(uint32_t width);
- void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
- bool lut_bank_a, bool enabled, int mpcc_id);
- void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params,
- bool lut_bank_a, int mpcc_id);
- } mcm;
+ /**
+ * @get_lut_mode:
+ *
+ * Obtains enablement and ram bank status.
+ *
+ * Parameters:
+ * - [in/out] mpc - MPC context.
+ * - [in] id
+ * - [in] mpcc_id
+ * - [out] enable
+ * - [out] lut_bank_a
+ *
+ * Return:
+ *
+ * void
+ */
+ void (*get_lut_mode)(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const int mpcc_id,
+ bool *enable,
+ bool *lut_bank_a);
/**
* @rmcm:
@@ -1142,9 +1155,11 @@ struct mpc_funcs {
void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
bool lut_bank_a, bool enabled, int mpcc_id);
- void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
- bool lut_bank_a, int mpcc_id);
- void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
+ void (*program_lut_mode)(struct mpc *mpc,
+ bool enable,
+ bool lut_bank_a,
+ int mpcc_id);
+ void (*program_3dlut_size)(struct mpc *mpc, const enum dc_cm_lut_size size, int mpcc_id);
void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
bool (*is_config_supported)(uint32_t width);
@@ -1152,6 +1167,8 @@ struct mpc_funcs {
void (*power_on_shaper_3dlut)(struct mpc *mpc, uint32_t mpcc_id, bool power_on);
void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params,
bool lut_bank_a, int mpcc_id);
+ void (*get_3dlut_mode)(struct mpc *mpc, int mpcc_id,
+ bool *enable, bool *lut_bank_a);
} rmcm;
};
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
index d8a4e604a34e..df92d8008fe6 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
@@ -73,56 +73,15 @@ void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_locati
}
}
-static enum dc_lut_mode get3dlut_config(
- struct mpc *mpc,
- bool *is_17x17x17,
- bool *is_12bits_color_channel,
- int mpcc_id)
-{
- uint32_t i_mode, i_enable_10bits, lut_size;
- enum dc_lut_mode mode;
- struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
-
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
- MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
-
- REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
- MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
-
- switch (i_mode) {
- case 0:
- mode = LUT_BYPASS;
- break;
- case 1:
- mode = LUT_RAM_A;
- break;
- case 2:
- mode = LUT_RAM_B;
- break;
- default:
- mode = LUT_BYPASS;
- break;
- }
- if (i_enable_10bits > 0)
- *is_12bits_color_channel = false;
- else
- *is_12bits_color_channel = true;
-
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
-
- if (lut_size == 0)
- *is_17x17x17 = true;
- else
- *is_17x17x17 = false;
-
- return mode;
-}
-
-void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id)
+void mpc401_populate_lut(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const union mcm_lut_params *params,
+ const bool lut_bank_a,
+ const int mpcc_id)
{
const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
- const struct pwl_params *lut1d = params.pwl;
- const struct pwl_params *lut_shaper = params.pwl;
+ const struct pwl_params *lut1d = params->pwl;
+ const struct pwl_params *lut_shaper = params->pwl;
bool is_17x17x17;
bool is_12bits_color_channel;
const struct dc_rgb *lut0;
@@ -131,7 +90,7 @@ void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union
const struct dc_rgb *lut3;
int lut_size0;
int lut_size;
- const struct tetrahedral_params *lut3d = params.lut3d;
+ const struct tetrahedral_params *lut3d = params->lut3d;
switch (id) {
case MCM_LUT_1DLUT:
@@ -174,8 +133,6 @@ void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
- get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
-
is_17x17x17 = !lut3d->use_tetrahedral_9;
is_12bits_color_channel = lut3d->use_12bits;
if (is_17x17x17) {
@@ -198,8 +155,6 @@ void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union
sizeof(lut3d->tetrahedral_9.lut1[0]);
}
- mpc32_select_3dlut_ram(mpc, next_mode,
- is_12bits_color_channel, mpcc_id);
mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
if (is_12bits_color_channel)
mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
@@ -232,46 +187,69 @@ void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union
}
+static uint32_t mpc401_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size cm_size)
+{
+ uint32_t size = 0;
+
+ switch (cm_size) {
+ case CM_LUT_SIZE_999:
+ size = 1;
+ break;
+ case CM_LUT_SIZE_171717:
+ size = 0;
+ break;
+ default:
+ /* invalid LUT size */
+ ASSERT(false);
+ size = 0;
+ break;
+ }
+
+ return size;
+}
+
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- const enum MCM_LUT_XABLE xable,
- bool lut_bank_a,
- int mpcc_id)
+ const bool enable,
+ const bool lut_bank_a,
+ const enum dc_cm_lut_size size,
+ const int mpcc_id)
{
+ uint32_t lut_size;
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
- switch (xable) {
- case MCM_LUT_DISABLE:
+ if (enable) {
+ lut_size = mpc401_cm_lut_size_to_3dlut_size(size);
+ REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
+ MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2,
+ MPCC_MCM_3DLUT_SIZE, lut_size);
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0);
- break;
- case MCM_LUT_ENABLE:
- REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2);
- break;
}
break;
case MCM_LUT_SHAPER:
- switch (xable) {
- case MCM_LUT_DISABLE:
- REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
- break;
- case MCM_LUT_ENABLE:
+ if (enable) {
REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
- break;
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
+ REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
}
break;
case MCM_LUT_1DLUT:
- switch (xable) {
- case MCM_LUT_DISABLE:
- REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
- MPCC_MCM_1DLUT_MODE, 0);
- break;
- case MCM_LUT_ENABLE:
+ if (enable) {
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE, 2);
- break;
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
+ REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_MODE, 0);
}
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
@@ -279,14 +257,20 @@ void mpc401_program_lut_mode(
}
}
-void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
+void mpc401_program_lut_read_write_control(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const bool lut_bank_a,
+ const unsigned int bit_depth,
+ const int mpcc_id)
{
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
- REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
+ REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+ MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 : 0,
+ MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
break;
case MCM_LUT_SHAPER:
mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
@@ -605,6 +589,44 @@ void mpc401_get_gamut_remap(struct mpc *mpc,
coef_format, ARRAY_SIZE(arr_reg_val));
}
+void mpc401_get_lut_mode(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const int mpcc_id,
+ bool *enable,
+ bool *lut_bank_a)
+{
+ struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
+
+ uint32_t lut_mode = 0;
+ uint32_t lut_select = 0;
+
+ *enable = false;
+ *lut_bank_a = true;
+
+ switch (id) {
+ case MCM_LUT_SHAPER:
+ REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id],
+ MPCC_MCM_SHAPER_MODE_CURRENT, &lut_mode);
+ *enable = lut_mode != 0;
+ *lut_bank_a = lut_mode != 2;
+ break;
+ case MCM_LUT_1DLUT:
+ REG_GET_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_MODE_CURRENT, &lut_mode,
+ MPCC_MCM_1DLUT_SELECT_CURRENT, &lut_select);
+ *enable = lut_mode != 0;
+ *lut_bank_a = lut_mode == 0 || lut_select == 0;
+ break;
+ case MCM_LUT_3DLUT:
+ default:
+ REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
+ MPCC_MCM_3DLUT_MODE_CURRENT, &lut_mode);
+ *enable = lut_mode != 0;
+ *lut_bank_a = lut_mode != 2;
+ break;
+ }
+}
+
static const struct mpc_funcs dcn401_mpc_funcs = {
.read_mpcc_state = mpc1_read_mpcc_state,
.insert_plane = mpc1_insert_plane,
@@ -643,6 +665,7 @@ static const struct mpc_funcs dcn401_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
+ .get_lut_mode = mpc401_get_lut_mode,
};
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
index 3d00d9497ed2..75fa05ed2b22 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
@@ -206,21 +206,32 @@ void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
int num_rmu);
void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id);
-void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
- bool lut_bank_a, int mpcc_id);
+void mpc401_populate_lut(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const union mcm_lut_params *params,
+ bool lut_bank_a,
+ int mpcc_id);
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- const enum MCM_LUT_XABLE xable,
- bool lut_bank_a,
- int mpcc_id);
+ const bool enable,
+ const bool lut_bank_a,
+ const enum dc_cm_lut_size size,
+ const int mpcc_id);
+
+void mpc401_get_lut_mode(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const int mpcc_id,
+ bool *enable,
+ bool *lut_bank_a);
void mpc401_program_lut_read_write_control(
struct mpc *mpc,
const enum MCM_LUT_ID id,
- bool lut_bank_a,
- int mpcc_id);
+ const bool lut_bank_a,
+ const unsigned int bit_depth,
+ const int mpcc_id);
void mpc401_set_gamut_remap(
struct mpc *mpc,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
index 38c0e8f96d40..5a888e1e1cc5 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
@@ -63,154 +63,6 @@ void mpc42_update_blending(
mpcc->blnd_cfg = *blnd_cfg;
}
-/* Shaper functions */
-void mpc42_power_on_shaper_3dlut(
- struct mpc *mpc,
- uint32_t mpcc_id,
- bool power_on)
-{
- uint32_t power_status_shaper = 2;
- uint32_t power_status_3dlut = 2;
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- int max_retries = 10;
-
- REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
- MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
- REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
- MPCC_MCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1:0);
- /* wait for memory to fully power up */
- if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
- REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
- REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
- }
-
- /*read status is not mandatory, it is just for debugging*/
- REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper);
- REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
-
- if (power_status_shaper != 0 && power_on == true)
- BREAK_TO_DEBUGGER();
-
- if (power_status_3dlut != 0 && power_on == true)
- BREAK_TO_DEBUGGER();
-}
-
-void mpc42_configure_shaper_lut(
- struct mpc *mpc,
- bool is_ram_a,
- uint32_t mpcc_id)
-{
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
- REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
- MPCC_MCM_SHAPER_SCALE_B, 0x7000);
- REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
- MPCC_MCM_SHAPER_SCALE_G, 0x7000);
- REG_UPDATE(MPCC_MCM_SHAPER_SCALE_R[mpcc_id],
- MPCC_MCM_SHAPER_SCALE_R, 0x7000);
- REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
- MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
- REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
- MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
- REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0);
-}
-
-
-void mpc42_program_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
-{
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- uint32_t size = 0xff;
-
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
-
- REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE,
- (width == 33) ? 2 :
- (width == 17) ? 0 : 2);
-
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
-}
-
-void mpc42_program_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
-{
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
- REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_R[mpcc_id],
- MPCC_MCM_3DLUT_OUT_OFFSET_R, bias,
- MPCC_MCM_3DLUT_OUT_SCALE_R, scale);
-
- REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_G[mpcc_id],
- MPCC_MCM_3DLUT_OUT_OFFSET_G, bias,
- MPCC_MCM_3DLUT_OUT_SCALE_G, scale);
-
- REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_B[mpcc_id],
- MPCC_MCM_3DLUT_OUT_OFFSET_B, bias,
- MPCC_MCM_3DLUT_OUT_SCALE_B, scale);
-}
-
-void mpc42_program_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_id)
-{
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
- REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK, 0xF);
-
- //program bit_depth
- REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
- MPCC_MCM_3DLUT_30BIT_EN,
- (bit_depth == 10) ? 1 : 0);
-}
-
-bool mpc42_is_config_supported(uint32_t width)
-{
- if (width == 17)
- return true;
-
- return false;
-}
-
-void mpc42_populate_lut(struct mpc *mpc, const union mcm_lut_params params,
- bool lut_bank_a, int mpcc_id)
-{
- const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
- const struct pwl_params *lut_shaper = params.pwl;
-
- if (lut_shaper == NULL)
- return;
- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
- mpc42_power_on_shaper_3dlut(mpc, mpcc_id, true);
-
- mpc42_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
-
- if (next_mode == LUT_RAM_A)
- mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id);
- else
- mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id);
-
- mpc32_program_shaper_lut(
- mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id);
-
- mpc42_power_on_shaper_3dlut(mpc, mpcc_id, false);
-}
-
-void mpc42_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id,
- bool lut_bank_a, bool enabled, int mpcc_id)
-{
- struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-
- switch (id) {
- case MCM_LUT_3DLUT:
- REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE,
- (!enabled) ? 0 :
- (lut_bank_a) ? 1 : 2);
- REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
- break;
- case MCM_LUT_SHAPER:
- mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
- break;
- default:
- break;
- }
-}
-
/* RMCM Shaper functions */
void mpc42_power_on_rmcm_shaper_3dlut(
struct mpc *mpc,
@@ -674,32 +526,47 @@ void mpc42_program_rmcm_lut_read_write_control(struct mpc *mpc, const enum MCM_L
}
}
-void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
- bool lut_bank_a, int mpcc_id)
+void mpc42_program_lut_mode(struct mpc *mpc,
+ bool enable,
+ bool lut_bank_a,
+ int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- switch (xable) {
- case MCM_LUT_DISABLE:
+ if (enable) {
+ REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+ } else {
REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, 0);
+ }
+}
+
+static uint32_t mpc42_get_rmcm_3dlut_width(
+ const enum dc_cm_lut_size size)
+{
+ uint32_t width = 0;
+
+ switch (size) {
+ case CM_LUT_SIZE_333333:
+ width = 2;
break;
- case MCM_LUT_ENABLE:
- REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+ case CM_LUT_SIZE_171717:
+ default:
+ width = 0;
break;
}
+
+ return width;
}
-void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
+void mpc42_program_rmcm_3dlut_size(struct mpc *mpc,
+ const enum dc_cm_lut_size size,
+ int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
- uint32_t size = 0xff;
-
- REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
-
- REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE,
- (width == 33) ? 2 : 0);
+ uint32_t width = mpc42_get_rmcm_3dlut_width(size);
- REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
+ REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id],
+ MPC_RMCM_3DLUT_SIZE, width);
}
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
@@ -731,14 +598,6 @@ void mpc42_program_rmcm_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_
(bit_depth == 10) ? 1 : 0);
}
-bool mpc42_is_rmcm_config_supported(uint32_t width)
-{
- if (width == 17 || width == 33)
- return true;
-
- return false;
-}
-
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,
@@ -746,6 +605,7 @@ void mpc42_set_fl_config(
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+ uint32_t width = mpc42_get_rmcm_3dlut_width(cfg->size);
/*
From: Jie Zhou
@@ -786,7 +646,7 @@ void mpc42_set_fl_config(
//width
REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id],
- MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0,
+ MPC_RMCM_3DLUT_SIZE, width,
MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : (cfg->select_lut_bank_a) ? 1 : 2);
//connect to hubp
@@ -799,181 +659,23 @@ void mpc42_set_fl_config(
REG_UPDATE(MPC_RMCM_CNTL[mpcc_id], MPC_RMCM_CNTL, cfg->enabled ? 0 : 0xF);
}
-//static void rmcm_program_gamut_remap(
-// struct mpc *mpc,
-// unsigned int mpcc_id,
-// const uint16_t *regval,
-// enum mpcc_gamut_remap_id gamut_remap_block_id,
-// enum mpcc_gamut_remap_mode_select mode_select)
-//{
-// struct color_matrices_reg gamut_regs;
-// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-//
-// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
-// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
-// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
-// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
-// return;
-// }
-// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP) {
-//
-// if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0,
-// MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-// return;
-// }
-//
-// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
-// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
-// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
-// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
-//
-// switch (mode_select) {
-// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
-// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
-// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
-// break;
-// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
-// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
-// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
-// break;
-// default:
-// break;
-// }
-//
-// cm_helper_program_color_matrices(
-// mpc->ctx,
-// regval,
-// &gamut_regs);
-//
-// //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
-// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-// }
-//}
-
-//static bool is_mpc_legacy_gamut_id(enum mpcc_gamut_remap_id gamut_remap_block_id)
-//{
-// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
-// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
-// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
-// return true;
-// }
-// return false;
-//}
-//static void program_gamut_remap(
-// struct mpc *mpc,
-// unsigned int mpcc_id,
-// const uint16_t *regval,
-// enum mpcc_gamut_remap_id gamut_remap_block_id,
-// enum mpcc_gamut_remap_mode_select mode_select)
-//{
-// if (is_mpc_legacy_gamut_id(gamut_remap_block_id))
-// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
-// else
-// rmcm_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
-//}
-
-//void mpc42_set_gamut_remap(
-// struct mpc *mpc,
-// int mpcc_id,
-// const struct mpc_grph_gamut_adjustment *adjust)
-//{
-// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-// unsigned int i = 0;
-// uint32_t mode_select = 0;
-//
-// if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
-// /* Bypass / Disable if type is bypass or hw */
-// program_gamut_remap(mpc, mpcc_id, NULL,
-// adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0);
-// } else {
-// struct fixed31_32 arr_matrix[12];
-// uint16_t arr_reg_val[12];
-//
-// for (i = 0; i < 12; i++)
-// arr_matrix[i] = adjust->temperature_matrix[i];
-//
-// convert_float_matrix(arr_reg_val, arr_matrix, 12);
-//
-// if (is_mpc_legacy_gamut_id(adjust->mpcc_gamut_remap_block_id))
-// REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
-// MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
-// else
-// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id],
-// MPC_RMCM_GAMUT_REMAP_MODE_CURRENT, &mode_select);
-//
-// //If current set in use not set A (MODE_1), then use set A, otherwise use set B
-// if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
-// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
-// else
-// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
-//
-// program_gamut_remap(mpc, mpcc_id, arr_reg_val,
-// adjust->mpcc_gamut_remap_block_id, mode_select);
-// }
-//}
-
-//static void read_gamut_remap(struct mpc *mpc,
-// int mpcc_id,
-// uint16_t *regval,
-// enum mpcc_gamut_remap_id gamut_remap_block_id,
-// uint32_t *mode_select)
-//{
-// struct color_matrices_reg gamut_regs = {0};
-// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
-//
-// if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) {
-// mpc_read_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
-// }
-// if (gamut_remap_block_id == MPCC_RMCM_GAMUT_REMAP) {
-// //current coefficient set in use
-// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
-//
-// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
-// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
-// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
-// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
-//
-// switch (*mode_select) {
-// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
-// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
-// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
-// break;
-// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
-// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
-// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
-// break;
-// default:
-// break;
-// }
-// }
-//
-// if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-// cm_helper_read_color_matrices(
-// mpc42->base.ctx,
-// regval,
-// &gamut_regs);
-// }
-//}
-
-//void mpc42_get_gamut_remap(struct mpc *mpc,
-// int mpcc_id,
-// struct mpc_grph_gamut_adjustment *adjust)
-//{
-// uint16_t arr_reg_val[12] = {0};
-// uint32_t mode_select;
-//
-// read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select);
-//
-// if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
-// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
-// return;
-// }
-//
-// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
-// convert_hw_matrix(adjust->temperature_matrix,
-// arr_reg_val, ARRAY_SIZE(arr_reg_val));
-//}
+void mpc42_get_rmcm_3dlut_mode(
+ struct mpc *mpc,
+ int mpcc_id,
+ bool *enable,
+ bool *lut_bank_a)
+{
+ struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
+ uint32_t mode_current = 0;
+
+ REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_MODE_CURRENT, &mode_current);
+
+ /* MPC_RMCM_3DLUT_MODE encoding:
+ * 0 -> disabled, 1 -> bank A, 2 -> bank B
+ */
+ *enable = mode_current != 0;
+ *lut_bank_a = mode_current != 2;
+}
void mpc42_read_mpcc_state(
struct mpc *mpc,
@@ -1071,14 +773,7 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
- .mcm = {
- .program_lut_read_write_control = mpc42_program_lut_read_write_control,
- .program_3dlut_size = mpc42_program_3dlut_size,
- .program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
- .program_bit_depth = mpc42_program_bit_depth,
- .is_config_supported = mpc42_is_config_supported,
- .populate_lut = mpc42_populate_lut,
- },
+ .get_lut_mode = mpc401_get_lut_mode,
.rmcm = {
.enable_3dlut_fl = mpc42_enable_3dlut_fl,
.update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select,
@@ -1087,10 +782,10 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.program_3dlut_size = mpc42_program_rmcm_3dlut_size,
.program_bias_scale = mpc42_program_rmcm_3dlut_fast_load_bias_scale,
.program_bit_depth = mpc42_program_rmcm_bit_depth,
- .is_config_supported = mpc42_is_rmcm_config_supported,
.power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
.populate_lut = mpc42_populate_rmcm_lut,
.fl_3dlut_configure = mpc42_set_fl_config,
+ .get_3dlut_mode = mpc42_get_rmcm_3dlut_mode,
},
};
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
index 12a12c28e553..af3b90af5396 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
@@ -884,49 +884,6 @@ void dcn42_mpc_construct(struct dcn42_mpc *mpc401,
void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
-void mpc42_program_shaper_lutb_settings(
- struct mpc *mpc,
- const struct pwl_params *params,
- uint32_t mpcc_id);
-void mpc42_program_shaper_luta_settings(
- struct mpc *mpc,
- const struct pwl_params *params,
- uint32_t mpcc_id);
-void mpc42_configure_shaper_lut(
- struct mpc *mpc,
- bool is_ram_a,
- uint32_t mpcc_id);
-void mpc42_power_on_shaper_3dlut(
- struct mpc *mpc,
- uint32_t mpcc_id,
- bool power_on);
-void mpc42_program_3dlut_size(
- struct mpc *mpc,
- uint32_t width,
- int mpcc_id);
-void mpc42_program_3dlut_fl_bias_scale(
- struct mpc *mpc,
- uint16_t bias,
- uint16_t scale,
- int mpcc_id);
-void mpc42_program_bit_depth(
- struct mpc *mpc,
- uint16_t bit_depth,
- int mpcc_id);
-void mpc42_populate_lut(
- struct mpc *mpc,
- const union mcm_lut_params params,
- bool lut_bank_a,
- int mpcc_id);
-void mpc42_program_lut_read_write_control(
- struct mpc *mpc,
- const enum MCM_LUT_ID id,
- bool lut_bank_a,
- bool enabled,
- int mpcc_id);
-
-bool mpc42_is_config_supported(uint32_t width);
-
/* RMCM */
void mpc42_program_rmcm_shaper_lut(
struct mpc *mpc,
@@ -970,12 +927,12 @@ void mpc42_program_rmcm_lut_read_write_control(
int mpcc_id);
void mpc42_program_lut_mode(
struct mpc *mpc,
- const enum MCM_LUT_XABLE xable,
+ bool enable,
bool lut_bank_a,
int mpcc_id);
void mpc42_program_rmcm_3dlut_size(
struct mpc *mpc,
- uint32_t width,
+ const enum dc_cm_lut_size size,
int mpcc_id);
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(
struct mpc *mpc,
@@ -987,13 +944,17 @@ void mpc42_program_rmcm_bit_depth(
uint16_t bit_depth,
int mpcc_id);
-bool mpc42_is_rmcm_config_supported(uint32_t width);
-
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,
int mpcc_id);
+void mpc42_get_rmcm_3dlut_mode(
+ struct mpc *mpc,
+ int mpcc_id,
+ bool *enable,
+ bool *lut_bank_a);
+
void mpc42_read_mpcc_state(
struct mpc *mpc,
int mpcc_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
index f8a878ead67d..2c0b92854a9c 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.c
@@ -139,165 +139,123 @@ void mpc60_program_rmcm_lut_read_write_control(struct mpc *mpc, const enum MCM_L
}
}
-void mpc60_select_3dlut_ram(
- struct mpc *mpc,
- enum dc_lut_mode mode,
- bool is_color_channel_12bits,
- uint32_t mpcc_id)
+static void mpc60_program_lut_read_write_control(struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const bool lut_bank_a,
+ const unsigned int bit_depth,
+ const int mpcc_id)
{
- (void)mode;
struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
- REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
- MPCC_MCM_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0 : 1);
+ switch (id) {
+ case MCM_LUT_3DLUT:
+ mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
+ REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
+ MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 : 0);
+ break;
+ case MCM_LUT_SHAPER:
+ mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
+ break;
+ case MCM_LUT_1DLUT:
+ mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id);
+ break;
+ }
}
-static enum dc_lut_mode get3dlut_config(
- struct mpc *mpc,
- bool *is_17x17x17,
- bool *is_12bits_color_channel,
- int mpcc_id)
+static uint32_t mpc60_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size cm_size)
{
- uint32_t i_mode, i_enable_10bits, lut_size;
- enum dc_lut_mode mode;
- struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
+ uint32_t size = 0;
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
- MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
-
- REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
- MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
-
- switch (i_mode) {
- case 0:
- mode = LUT_BYPASS;
- break;
- case 1:
- mode = LUT_RAM_A;
+ switch (cm_size) {
+ case CM_LUT_SIZE_999:
+ size = 1;
break;
- case 2:
- mode = LUT_RAM_B;
+ case CM_LUT_SIZE_171717:
+ size = 0;
break;
default:
- mode = LUT_BYPASS;
+ /* invalid LUT size for MCM */
+ ASSERT(false);
+ size = 0;
break;
}
- if (i_enable_10bits > 0)
- *is_12bits_color_channel = false;
- else
- *is_12bits_color_channel = true;
-
- REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
-
- if (lut_size == 0)
- *is_17x17x17 = true;
- else
- *is_17x17x17 = false;
-
- return mode;
-}
-
-bool mpc60_program_3dlut(
- struct mpc *mpc,
- const struct tetrahedral_params *params,
- int mpcc_id)
-{
- enum dc_lut_mode mode;
- bool is_17x17x17;
- bool is_12bits_color_channel;
- const struct dc_rgb *lut0;
- const struct dc_rgb *lut1;
- const struct dc_rgb *lut2;
- const struct dc_rgb *lut3;
- int lut_size0;
- int lut_size;
-
- if (params == NULL) {
- mpc32_set_3dlut_mode(mpc, LUT_BYPASS, false, false, mpcc_id);
- return false;
- }
- mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
-
- mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
-
- if (mode == LUT_BYPASS || mode == LUT_RAM_B)
- mode = LUT_RAM_A;
- else
- mode = LUT_RAM_B;
-
- is_17x17x17 = !params->use_tetrahedral_9;
- is_12bits_color_channel = params->use_12bits;
- if (is_17x17x17) {
- lut0 = params->tetrahedral_17.lut0;
- lut1 = params->tetrahedral_17.lut1;
- lut2 = params->tetrahedral_17.lut2;
- lut3 = params->tetrahedral_17.lut3;
- lut_size0 = sizeof(params->tetrahedral_17.lut0) /
- sizeof(params->tetrahedral_17.lut0[0]);
- lut_size = sizeof(params->tetrahedral_17.lut1) /
- sizeof(params->tetrahedral_17.lut1[0]);
- } else {
- lut0 = params->tetrahedral_9.lut0;
- lut1 = params->tetrahedral_9.lut1;
- lut2 = params->tetrahedral_9.lut2;
- lut3 = params->tetrahedral_9.lut3;
- lut_size0 = sizeof(params->tetrahedral_9.lut0) /
- sizeof(params->tetrahedral_9.lut0[0]);
- lut_size = sizeof(params->tetrahedral_9.lut1) /
- sizeof(params->tetrahedral_9.lut1[0]);
- }
- mpc60_select_3dlut_ram(mpc, mode,
- is_12bits_color_channel, mpcc_id);
- mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
- if (is_12bits_color_channel)
- mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
- else
- mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id);
-
- mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id);
- if (is_12bits_color_channel)
- mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id);
- else
- mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id);
-
- mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id);
- if (is_12bits_color_channel)
- mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id);
- else
- mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id);
-
- mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id);
- if (is_12bits_color_channel)
- mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id);
- else
- mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id);
-
- mpc32_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
- is_17x17x17, mpcc_id);
-
- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
- mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
-
- return true;
+ return size;
}
-void mpc60_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
+static void mpc60_program_lut_mode(
+ struct mpc *mpc,
+ const enum MCM_LUT_ID id,
+ const bool enable,
+ const bool lut_bank_a,
+ const enum dc_cm_lut_size size,
+ const int mpcc_id)
{
+ uint32_t lut_size;
+ struct dcn60_mpc *mpc60 = TO_DCN60_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
- mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
+ if (enable) {
+ lut_size = mpc60_cm_lut_size_to_3dlut_size(size);
+ REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
+ MPCC_MCM_3DLUT_MODE, 1,
+ MPCC_MCM_3DLUT_SIZE, lut_size);
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
+ REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0);
+ }
break;
case MCM_LUT_SHAPER:
- mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
+ if (enable) {
+ REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
+ REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
+ }
break;
case MCM_LUT_1DLUT:
- mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id);
+ if (enable) {
+ REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_MODE, 2);
+ } else {
+ if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
+ mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
+ REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_MODE, 0);
+ }
+ REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
+ MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
break;
}
}
+static bool mpc60_program_3dlut(
+ struct mpc *mpc,
+ const struct tetrahedral_params *params,
+ int mpcc_id)
+{
+ union mcm_lut_params lut_params = { 0 };
+ lut_params.lut3d = params;
+
+ mpc60_program_lut_read_write_control(mpc,
+ MCM_LUT_3DLUT,
+ true,
+ params->use_12bits ? 12 : 10,
+ mpcc_id);
+ mpc401_populate_lut(mpc, MCM_LUT_3DLUT, &lut_params, true, mpcc_id);
+ mpc60_program_lut_mode(mpc,
+ MCM_LUT_3DLUT,
+ true,
+ true,
+ params->use_tetrahedral_9 ? CM_LUT_SIZE_999 : CM_LUT_SIZE_171717,
+ mpcc_id);
+
+ return true;
+}
+
static const struct mpc_funcs dcn60_mpc_funcs = {
.read_mpcc_state = mpc1_read_mpcc_state,
.insert_plane = mpc60_insert_plane,
@@ -328,15 +286,8 @@ static const struct mpc_funcs dcn60_mpc_funcs = {
.get_3dlut_fast_load_status = mpc401_get_3dlut_fast_load_status,
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc60_program_lut_read_write_control,
- .program_lut_mode = mpc401_program_lut_mode,
- .mcm = {
- .program_lut_read_write_control = mpc42_program_lut_read_write_control,
- .program_3dlut_size = mpc42_program_3dlut_size,
- .program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
- .program_bit_depth = mpc42_program_bit_depth,
- .is_config_supported = mpc42_is_config_supported,
- .populate_lut = mpc42_populate_lut,
- },
+ .program_lut_mode = mpc60_program_lut_mode,
+ .get_lut_mode = mpc401_get_lut_mode,
.rmcm = {
.enable_3dlut_fl = mpc42_enable_3dlut_fl,
.update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select,
@@ -345,9 +296,9 @@ static const struct mpc_funcs dcn60_mpc_funcs = {
.program_3dlut_size = mpc42_program_rmcm_3dlut_size,
.program_bias_scale = mpc42_program_rmcm_3dlut_fast_load_bias_scale,
.program_bit_depth = mpc42_program_rmcm_bit_depth,
- .is_config_supported = mpc42_is_rmcm_config_supported,
.power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
.populate_lut = mpc42_populate_rmcm_lut,
+ .get_3dlut_mode = mpc42_get_rmcm_3dlut_mode,
},
};
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
index 76d5c721f742..640a322d15c1 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn60/dcn60_mpc.h
@@ -469,19 +469,4 @@ void mpc60_program_rmcm_lut_read_write_control(struct mpc *mpc,
bool lut_bank_a,
bool enabled,
int mpcc_id);
-
-void mpc60_select_3dlut_ram(struct mpc *mpc,
- enum dc_lut_mode mode,
- bool is_color_channel_12bits,
- uint32_t mpcc_id);
-
-bool mpc60_program_3dlut(struct mpc *mpc,
- const struct tetrahedral_params *params,
- int mpcc_id);
-
-void mpc60_program_lut_read_write_control(struct mpc *mpc,
- const enum MCM_LUT_ID id,
- bool lut_bank_a,
- int mpcc_id);
-
#endif /* DCN60_MPC_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
index 6296330e2450..6370d3903eb5 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
@@ -704,6 +704,7 @@ static const struct resource_caps res_cap_dcn42 = {
.num_vmid = 16,
.num_mpc_3dlut = 2,
.num_dsc = 4,
+ .num_rmcm = 2,
};
static const struct dc_plane_cap plane_cap = {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
index b441d6d2d36b..4b7668abf4dc 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
@@ -584,6 +584,7 @@ static const struct resource_caps res_cap_dcn6_0 = {
.num_mpc_3dlut = 4,
.num_dsc = 4,
.num_aux = 4,
+ .num_rmcm = 2,
};
static const struct dc_plane_cap plane_cap = {
--
2.34.1
next prev parent reply other threads:[~2026-07-31 21:16 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 21:12 [PATCH 00/41] DC Patches July 31, 2026 Roman.Li
2026-07-31 21:12 ` [PATCH 03/41] drm/amd/display: Enable DCN6 init Roman.Li
2026-07-31 21:12 ` [PATCH 04/41] drm/amd/display: Dependent changes for DCN6 Roman.Li
2026-07-31 21:12 ` [PATCH 05/41] drm/amd/display: Enable DCN6 sources compilation Roman.Li
2026-07-31 21:12 ` [PATCH 06/41] drm/amd/display: Remove duplicate in tests/Makefile Roman.Li
2026-07-31 21:12 ` [PATCH 07/41] drm/amd/display: Resize MST HDCP per-connector arrays to 32 Roman.Li
2026-07-31 21:12 ` [PATCH 08/41] drm/amd/display: Bounds-check connector->index in dm_dp_mst_get_modes Roman.Li
2026-07-31 21:12 ` [PATCH 09/41] drm/amd/display: Ensure dtbclk is enabled Roman.Li
2026-07-31 21:12 ` [PATCH 10/41] drm/amd/display: Update VRR info packet to support 12-bit refresh rates Roman.Li
2026-07-31 21:12 ` [PATCH 11/41] drm/amd/display: Gate HDMI FRL status polling on active FRL link rate Roman.Li
2026-07-31 21:12 ` [PATCH 12/41] drm/amd/display: Fix wb_info leak and NULL deref in writeback Roman.Li
2026-07-31 21:12 ` [PATCH 13/41] drm/amd/display: Fix seamless mode switch not triggering for HDR to SDR transition Roman.Li
2026-07-31 21:12 ` [PATCH 14/41] drm/amd/display: Add KUnit tests for more crtc functions Roman.Li
2026-07-31 21:12 ` [PATCH 15/41] drm/amd/display: Add vblank handling tests for crtc Roman.Li
2026-07-31 21:12 ` [PATCH 16/41] drm/amd/display: Add idle worker " Roman.Li
2026-07-31 21:12 ` [PATCH 17/41] drm/amd/display: Add active plane count " Roman.Li
2026-07-31 21:12 ` [PATCH 18/41] drm/amd/display: Add KUnit test for crtc vblank event completion Roman.Li
2026-07-31 21:12 ` [PATCH 19/41] drm/amd/display: Add KUnit tests for crtc set_vupdate_irq Roman.Li
2026-07-31 21:12 ` [PATCH 20/41] drm/amd/display: Add KUnit tests for crtc set_static_screen_optimze Roman.Li
2026-07-31 21:12 ` [PATCH 21/41] drm/amd/display: Refactor stream validation Roman.Li
2026-07-31 21:12 ` [PATCH 22/41] drm/amd/display: Unify force_yuv debugfs into force_yuv_pixel_format Roman.Li
2026-07-31 21:12 ` [PATCH 23/41] drm/amd/display: Align connector KUnit tests with stream validation refactor Roman.Li
2026-07-31 21:12 ` [PATCH 24/41] drm/amd/display: Increase fclk change latency on dcn351 Roman.Li
2026-07-31 21:12 ` [PATCH 25/41] drm/amd/display: Add KUnit tests for crtc set_vblank Roman.Li
2026-07-31 21:12 ` [PATCH 26/41] drm/amd/display: Cover crtc set_vblank workqueue branch Roman.Li
2026-07-31 21:12 ` [PATCH 27/41] drm/amd/display: Cover crtc vblank IPS self-refresh restore Roman.Li
2026-07-31 21:12 ` [PATCH 28/41] drm/amd/display: Cover crtc vblank restore replay-supported path Roman.Li
2026-07-31 21:12 ` [PATCH 29/41] drm/amd/display: Cover crtc destroy_state stream release Roman.Li
2026-07-31 21:12 ` [PATCH 30/41] drm/amd/display: Fix ABM over VABC Roman.Li
2026-07-31 21:12 ` [PATCH 31/41] drm/amd/display: Add missing DCN42B register defines Roman.Li
2026-07-31 21:12 ` [PATCH 32/41] drm/amd/display: Add missing DMUB CACP and PR definitions Roman.Li
2026-07-31 21:12 ` [PATCH 33/41] drm/amd/display: Add missing OTG_CRC1_SELECT mask for DCN3.2 Roman.Li
2026-07-31 21:12 ` [PATCH 34/41] drm/amd/display: Fix CRC engine 1 enable/disable on DCN3.1.2+ Roman.Li
2026-07-31 21:12 ` [PATCH 35/41] drm/amd/display: Configure all CRC engines in pipe CRC source path Roman.Li
2026-07-31 21:12 ` [PATCH 36/41] drm/amd/display: Fix more KUnit connector use-after-free bugs Roman.Li
2026-07-31 21:12 ` [PATCH 37/41] drm/amd/display: Update BW bounding box unconditionally for DCN6 Roman.Li
2026-07-31 21:12 ` [PATCH 38/41] drm/amd/display: switch max FFE level cap based on FRL link rate Roman.Li
2026-07-31 21:13 ` [PATCH 39/41] drm/amd/display: Add FFE level defaults Roman.Li
2026-07-31 21:13 ` Roman.Li [this message]
2026-07-31 21:13 ` [PATCH 41/41] drm/amd/display: Promote DC to 3.2.392 Roman.Li
2026-08-04 13:24 ` [PATCH 00/41] DC Patches July 31, 2026 Wheeler, Daniel
2026-08-04 21:15 ` Timur Kristóf
2026-08-05 20:03 ` Wheeler, Daniel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731211302.3040343-41-Roman.Li@amd.com \
--to=roman.li@amd.com \
--cc=Chen-Yu.Chen@amd.com \
--cc=PingLei.Lin@amd.com \
--cc=Ray.Wu@amd.com \
--cc=alex.hung@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=aurabindo.pillai@amd.com \
--cc=chiahsuan.chung@amd.com \
--cc=daniel.wheeler@amd.com \
--cc=dillon.varone@amd.com \
--cc=harry.wentland@amd.com \
--cc=ivan.lipski@amd.com \
--cc=jerry.zuo@amd.com \
--cc=rafal.ostrowski@amd.com \
--cc=sunpeng.li@amd.com \
--cc=wayne.lin@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.