drm/amd/display: Fix Color Manager (3DLUT, Shaper, Blend)

[WHY & HOW]
The original refactor and fixes are causing regressions.
Revert them for now until they can be resolved

Fixes: e56e3cff2a ("drm/amd/display: Sync dcn42 with DC 3.2.373")
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Dillon Varone 2026-03-19 11:57:08 -04:00 committed by Alex Deucher
parent 6888eb3157
commit 12f58a6caa
19 changed files with 1473 additions and 715 deletions

View File

@ -2961,27 +2961,16 @@ static struct surface_update_descriptor det_surface_update(
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
if (u->blend_tf || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
update_flags->bits.gamma_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) {
if (u->lut3d_func || u->func_shaper) {
update_flags->bits.lut_3d = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable &&
u->cm->flags.bits.lut3d_enable && u->surface->cm.flags.bits.lut3d_enable) {
/* Toggling 3DLUT loading between DMA and Host is illegal */
BREAK_TO_DEBUGGER();
}
if (u->cm && u->cm->flags.bits.lut3d_enable && !u->cm->flags.bits.lut3d_dma_enable) {
/* Host loading 3DLUT requires full update but only stream lock */
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_STREAM);
}
if (u->hdr_mult.value)
if (u->hdr_mult.value != u->surface->hdr_mult.value) {
// TODO: Should be fast?
@ -3000,6 +2989,20 @@ static struct surface_update_descriptor det_surface_update(
update_flags->bits.cm_hist_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->cm2_params) {
if (u->cm2_params->component_settings.shaper_3dlut_setting != u->surface->mcm_shaper_3dlut_setting
|| u->cm2_params->component_settings.lut1d_enable != u->surface->mcm_lut1d_enable
|| u->cm2_params->cm2_luts.lut3d_data.lut3d_src != u->surface->mcm_luts.lut3d_data.lut3d_src) {
update_flags->bits.mcm_transfer_function_enable_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
}
if (update_flags->bits.lut_3d &&
u->surface->mcm_luts.lut3d_data.lut3d_src != DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
if (check_config->enable_legacy_fast_update &&
(update_flags->bits.gamma_change ||
update_flags->bits.gamut_remap_change ||
@ -3311,12 +3314,24 @@ static void copy_surface_update_to_plane(
sizeof(struct dc_transfer_func_distributed_points));
}
/* Shaper, 3DLUT, 1DLUT */
if (srf_update->cm) {
memcpy(&surface->cm, srf_update->cm,
sizeof(surface->cm));
if (srf_update->cm2_params) {
surface->mcm_shaper_3dlut_setting = srf_update->cm2_params->component_settings.shaper_3dlut_setting;
surface->mcm_lut1d_enable = srf_update->cm2_params->component_settings.lut1d_enable;
surface->mcm_luts = srf_update->cm2_params->cm2_luts;
}
if (srf_update->func_shaper) {
memcpy(&surface->in_shaper_func, srf_update->func_shaper,
sizeof(surface->in_shaper_func));
if (surface->mcm_shaper_3dlut_setting >= DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER)
surface->mcm_luts.shaper = &surface->in_shaper_func;
}
if (srf_update->lut3d_func)
memcpy(&surface->lut3d_func, srf_update->lut3d_func,
sizeof(surface->lut3d_func));
if (srf_update->hdr_mult.value)
surface->hdr_mult =
srf_update->hdr_mult;
@ -3325,6 +3340,17 @@ static void copy_surface_update_to_plane(
surface->sdr_white_level_nits =
srf_update->sdr_white_level_nits;
if (srf_update->blend_tf) {
memcpy(&surface->blend_tf, srf_update->blend_tf,
sizeof(surface->blend_tf));
if (surface->mcm_lut1d_enable)
surface->mcm_luts.lut1d_func = &surface->blend_tf;
}
if (srf_update->cm2_params || srf_update->blend_tf)
surface->lut_bank_a = !surface->lut_bank_a;
if (srf_update->input_csc_color_matrix)
surface->input_csc_color_matrix =
*srf_update->input_csc_color_matrix;
@ -4618,9 +4644,11 @@ static void commit_planes_for_stream(struct dc *dc,
if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
continue;
if (srf_updates[i].cm &&
srf_updates[i].cm->flags.bits.lut3d_enable &&
srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
if (srf_updates[i].cm2_params &&
srf_updates[i].cm2_params->cm2_luts.lut3d_data.lut3d_src ==
DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM &&
srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting ==
DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT &&
dc->hwss.trigger_3dlut_dma_load)
dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx);
@ -6864,7 +6892,7 @@ bool dc_capture_register_software_state(struct dc *dc, struct dc_register_softwa
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
/* MPCC blending tree and mode control - capture actual blend configuration */
state->mpc.mpcc_mode[i] = (plane_state->cm.blend_func.type != TF_TYPE_BYPASS) ? 1 : 0;
state->mpc.mpcc_mode[i] = (plane_state->blend_tf.type != TF_TYPE_BYPASS) ? 1 : 0;
state->mpc.mpcc_alpha_blend_mode[i] = plane_state->per_pixel_alpha ? 1 : 0;
state->mpc.mpcc_alpha_multiplied_mode[i] = plane_state->pre_multiplied_alpha ? 1 : 0;
state->mpc.mpcc_blnd_active_overlap_only[i] = 0; /* Default - no overlap restriction */

View File

@ -39,7 +39,6 @@
#include "abm.h"
#include "dcn10/dcn10_hubbub.h"
#include "dce/dmub_hw_lock_mgr.h"
#include "custom_float.h"
#include "link_service.h"
#define MAX_NUM_MCACHE 8

View File

@ -1002,6 +1002,7 @@ void dc_stream_release_3dlut_for_stream(
if (rmcm_3dlut) {
rmcm_3dlut->isInUse = false;
rmcm_3dlut->stream = NULL;
rmcm_3dlut->protection_bits = 0;
}
}
@ -1013,6 +1014,7 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
for (int i = 0; i < num_rmcm; i++) {
dc->res_pool->rmcm_3dlut[i].isInUse = false;
dc->res_pool->rmcm_3dlut[i].stream = NULL;
dc->res_pool->rmcm_3dlut[i].protection_bits = 0;
}
}

View File

@ -1407,50 +1407,15 @@ struct lut_mem_mapping {
struct dc_rmcm_3dlut {
bool isInUse;
const struct dc_stream_state *stream;
uint8_t protection_bits;
};
struct dc_3dlut {
struct kref refcount;
struct tetrahedral_params lut_3d;
struct fixed31_32 hdr_multiplier;
union dc_3dlut_state state;
};
/* 3DLUT DMA (Fast Load) params */
struct dc_3dlut_dma {
struct dc_plane_address addr;
enum dc_cm_lut_swizzle swizzle;
enum dc_cm_lut_pixel_format format;
uint16_t bias; /* FP1.5.10 */
uint16_t scale; /* FP1.5.10 */
enum dc_cm_lut_size size;
};
/* color manager */
union dc_plane_cm_flags {
unsigned int all;
struct {
unsigned int shaper_enable : 1;
unsigned int lut3d_enable : 1;
unsigned int blend_enable : 1;
/* whether legacy (lut3d_func) or DMA is valid */
unsigned int lut3d_dma_enable : 1;
/* RMCM lut to be used instead of MCM */
unsigned int rmcm_enable : 1;
unsigned int reserved: 27;
} bits;
};
struct dc_plane_cm {
struct kref refcount;
struct dc_transfer_func shaper_func;
union {
struct dc_3dlut lut3d_func;
struct dc_3dlut_dma lut3d_dma;
};
struct dc_transfer_func blend_func;
union dc_plane_cm_flags flags;
};
/*
* This structure is filled in by dc_surface_get_status and contains
* the last requested address and the currently active address so the called
@ -1532,18 +1497,14 @@ struct dc_plane_state {
struct fixed31_32 hdr_mult;
struct colorspace_transform gamut_remap_matrix;
// TODO: No longer used, remove
struct dc_hdr_static_metadata hdr_static_ctx;
enum dc_color_space color_space;
bool lut_bank_a;
struct dc_hdr_static_metadata hdr_static_ctx;
struct dc_3dlut lut3d_func;
struct dc_transfer_func in_shaper_func;
struct dc_transfer_func blend_tf;
enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
bool mcm_lut1d_enable;
struct dc_cm2_func_luts mcm_luts;
enum mpcc_movable_cm_location mcm_location;
struct dc_plane_cm cm;
struct dc_transfer_func *gamcor_tf;
enum surface_pixel_format format;
@ -1580,6 +1541,11 @@ struct dc_plane_state {
bool is_statically_allocated;
enum chroma_cositing cositing;
enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
bool mcm_lut1d_enable;
struct dc_cm2_func_luts mcm_luts;
bool lut_bank_a;
enum mpcc_movable_cm_location mcm_location;
struct dc_csc_transform cursor_csc_color_matrix;
bool adaptive_sharpness_en;
int adaptive_sharpness_policy;
@ -1958,10 +1924,6 @@ struct dc_3dlut *dc_create_3dlut_func(void);
void dc_3dlut_func_release(struct dc_3dlut *lut);
void dc_3dlut_func_retain(struct dc_3dlut *lut);
struct dc_plane_cm *dc_plane_cm_create(void);
void dc_plane_cm_release(struct dc_plane_cm *cm);
void dc_plane_cm_retain(struct dc_plane_cm *cm);
void dc_post_update_surfaces_to_stream(
struct dc *dc);

View File

@ -1523,28 +1523,4 @@ struct dc_validation_dpia_set {
uint32_t required_bw;
};
enum dc_cm_lut_swizzle {
CM_LUT_3D_SWIZZLE_LINEAR_RGB,
CM_LUT_3D_SWIZZLE_LINEAR_BGR,
CM_LUT_1D_PACKED_LINEAR
};
enum dc_cm_lut_pixel_format {
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB,
CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB,
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB,
CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB,
CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10,
CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10
};
enum dc_cm_lut_size {
CM_LUT_SIZE_NONE,
CM_LUT_SIZE_999,
CM_LUT_SIZE_171717,
CM_LUT_SIZE_333333,
CM_LUT_SIZE_454545,
CM_LUT_SIZE_656565,
};
#endif /* DC_TYPES_H_ */

View File

@ -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,46 +72,33 @@ int hubp401_get_3dlut_fl_done(struct hubp *hubp)
return ret;
}
static void hubp401_get_3dlut_fl_xbar_map(
const enum dc_cm_lut_pixel_format format,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
{
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_crossbar(struct hubp *hubp,
const enum dc_cm_lut_pixel_format format)
void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g = 0;
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b = 0;
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r = 0;
REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
}
hubp401_get_3dlut_fl_xbar_map(format,
&bit_slice_y_g,
&bit_slice_cb_b,
&bit_slice_cr_r);
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);
}
void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
}
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);
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
@ -119,122 +106,62 @@ void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
}
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)
{
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;
}
return width;
}
static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format(
const enum dc_cm_lut_pixel_format dc_format)
{
enum hubp_3dlut_fl_format hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
switch (dc_format) {
case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
break;
case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
hubp_format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
break;
case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
hubp_format = hubp_3dlut_fl_format_float_fp1_5_10;
break;
default:
BREAK_TO_DEBUGGER();
break;
}
return hubp_format;
}
static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode(
const enum dc_cm_lut_swizzle swizzle)
{
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;
}
return addr_mode;
}
static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode(
const enum dc_cm_lut_swizzle swizzle)
{
enum hubp_3dlut_fl_mode mode;
switch (swizzle) {
case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
mode = hubp_3dlut_fl_mode_native_1;
break;
case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
mode = hubp_3dlut_fl_mode_native_2;
break;
case CM_LUT_1D_PACKED_LINEAR:
mode = hubp_3dlut_fl_mode_transform;
break;
default:
mode = hubp_3dlut_fl_mode_disable;
break;
}
return mode;
}
void hubp401_program_3dlut_fl_config(struct hubp *hubp,
const struct dc_3dlut_dma *config)
void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale)
{
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_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale);
}
void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
}
void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
}
void hubp401_program_3dlut_fl_config(
struct hubp *hubp,
struct hubp_fl_3dlut_config *cfg)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
uint32_t width = {cfg->width};
if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR)
width = (cfg->width == 17) ? 4916 : 35940;
REG_UPDATE_2(_3DLUT_FL_CONFIG,
HUBP0_3DLUT_FL_MODE, mode,
HUBP0_3DLUT_FL_FORMAT, format);
HUBP0_3DLUT_FL_MODE, cfg->mode,
HUBP0_3DLUT_FL_FORMAT, cfg->format);
REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
HUBP0_3DLUT_FL_BIAS, config->bias,
HUBP0_3DLUT_FL_SCALE, config->scale);
HUBP0_3DLUT_FL_BIAS, cfg->bias,
HUBP0_3DLUT_FL_SCALE, cfg->scale);
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_WIDTH, width,
HUBP_3DLUT_ADDRESSING_MODE, addr_mode,
HUBP_3DLUT_TMZ, config->addr.tmz_surface);
REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
//cross bar
REG_UPDATE_8(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_MPC_WIDTH, mpc_width,
HUBP_3DLUT_WIDTH, width,
HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
HUBP_3DLUT_TMZ, cfg->protection_bits,
HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
}
void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
@ -1135,13 +1062,19 @@ static struct hubp_funcs dcn401_hubp_funcs = {
.hubp_update_mall_sel = hubp401_update_mall_sel,
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
.hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
.hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
.hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
.hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
.hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
.hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
.hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
.hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
.hubp_read_reg_state = hubp3_read_reg_state
};

View File

@ -328,17 +328,32 @@ int hubp401_get_3dlut_fl_done(struct hubp *hubp);
void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable);
void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale);
void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
const enum dc_cm_lut_pixel_format format);
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits);
void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width);
void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable);
void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group);
void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address *address);
void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address address);
void hubp401_program_3dlut_fl_config(struct hubp *hubp,
const struct dc_3dlut_dma *config);
void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format);
void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode);
void hubp401_program_3dlut_fl_config(
struct hubp *hubp,
struct hubp_fl_3dlut_config *cfg);
void hubp401_clear_tiling(struct hubp *hubp);

View File

@ -311,84 +311,19 @@ static void hubp42_program_surface_config(
hubp42_program_pixel_format(hubp, format);
}
static void hubp42_get_3dlut_fl_xbar_map(
const enum dc_cm_lut_pixel_format format,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b,
enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r)
{
switch (format) {
case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB:
case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB:
case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10:
/* BGRA */
*bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
*bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
*bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
break;
case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB:
case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB:
case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10:
default:
/* RGBA */
*bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
*bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
*bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
break;
}
}
void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
const enum dc_cm_lut_pixel_format format)
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0;
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0;
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0;
hubp42_get_3dlut_fl_xbar_map(format,
&bit_slice_g,
&bit_slice_b,
&bit_slice_r);
REG_UPDATE_3(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r,
HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g,
HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b);
}
static uint32_t hubp42_get_3dlut_fl_mpc_width(
const enum dc_cm_lut_size size)
{
uint32_t width = 0;
switch (size) {
case CM_LUT_SIZE_333333:
width = 1;
break;
case CM_LUT_SIZE_171717:
default:
width = 0;
break;
}
return width;
}
void hubp42_program_3dlut_fl_config(struct hubp *hubp,
const struct dc_3dlut_dma *config)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size);
REG_UPDATE(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_MPC_WIDTH, mpc_width);
hubp401_program_3dlut_fl_config(hubp, config);
}
static bool hubp42_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
@ -670,10 +605,15 @@ struct hubp_funcs dcn42_hubp_funcs = {
.hubp_set_flip_int = hubp1_set_flip_int,
.hubp_in_blank = hubp1_in_blank,
.program_extended_blank = hubp31_program_extended_blank_value,
.hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
.hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
.hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
.hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config,
.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
.hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
.hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
.hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
.hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp3_clear_tiling,

View File

@ -58,11 +58,11 @@ bool hubp42_construct(
const struct dcn_hubp2_shift *hubp_shift,
const struct dcn_hubp2_mask *hubp_mask);
void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp,
const enum dc_cm_lut_pixel_format format);
void hubp42_program_3dlut_fl_config(struct hubp *hubp,
const struct dc_3dlut_dma *config);
void hubp42_program_3dlut_fl_crossbar(
struct hubp *hubp,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b);
void hubp42_read_state(struct hubp *hubp);

View File

@ -95,6 +95,10 @@ void dcn401_program_gamut_remap(struct pipe_ctx *pipe_ctx)
unsigned int mpcc_id = pipe_ctx->plane_res.mpcc_inst;
struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
//For now assert if location is not pre-blend
if (pipe_ctx->plane_state)
ASSERT(pipe_ctx->plane_state->mcm_location == MPCC_MOVABLE_CM_LOCATION_BEFORE);
// program MPCC_MCM_FIRST_GAMUT_REMAP
memset(&mpc_adjust, 0, sizeof(mpc_adjust));
mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@ -374,6 +378,242 @@ 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)
{
enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
bool lut1d_enable = false;
struct mpc *mpc = dc->res_pool->mpc;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
if (!pipe_ctx->plane_state)
return;
shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
*lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
switch (shaper_3dlut_setting) {
case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
*lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
break;
case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
*lut3d_xable = MCM_LUT_DISABLE;
*shaper_xable = MCM_LUT_ENABLE;
break;
case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
*lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
break;
}
}
void dcn401_populate_mcm_luts(struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_cm2_func_luts mcm_luts,
bool lut_bank_a)
{
struct 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;
enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
enum hubp_3dlut_fl_format format = 0;
enum hubp_3dlut_fl_mode mode;
enum hubp_3dlut_fl_width width = 0;
enum hubp_3dlut_fl_addressing_mode addr_mode;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
bool rval;
dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
/* 1D LUT */
if (mcm_luts.lut1d_func) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
mcm_luts.lut1d_func,
&dpp_base->regamma_params, false);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
}
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
}
/* Shaper */
if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.shaper->pwl;
else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
mcm_luts.shaper,
&dpp_base->regamma_params, true);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->mcm.populate_lut)
mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
}
}
/* 3DLUT */
switch (lut3d_src) {
case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (hubp->funcs->hubp_enable_3dlut_fl)
hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d;
if (mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
mpcc_id);
}
break;
case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
#if defined(CONFIG_DRM_AMD_DC_DCN4_2)
case DC_CM2_GPU_MEM_SIZE_333333:
if (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33)
width = hubp_3dlut_fl_width_33;
break;
#endif
case DC_CM2_GPU_MEM_SIZE_171717:
width = hubp_3dlut_fl_width_17;
break;
case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
width = hubp_3dlut_fl_width_transformed;
break;
default:
//TODO: handle default case
break;
}
//check for support
if (mpc->funcs->mcm.is_config_supported &&
!mpc->funcs->mcm.is_config_supported(width))
break;
if (mpc->funcs->program_lut_read_write_control)
mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
if (hubp->funcs->hubp_program_3dlut_fl_addr)
hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr);
if (mpc->funcs->mcm.program_bit_depth)
mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
switch (mcm_luts.lut3d_data.gpu_mem_params.layout) {
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
mode = hubp_3dlut_fl_mode_native_1;
addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
mode = hubp_3dlut_fl_mode_native_2;
addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
mode = hubp_3dlut_fl_mode_transform;
addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
break;
default:
mode = hubp_3dlut_fl_mode_disable;
addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
}
if (hubp->funcs->hubp_program_3dlut_fl_mode)
hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
format = hubp_3dlut_fl_format_float_fp1_5_10;
break;
}
if (hubp->funcs->hubp_program_3dlut_fl_format)
hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
mpc->funcs->mcm.program_bias_scale) {
mpc->funcs->mcm.program_bias_scale(mpc,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
mpcc_id);
hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
}
//navi 4x has a bug and r and blue are swapped and need to be worked around here in
//TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
switch (mcm_luts.lut3d_data.gpu_mem_params.component_order) {
case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
default:
crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
break;
}
if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
crossbar_bit_slice_cr_r,
crossbar_bit_slice_y_g,
crossbar_bit_slice_cb_b);
if (mpc->funcs->mcm.program_lut_read_write_control)
mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
if (mpc->funcs->mcm.program_3dlut_size)
mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
if (mpc->funcs->update_3dlut_fast_load_select)
mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
if (hubp->funcs->hubp_enable_3dlut_fl)
hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
else {
if (mpc->funcs->program_lut_mode) {
mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
}
}
break;
}
}
void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
(void)dc;
@ -387,167 +627,51 @@ void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx)
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;
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
const struct dc_plane_cm *cm = &plane_state->cm;
int mpcc_id = hubp->inst;
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;
union mcm_lut_params m_lut_params;
struct dc_3dlut_dma lut3d_dma;
bool lut_enable;
bool lut_bank_a;
bool result;
const struct pwl_params *lut_params = NULL;
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);
if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
dcn401_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a);
return true;
}
/* 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 */
lut_enable = cm->flags.bits.blend_enable;
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (lut_enable) {
if (cm->blend_func.type == TF_TYPE_HWPWL)
m_lut_params.pwl = &cm->blend_func.pwl;
else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&cm->blend_func,
&dpp_base->regamma_params,
false);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (!m_lut_params.pwl) {
lut_enable = false;
}
} else {
lut_enable = false;
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
// 1D LUT
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
lut_params = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&plane_state->blend_tf,
&dpp_base->regamma_params, false);
lut_params = rval ? &dpp_base->regamma_params : NULL;
}
result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
lut_params = NULL;
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id);
if (lut_enable && mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, &m_lut_params, lut_bank_a, mpcc_id);
/* Shaper */
lut_enable = cm->flags.bits.shaper_enable;
if (lut_enable) {
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(plane_state->ctx,
&cm->shaper_func,
&dpp_base->shaper_params,
true);
m_lut_params.pwl = rval ? &dpp_base->shaper_params : NULL;
}
if (!m_lut_params.pwl) {
lut_enable = false;
}
} else {
lut_enable = false;
// Shaper
if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
lut_params = &plane_state->in_shaper_func.pwl;
else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
// TODO: dpp_base replace
rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&plane_state->in_shaper_func,
&dpp_base->shaper_params, true);
lut_params = rval ? &dpp_base->shaper_params : NULL;
}
result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
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);
/* 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.
*/
/* 3DLUT */
lut_enable = cm->flags.bits.lut3d_enable;
if (lut_enable && cm->flags.bits.lut3d_dma_enable) {
/* Fast (DMA) Load Mode */
/* MPC */
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id);
/* 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 (mpc->funcs->update_3dlut_fast_load_select)
mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
/* 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_crossbar)
hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format);
if (hubp->funcs->hubp_program_3dlut_fl_addr)
hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
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 {
/* Legacy (Host) Load Mode */
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (cm->flags.bits.lut3d_enable && cm->lut3d_func.state.bits.initialized) {
m_lut_params.lut3d = &cm->lut3d_func.lut_3d;
} else {
lut_enable = false;
}
/* 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 (mpc->funcs->update_3dlut_fast_load_select)
mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 0xf);
if (mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, &m_lut_params, lut_bank_a, mpcc_id);
}
/* HUBP */
memset(&lut3d_dma, 0, sizeof(lut3d_dma));
if (hubp->funcs->hubp_program_3dlut_fl_config)
hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma);
if (hubp->funcs->hubp_enable_3dlut_fl)
hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
// 3D
if (mpc->funcs->program_3dlut) {
if (plane_state->lut3d_func.state.bits.initialized == 1)
result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
else
result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
}
return result;
@ -1828,9 +1952,10 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) {
for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) {
if (mpc_pipe->plane_state &&
mpc_pipe->plane_state->cm.flags.bits.lut3d_enable &&
mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) {
if (mpc_pipe->plane_state && mpc_pipe->plane_state->mcm_luts.lut3d_data.lut3d_src
== DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM
&& mpc_pipe->plane_state->mcm_shaper_3dlut_setting
== DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT) {
wa_pipes[wa_pipe_ct++] = mpc_pipe;
}
}

View File

@ -393,6 +393,68 @@ void dcn42_program_cm_hist(
plane_state->cm_hist_control, plane_state->color_space);
}
static void dc_get_lut_xbar(
enum dc_cm2_gpu_mem_pixel_component_order order,
enum hubp_3dlut_fl_crossbar_bit_slice *cr_r,
enum hubp_3dlut_fl_crossbar_bit_slice *y_g,
enum hubp_3dlut_fl_crossbar_bit_slice *cb_b)
{
switch (order) {
case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA:
*cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
*y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
*cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
break;
case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA:
*cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15;
*y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
*cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47;
break;
}
}
static void dc_get_lut_mode(
enum dc_cm2_gpu_mem_layout layout,
enum hubp_3dlut_fl_mode *mode,
enum hubp_3dlut_fl_addressing_mode *addr_mode)
{
switch (layout) {
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
*mode = hubp_3dlut_fl_mode_native_1;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
*mode = hubp_3dlut_fl_mode_native_2;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
*mode = hubp_3dlut_fl_mode_transform;
*addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
break;
default:
*mode = hubp_3dlut_fl_mode_disable;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
}
}
static void dc_get_lut_format(
enum dc_cm2_gpu_mem_format dc_format,
enum hubp_3dlut_fl_format *format)
{
switch (dc_format) {
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
*format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
*format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
*format = hubp_3dlut_fl_format_float_fp1_5_10;
break;
}
}
static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
{
if (mpc->funcs->rmcm.power_on_shaper_3dlut &&
@ -403,17 +465,119 @@ static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc)
return false;
}
static bool is_rmcm_3dlut_fl_supported(struct dc *dc, enum dc_cm2_gpu_mem_size size)
{
if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut)
return false;
if (size == DC_CM2_GPU_MEM_SIZE_171717)
return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17);
else if (size == DC_CM2_GPU_MEM_SIZE_333333)
return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33);
return false;
}
static void dcn42_set_mcm_location_post_blend(struct dc *dc, struct pipe_ctx *pipe_ctx, bool bPostBlend)
{
struct mpc *mpc = dc->res_pool->mpc;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
if (!pipe_ctx->plane_state)
return;
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = (bPostBlend) ?
MPCC_MOVABLE_CM_LOCATION_AFTER :
MPCC_MOVABLE_CM_LOCATION_BEFORE;
}
static void dcn42_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx,
enum MCM_LUT_XABLE *shaper_xable,
enum MCM_LUT_XABLE *lut3d_xable,
enum MCM_LUT_XABLE *lut1d_xable)
{
enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL;
bool lut1d_enable = false;
struct mpc *mpc = dc->res_pool->mpc;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
if (!pipe_ctx->plane_state)
return;
shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting;
lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable;
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
*lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE;
switch (shaper_3dlut_setting) {
case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL:
*lut3d_xable = *shaper_xable = MCM_LUT_DISABLE;
break;
case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER:
*lut3d_xable = MCM_LUT_DISABLE;
*shaper_xable = MCM_LUT_ENABLE;
break;
case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT:
*lut3d_xable = *shaper_xable = MCM_LUT_ENABLE;
break;
}
}
static void fl_get_lut_mode(
enum dc_cm2_gpu_mem_layout layout,
enum dc_cm2_gpu_mem_size size,
enum hubp_3dlut_fl_mode *mode,
enum hubp_3dlut_fl_addressing_mode *addr_mode,
enum hubp_3dlut_fl_width *width)
{
*width = hubp_3dlut_fl_width_17;
if (size == DC_CM2_GPU_MEM_SIZE_333333)
*width = hubp_3dlut_fl_width_33;
switch (layout) {
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
*mode = hubp_3dlut_fl_mode_native_1;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
*mode = hubp_3dlut_fl_mode_native_2;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
*mode = hubp_3dlut_fl_mode_transform;
*addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear;
break;
default:
*mode = hubp_3dlut_fl_mode_disable;
*addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear;
break;
}
}
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
const struct dc_plane_cm *cm,
enum dc_cm2_transfer_func_source lut3d_src,
struct dc_cm2_func_luts *mcm_luts,
struct mpc *mpc,
bool lut_bank_a,
int mpcc_id)
{
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
union mcm_lut_params m_lut_params = {0};
enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, lut1d_xable;
enum hubp_3dlut_fl_mode mode;
enum hubp_3dlut_fl_addressing_mode addr_mode;
enum hubp_3dlut_fl_format format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47;
enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_17;
struct dc *dc = hubp->ctx->dc;
struct hubp_fl_3dlut_config fl_config;
struct mpc_fl_3dlut_config mpc_fl_config;
struct dc_stream_state *stream = pipe_ctx->stream;
@ -421,23 +585,25 @@ bool dcn42_program_rmcm_luts(
// true->false when it can be allocated at DI time
struct dc_rmcm_3dlut *rmcm_3dlut = dc_stream_get_3dlut_for_stream(dc, stream, false);
bool lut_bank_a = true; // TODO get from HW
//check to see current pipe is part of a stream with allocated rmcm 3dlut
if (!rmcm_3dlut)
return false;
rmcm_3dlut->protection_bits = mcm_luts->lut3d_data.rmcm_tmz;
dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
/* Shaper */
if (cm->flags.bits.shaper_enable) {
if (mcm_luts->shaper) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (cm->shaper_func.type == TF_TYPE_HWPWL) {
m_lut_params.pwl = &cm->shaper_func.pwl;
} else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
if (mcm_luts->shaper->type == TF_TYPE_HWPWL) {
m_lut_params.pwl = &mcm_luts->shaper->pwl;
} else if (mcm_luts->shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
cm_helper_translate_curve_to_hw_format(
dc->ctx,
&cm->shaper_func,
mcm_luts->shaper,
&dpp_base->shaper_params, true);
m_lut_params.pwl = &dpp_base->shaper_params;
}
@ -453,21 +619,58 @@ bool dcn42_program_rmcm_luts(
}
/* 3DLUT */
if (!cm->flags.bits.lut3d_dma_enable) {
switch (lut3d_src) {
case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
memset(&m_lut_params, 0, sizeof(m_lut_params));
// Don't know what to do in this case.
} else {
if (!dc_is_rmcm_3dlut_supported(hubp, mpc))
//case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
break;
case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
fl_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout,
mcm_luts->lut3d_data.gpu_mem_params.size,
&mode,
&addr_mode,
&width);
if (!dc_is_rmcm_3dlut_supported(hubp, mpc) ||
!mpc->funcs->rmcm.is_config_supported(
(width == hubp_3dlut_fl_width_17 ||
width == hubp_3dlut_fl_width_transformed) ? 17 : 33))
return false;
// setting native or transformed mode,
dc_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
//seems to be only for the MCM
mpc_fl_config.enabled = cm->flags.bits.lut3d_enable;
mpc_fl_config.size = cm->lut3d_dma.size;
dc_get_lut_format(mcm_luts->lut3d_data.gpu_mem_params.format_params.format, &format);
dc_get_lut_xbar(
mcm_luts->lut3d_data.gpu_mem_params.component_order,
&crossbar_bit_slice_cr_r,
&crossbar_bit_slice_y_g,
&crossbar_bit_slice_cb_b);
fl_config.mode = mode;
fl_config.enabled = lut3d_xable != MCM_LUT_DISABLE;
fl_config.address = mcm_luts->lut3d_data.gpu_mem_params.addr;
fl_config.format = format;
fl_config.crossbar_bit_slice_y_g = crossbar_bit_slice_y_g;
fl_config.crossbar_bit_slice_cb_b = crossbar_bit_slice_cb_b;
fl_config.crossbar_bit_slice_cr_r = crossbar_bit_slice_cr_r;
fl_config.width = width;
fl_config.protection_bits = rmcm_3dlut->protection_bits;
fl_config.addr_mode = addr_mode;
fl_config.layout = mcm_luts->lut3d_data.gpu_mem_params.layout;
fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
mpc_fl_config.enabled = fl_config.enabled;
mpc_fl_config.width = width;
mpc_fl_config.select_lut_bank_a = lut_bank_a;
mpc_fl_config.bit_depth = 0;
mpc_fl_config.bit_depth = mcm_luts->lut3d_data.gpu_mem_params.bit_depth;
mpc_fl_config.hubp_index = hubp->inst;
mpc_fl_config.bias = cm->lut3d_dma.bias;
mpc_fl_config.scale = cm->lut3d_dma.scale;
mpc_fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias;
mpc_fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale;
//1. power down the block
mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, false);
@ -475,44 +678,268 @@ bool dcn42_program_rmcm_luts(
//2. program RMCM - 3dlut reg programming
mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, mpcc_id);
/* HUBP */
if (hubp->funcs->hubp_program_3dlut_fl_config)
hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma);
if (hubp->funcs->hubp_program_3dlut_fl_addr)
hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr);
hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config);
//3. power on the block
mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true);
break;
default:
return false;
}
return true;
}
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state)
void dcn42_populate_mcm_luts(struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_cm2_func_luts mcm_luts,
bool lut_bank_a)
{
struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc;
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
const struct dc_plane_cm *cm = &plane_state->cm;
struct mpc *mpc = dc->res_pool->mpc;
int mpcc_id = hubp->inst;
bool result;
struct mpc *mpc = dc->res_pool->mpc;
union mcm_lut_params m_lut_params;
enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src;
enum hubp_3dlut_fl_format format = 0;
enum hubp_3dlut_fl_mode mode;
enum hubp_3dlut_fl_width width = 0;
enum hubp_3dlut_fl_addressing_mode addr_mode;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0;
enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
bool rval;
/* MCM */
result = dcn401_set_mcm_luts(pipe_ctx, plane_state);
dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable);
/* RMCM */
if (cm->flags.bits.rmcm_enable && cm->flags.bits.lut3d_dma_enable) {
/* TODO - move RMCM to its own block */
//MCM - setting its location (Before/After) blender
//set to post blend (true)
dcn42_set_mcm_location_post_blend(
dc,
pipe_ctx,
mcm_luts.lut3d_data.mpc_mcm_post_blend);
//RMCM - 3dLUT+Shaper
if (mcm_luts.lut3d_data.rmcm_3dlut_enable &&
is_rmcm_3dlut_fl_supported(dc, mcm_luts.lut3d_data.gpu_mem_params.size)) {
dcn42_program_rmcm_luts(
hubp,
pipe_ctx,
cm,
lut3d_src,
&mcm_luts,
mpc,
lut_bank_a,
mpcc_id);
}
/* 1D LUT */
if (mcm_luts.lut1d_func) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
mcm_luts.lut1d_func,
&dpp_base->regamma_params, false);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id);
}
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id);
}
/* Shaper */
if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.shaper->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.shaper->pwl;
else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
ASSERT(false);
rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
mcm_luts.shaper,
&dpp_base->regamma_params, true);
m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
}
if (m_lut_params.pwl) {
if (mpc->funcs->mcm.populate_lut)
mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id);
}
}
/* 3DLUT */
switch (lut3d_src) {
case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM:
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (hubp->funcs->hubp_enable_3dlut_fl)
hubp->funcs->hubp_enable_3dlut_fl(hubp, false);
if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) {
m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d;
if (mpc->funcs->populate_lut)
mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a,
mpcc_id);
}
break;
case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM:
switch (mcm_luts.lut3d_data.gpu_mem_params.size) {
case DC_CM2_GPU_MEM_SIZE_333333:
width = hubp_3dlut_fl_width_33;
break;
case DC_CM2_GPU_MEM_SIZE_171717:
width = hubp_3dlut_fl_width_17;
break;
case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
width = hubp_3dlut_fl_width_transformed;
break;
default:
//TODO: Handle default case
break;
}
//check for support
if (mpc->funcs->mcm.is_config_supported &&
!mpc->funcs->mcm.is_config_supported(width))
break;
if (mpc->funcs->program_lut_read_write_control)
mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id);
if (hubp->funcs->hubp_program_3dlut_fl_addr)
hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr);
if (mpc->funcs->mcm.program_bit_depth)
mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id);
dc_get_lut_mode(mcm_luts.lut3d_data.gpu_mem_params.layout, &mode, &addr_mode);
if (hubp->funcs->hubp_program_3dlut_fl_mode)
hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode);
if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode)
hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode);
switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) {
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB:
format = hubp_3dlut_fl_format_unorm_12msb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB:
format = hubp_3dlut_fl_format_unorm_12lsb_bitslice;
break;
case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10:
format = hubp_3dlut_fl_format_float_fp1_5_10;
break;
}
if (hubp->funcs->hubp_program_3dlut_fl_format)
hubp->funcs->hubp_program_3dlut_fl_format(hubp, format);
if (hubp->funcs->hubp_update_3dlut_fl_bias_scale &&
mpc->funcs->mcm.program_bias_scale) {
mpc->funcs->mcm.program_bias_scale(mpc,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale,
mpcc_id);
hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias,
mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale);
}
//navi 4x has a bug and r and blue are swapped and need to be worked around here in
//TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x
dc_get_lut_xbar(
mcm_luts.lut3d_data.gpu_mem_params.component_order,
&crossbar_bit_slice_cr_r,
&crossbar_bit_slice_y_g,
&crossbar_bit_slice_cb_b);
if (hubp->funcs->hubp_program_3dlut_fl_crossbar)
hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp,
crossbar_bit_slice_cr_r,
crossbar_bit_slice_y_g,
crossbar_bit_slice_cb_b);
if (mpc->funcs->mcm.program_lut_read_write_control)
mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id);
if (mpc->funcs->mcm.program_3dlut_size)
mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id);
if (mpc->funcs->update_3dlut_fast_load_select)
mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst);
if (hubp->funcs->hubp_enable_3dlut_fl)
hubp->funcs->hubp_enable_3dlut_fl(hubp, true);
else {
if (mpc->funcs->program_lut_mode) {
mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id);
}
}
break;
}
}
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state)
{
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc;
struct mpc *mpc = dc->res_pool->mpc;
bool result;
const struct pwl_params *lut_params = NULL;
bool rval;
if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
dcn42_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a);
return true;
}
mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
// 1D LUT
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
lut_params = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&plane_state->blend_tf,
&dpp_base->regamma_params, false);
lut_params = rval ? &dpp_base->regamma_params : NULL;
}
result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
lut_params = NULL;
// Shaper
if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL)
lut_params = &plane_state->in_shaper_func.pwl;
else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
// TODO: dpp_base replace
rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
&plane_state->in_shaper_func,
&dpp_base->shaper_params, true);
lut_params = rval ? &dpp_base->shaper_params : NULL;
}
result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
// 3D
if (mpc->funcs->program_3dlut) {
if (plane_state->lut3d_func.state.bits.initialized == 1)
result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id);
else
result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id);
}
return result;
}
void dcn42_hardware_release(struct dc *dc)

View File

@ -18,11 +18,18 @@ void dcn42_program_cm_hist(
bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
void dcn42_populate_mcm_luts(struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_cm2_func_luts mcm_luts,
bool lut_bank_a);
bool dcn42_program_rmcm_luts(
struct hubp *hubp,
struct pipe_ctx *pipe_ctx,
const struct dc_plane_cm *cm,
enum dc_cm2_transfer_func_source lut3d_src,
struct dc_cm2_func_luts *mcm_luts,
struct mpc *mpc,
bool lut_bank_a,
int mpcc_id);
void dcn42_hardware_release(struct dc *dc);

View File

@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode {
enum hubp_3dlut_fl_width {
hubp_3dlut_fl_width_17 = 17,
hubp_3dlut_fl_width_33 = 33,
hubp_3dlut_fl_width_17_transformed = 4916, //mpc default
hubp_3dlut_fl_width_transformed = 4916, //mpc default
};
enum hubp_3dlut_fl_crossbar_bit_slice {
@ -99,6 +99,22 @@ enum hubp_3dlut_fl_crossbar_bit_slice {
hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3
};
struct hubp_fl_3dlut_config {
bool enabled;
enum hubp_3dlut_fl_width width;
enum hubp_3dlut_fl_mode mode;
enum hubp_3dlut_fl_format format;
uint16_t bias;
uint16_t scale;
struct dc_plane_address address;
enum hubp_3dlut_fl_addressing_mode addr_mode;
enum dc_cm2_gpu_mem_layout layout;
uint8_t protection_bits;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
};
struct hubp {
const struct hubp_funcs *funcs;
struct dc_context *ctx;
@ -273,15 +289,24 @@ struct hubp_funcs {
void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, struct dml2_hubp_pipe_mcache_regs *mcache_regs);
void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t bias, uint16_t scale);
void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp,
enum hubp_3dlut_fl_mode mode);
void (*hubp_program_3dlut_fl_format)(struct hubp *hubp,
enum hubp_3dlut_fl_format format);
void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp,
const struct dc_plane_address *address);
void (*hubp_program_3dlut_fl_config)(struct hubp *hubp,
const struct dc_3dlut_dma *config);
const struct dc_plane_address address);
void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int refcyc_per_3dlut_group);
void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable);
void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode);
void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum hubp_3dlut_fl_width width);
void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t protection_bits);
void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp,
enum dc_cm_lut_pixel_format format);
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
int (*hubp_get_3dlut_fl_done)(struct hubp *hubp);
void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg);
void (*hubp_clear_tiling)(struct hubp *hubp);
uint32_t (*hubp_get_current_read_line)(struct hubp *hubp);
uint32_t (*hubp_get_det_config_error)(struct hubp *hubp);

View File

@ -54,7 +54,6 @@
#include "dc_hw_types.h"
#include "hw_shared.h"
#include "transform.h"
#include "dc_types.h"
#define MAX_MPCC 6
#define MAX_OPP 6
@ -102,6 +101,13 @@ enum mpcc_movable_cm_location {
MPCC_MOVABLE_CM_LOCATION_AFTER,
};
enum MCM_LUT_XABLE {
MCM_LUT_DISABLE,
MCM_LUT_DISABLED = MCM_LUT_DISABLE,
MCM_LUT_ENABLE,
MCM_LUT_ENABLED = MCM_LUT_ENABLE,
};
enum MCM_LUT_ID {
MCM_LUT_3DLUT,
MCM_LUT_1DLUT,
@ -110,7 +116,7 @@ enum MCM_LUT_ID {
struct mpc_fl_3dlut_config {
bool enabled;
enum dc_cm_lut_size size;
uint16_t width;
bool select_lut_bank_a;
uint16_t bit_depth;
int hubp_index;
@ -1069,11 +1075,8 @@ struct mpc_funcs {
*
* void
*/
void (*populate_lut)(struct mpc *mpc,
const enum MCM_LUT_ID id,
const union mcm_lut_params *params,
const bool lut_bank_a,
const int mpcc_id);
void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
bool lut_bank_a, int mpcc_id);
/**
* @program_lut_read_write_control:
@ -1084,18 +1087,13 @@ struct mpc_funcs {
* - [in/out] mpc - MPC context.
* - [in] id
* - [in] lut_bank_a
* - [in] bit_depth
* - [in] mpcc_id
*
* Return:
*
* void
*/
void (*program_lut_read_write_control)(struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool lut_bank_a,
const unsigned int bit_depth,
const int mpcc_id);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
/**
* @program_lut_mode:
@ -1105,44 +1103,33 @@ struct mpc_funcs {
* Parameters:
* - [in/out] mpc - MPC context.
* - [in] id
* - [in] enable
* - [in] xable
* - [in] lut_bank_a
* - [in] size
* - [in] mpcc_id
*
* Return:
*
* void
*/
void (*program_lut_mode)(struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool enable,
const bool lut_bank_a,
const enum dc_cm_lut_size size,
const int mpcc_id);
void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable,
bool lut_bank_a, int mpcc_id);
/**
* @get_lut_mode:
*
* Obtains enablement and ram bank status.
*
* Parameters:
* - [in/out] mpc - MPC context.
* - [in] id
* - [in] mpcc_id
* - [out] enable
* - [out] lut_bank_a
*
* Return:
*
* void
*/
void (*get_lut_mode)(struct mpc *mpc,
const enum MCM_LUT_ID id,
const int mpcc_id,
bool *enable,
bool *lut_bank_a);
* @mcm:
*
* MPC MCM new HW sequential programming functions
*/
struct {
void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
bool (*is_config_supported)(uint32_t width);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
bool lut_bank_a, bool enabled, int mpcc_id);
void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params,
bool lut_bank_a, int mpcc_id);
} mcm;
/**
* @rmcm:
@ -1155,11 +1142,9 @@ struct mpc_funcs {
void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,
bool lut_bank_a, bool enabled, int mpcc_id);
void (*program_lut_mode)(struct mpc *mpc,
bool enable,
bool lut_bank_a,
int mpcc_id);
void (*program_3dlut_size)(struct mpc *mpc, const enum dc_cm_lut_size size, int mpcc_id);
void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
bool lut_bank_a, int mpcc_id);
void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id);
void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id);
void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id);
bool (*is_config_supported)(uint32_t width);

View File

@ -73,15 +73,56 @@ void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_locati
}
}
void mpc401_populate_lut(struct mpc *mpc,
const enum MCM_LUT_ID id,
const union mcm_lut_params *params,
const bool lut_bank_a,
const int mpcc_id)
static enum dc_lut_mode get3dlut_config(
struct mpc *mpc,
bool *is_17x17x17,
bool *is_12bits_color_channel,
int mpcc_id)
{
uint32_t i_mode, i_enable_10bits, lut_size;
enum dc_lut_mode mode;
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
switch (i_mode) {
case 0:
mode = LUT_BYPASS;
break;
case 1:
mode = LUT_RAM_A;
break;
case 2:
mode = LUT_RAM_B;
break;
default:
mode = LUT_BYPASS;
break;
}
if (i_enable_10bits > 0)
*is_12bits_color_channel = false;
else
*is_12bits_color_channel = true;
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
if (lut_size == 0)
*is_17x17x17 = true;
else
*is_17x17x17 = false;
return mode;
}
void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id)
{
const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
const struct pwl_params *lut1d = params->pwl;
const struct pwl_params *lut_shaper = params->pwl;
const struct pwl_params *lut1d = params.pwl;
const struct pwl_params *lut_shaper = params.pwl;
bool is_17x17x17;
bool is_12bits_color_channel;
const struct dc_rgb *lut0;
@ -90,7 +131,7 @@ void mpc401_populate_lut(struct mpc *mpc,
const struct dc_rgb *lut3;
int lut_size0;
int lut_size;
const struct tetrahedral_params *lut3d = params->lut3d;
const struct tetrahedral_params *lut3d = params.lut3d;
switch (id) {
case MCM_LUT_1DLUT:
@ -133,6 +174,8 @@ void mpc401_populate_lut(struct mpc *mpc,
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
is_17x17x17 = !lut3d->use_tetrahedral_9;
is_12bits_color_channel = lut3d->use_12bits;
if (is_17x17x17) {
@ -155,6 +198,8 @@ void mpc401_populate_lut(struct mpc *mpc,
sizeof(lut3d->tetrahedral_9.lut1[0]);
}
mpc32_select_3dlut_ram(mpc, next_mode,
is_12bits_color_channel, mpcc_id);
mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
if (is_12bits_color_channel)
mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
@ -187,69 +232,46 @@ void mpc401_populate_lut(struct mpc *mpc,
}
static uint32_t mpc401_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size cm_size)
{
uint32_t size = 0;
switch (cm_size) {
case CM_LUT_SIZE_999:
size = 1;
break;
case CM_LUT_SIZE_171717:
size = 0;
break;
default:
/* invalid LUT size */
ASSERT(false);
size = 0;
break;
}
return size;
}
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool enable,
const bool lut_bank_a,
const enum dc_cm_lut_size size,
const int mpcc_id)
const enum MCM_LUT_XABLE xable,
bool lut_bank_a,
int mpcc_id)
{
uint32_t lut_size;
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
if (enable) {
lut_size = mpc401_cm_lut_size_to_3dlut_size(size);
REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2,
MPCC_MCM_3DLUT_SIZE, lut_size);
} else {
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
switch (xable) {
case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0);
break;
case MCM_LUT_ENABLE:
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2);
break;
}
break;
case MCM_LUT_SHAPER:
if (enable) {
REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
} else {
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
switch (xable) {
case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
break;
case MCM_LUT_ENABLE:
REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
break;
}
break;
case MCM_LUT_1DLUT:
if (enable) {
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE, 2);
} else {
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
switch (xable) {
case MCM_LUT_DISABLE:
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE, 0);
break;
case MCM_LUT_ENABLE:
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE, 2);
break;
}
REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
@ -257,20 +279,14 @@ void mpc401_program_lut_mode(
}
}
void mpc401_program_lut_read_write_control(struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool lut_bank_a,
const unsigned int bit_depth,
const int mpcc_id)
void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
{
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 : 0,
MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
break;
case MCM_LUT_SHAPER:
mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
@ -562,44 +578,6 @@ void mpc401_get_gamut_remap(struct mpc *mpc,
arr_reg_val, ARRAY_SIZE(arr_reg_val));
}
void mpc401_get_lut_mode(struct mpc *mpc,
const enum MCM_LUT_ID id,
const int mpcc_id,
bool *enable,
bool *lut_bank_a)
{
struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
uint32_t lut_mode = 0;
uint32_t lut_select = 0;
*enable = false;
*lut_bank_a = true;
switch (id) {
case MCM_LUT_SHAPER:
REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id],
MPCC_MCM_SHAPER_MODE_CURRENT, &lut_mode);
*enable = lut_mode != 0;
*lut_bank_a = lut_mode != 2;
break;
case MCM_LUT_1DLUT:
REG_GET_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
MPCC_MCM_1DLUT_MODE_CURRENT, &lut_mode,
MPCC_MCM_1DLUT_SELECT_CURRENT, &lut_select);
*enable = lut_mode != 0;
*lut_bank_a = lut_mode == 0 || lut_select == 0;
break;
case MCM_LUT_3DLUT:
default:
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
MPCC_MCM_3DLUT_MODE_CURRENT, &lut_mode);
*enable = lut_mode != 0;
*lut_bank_a = lut_mode != 2;
break;
}
}
static const struct mpc_funcs dcn401_mpc_funcs = {
.read_mpcc_state = mpc1_read_mpcc_state,
.insert_plane = mpc1_insert_plane,
@ -638,7 +616,6 @@ static const struct mpc_funcs dcn401_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
.get_lut_mode = mpc401_get_lut_mode,
};

View File

@ -206,32 +206,21 @@ void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
int num_rmu);
void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id);
void mpc401_populate_lut(struct mpc *mpc,
const enum MCM_LUT_ID id,
const union mcm_lut_params *params,
bool lut_bank_a,
int mpcc_id);
void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params,
bool lut_bank_a, int mpcc_id);
void mpc401_program_lut_mode(
struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool enable,
const bool lut_bank_a,
const enum dc_cm_lut_size size,
const int mpcc_id);
void mpc401_get_lut_mode(struct mpc *mpc,
const enum MCM_LUT_ID id,
const int mpcc_id,
bool *enable,
bool *lut_bank_a);
const enum MCM_LUT_XABLE xable,
bool lut_bank_a,
int mpcc_id);
void mpc401_program_lut_read_write_control(
struct mpc *mpc,
const enum MCM_LUT_ID id,
const bool lut_bank_a,
const unsigned int bit_depth,
const int mpcc_id);
bool lut_bank_a,
int mpcc_id);
void mpc401_set_gamut_remap(
struct mpc *mpc,

View File

@ -63,6 +63,154 @@ void mpc42_update_blending(
mpcc->blnd_cfg = *blnd_cfg;
}
/* Shaper functions */
void mpc42_power_on_shaper_3dlut(
struct mpc *mpc,
uint32_t mpcc_id,
bool power_on)
{
uint32_t power_status_shaper = 2;
uint32_t power_status_3dlut = 2;
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
int max_retries = 10;
REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
MPCC_MCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1:0);
/* wait for memory to fully power up */
if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
}
/*read status is not mandatory, it is just for debugging*/
REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper);
REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
if (power_status_shaper != 0 && power_on == true)
BREAK_TO_DEBUGGER();
if (power_status_3dlut != 0 && power_on == true)
BREAK_TO_DEBUGGER();
}
void mpc42_configure_shaper_lut(
struct mpc *mpc,
bool is_ram_a,
uint32_t mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
MPCC_MCM_SHAPER_SCALE_B, 0x7000);
REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id],
MPCC_MCM_SHAPER_SCALE_G, 0x7000);
REG_UPDATE(MPCC_MCM_SHAPER_SCALE_R[mpcc_id],
MPCC_MCM_SHAPER_SCALE_R, 0x7000);
REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0);
}
void mpc42_program_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
uint32_t size = 0xff;
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE,
(width == 33) ? 2 :
(width == 17) ? 0 : 2);
REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size);
}
void mpc42_program_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_R[mpcc_id],
MPCC_MCM_3DLUT_OUT_OFFSET_R, bias,
MPCC_MCM_3DLUT_OUT_SCALE_R, scale);
REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_G[mpcc_id],
MPCC_MCM_3DLUT_OUT_OFFSET_G, bias,
MPCC_MCM_3DLUT_OUT_SCALE_G, scale);
REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_B[mpcc_id],
MPCC_MCM_3DLUT_OUT_OFFSET_B, bias,
MPCC_MCM_3DLUT_OUT_SCALE_B, scale);
}
void mpc42_program_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK, 0xF);
//program bit_depth
REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
MPCC_MCM_3DLUT_30BIT_EN,
(bit_depth == 10) ? 1 : 0);
}
bool mpc42_is_config_supported(uint32_t width)
{
if (width == 17)
return true;
return false;
}
void mpc42_populate_lut(struct mpc *mpc, const union mcm_lut_params params,
bool lut_bank_a, int mpcc_id)
{
const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
const struct pwl_params *lut_shaper = params.pwl;
if (lut_shaper == NULL)
return;
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
mpc42_power_on_shaper_3dlut(mpc, mpcc_id, true);
mpc42_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
if (next_mode == LUT_RAM_A)
mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id);
else
mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id);
mpc32_program_shaper_lut(
mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id);
mpc42_power_on_shaper_3dlut(mpc, mpcc_id, false);
}
void mpc42_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id,
bool lut_bank_a, bool enabled, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
switch (id) {
case MCM_LUT_3DLUT:
REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE,
(!enabled) ? 0 :
(lut_bank_a) ? 1 : 2);
REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
break;
case MCM_LUT_SHAPER:
mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
break;
default:
break;
}
}
/* RMCM Shaper functions */
void mpc42_power_on_rmcm_shaper_3dlut(
struct mpc *mpc,
@ -526,47 +674,32 @@ void mpc42_program_rmcm_lut_read_write_control(struct mpc *mpc, const enum MCM_L
}
}
void mpc42_program_lut_mode(struct mpc *mpc,
bool enable,
bool lut_bank_a,
int mpcc_id)
void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable,
bool lut_bank_a, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
if (enable) {
REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
} else {
switch (xable) {
case MCM_LUT_DISABLE:
REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, 0);
break;
case MCM_LUT_ENABLE:
REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
break;
}
}
static uint32_t mpc42_get_rmcm_3dlut_width(
const enum dc_cm_lut_size size)
{
uint32_t width = 0;
switch (size) {
case CM_LUT_SIZE_333333:
width = 2;
break;
case CM_LUT_SIZE_171717:
default:
width = 0;
break;
}
return width;
}
void mpc42_program_rmcm_3dlut_size(struct mpc *mpc,
const enum dc_cm_lut_size size,
int mpcc_id)
void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id)
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
uint32_t width = mpc42_get_rmcm_3dlut_width(size);
uint32_t size = 0xff;
REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id],
MPC_RMCM_3DLUT_SIZE, width);
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);
REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size);
}
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id)
@ -598,6 +731,14 @@ void mpc42_program_rmcm_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_
(bit_depth == 10) ? 1 : 0);
}
bool mpc42_is_rmcm_config_supported(uint32_t width)
{
if (width == 17 || width == 33)
return true;
return false;
}
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,
@ -605,7 +746,6 @@ void mpc42_set_fl_config(
{
struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
uint32_t width = mpc42_get_rmcm_3dlut_width(cfg->size);
/*
From: Jie Zhou
@ -646,7 +786,7 @@ void mpc42_set_fl_config(
//width
REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id],
MPC_RMCM_3DLUT_SIZE, width,
MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0,
MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : (cfg->select_lut_bank_a) ? 1 : 2);
//connect to hubp
@ -659,6 +799,182 @@ void mpc42_set_fl_config(
REG_UPDATE(MPC_RMCM_CNTL[mpcc_id], MPC_RMCM_CNTL, cfg->enabled ? 0 : 0xF);
}
//static void rmcm_program_gamut_remap(
// struct mpc *mpc,
// unsigned int mpcc_id,
// const uint16_t *regval,
// enum mpcc_gamut_remap_id gamut_remap_block_id,
// enum mpcc_gamut_remap_mode_select mode_select)
//{
// struct color_matrices_reg gamut_regs;
// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
//
// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
// return;
// }
// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP) {
//
// if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0,
// MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
// return;
// }
//
// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
//
// switch (mode_select) {
// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
// break;
// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
// break;
// default:
// break;
// }
//
// cm_helper_program_color_matrices(
// mpc->ctx,
// regval,
// &gamut_regs);
//
// //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
// REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
// }
//}
//static bool is_mpc_legacy_gamut_id(enum mpcc_gamut_remap_id gamut_remap_block_id)
//{
// if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP ||
// gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP ||
// gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) {
// return true;
// }
// return false;
//}
//static void program_gamut_remap(
// struct mpc *mpc,
// unsigned int mpcc_id,
// const uint16_t *regval,
// enum mpcc_gamut_remap_id gamut_remap_block_id,
// enum mpcc_gamut_remap_mode_select mode_select)
//{
// if (is_mpc_legacy_gamut_id(gamut_remap_block_id))
// mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
// else
// rmcm_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
//}
//void mpc42_set_gamut_remap(
// struct mpc *mpc,
// int mpcc_id,
// const struct mpc_grph_gamut_adjustment *adjust)
//{
// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
// unsigned int i = 0;
// uint32_t mode_select = 0;
//
// if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
// /* Bypass / Disable if type is bypass or hw */
// program_gamut_remap(mpc, mpcc_id, NULL,
// adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0);
// } else {
// struct fixed31_32 arr_matrix[12];
// uint16_t arr_reg_val[12];
//
// for (i = 0; i < 12; i++)
// arr_matrix[i] = adjust->temperature_matrix[i];
//
// convert_float_matrix(arr_reg_val, arr_matrix, 12);
//
// if (is_mpc_legacy_gamut_id(adjust->mpcc_gamut_remap_block_id))
// REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
// MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
// else
// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id],
// MPC_RMCM_GAMUT_REMAP_MODE_CURRENT, &mode_select);
//
// //If current set in use not set A (MODE_1), then use set A, otherwise use set B
// if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
// else
// mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
//
// program_gamut_remap(mpc, mpcc_id, arr_reg_val,
// adjust->mpcc_gamut_remap_block_id, mode_select);
// }
//}
//static void read_gamut_remap(struct mpc *mpc,
// int mpcc_id,
// uint16_t *regval,
// enum mpcc_gamut_remap_id gamut_remap_block_id,
// uint32_t *mode_select)
//{
// struct color_matrices_reg gamut_regs = {0};
// struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc);
//
// if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) {
// mpc_read_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select);
// }
// if (gamut_remap_block_id == MPCC_RMCM_GAMUT_REMAP) {
// //current coefficient set in use
// REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], MPC_RMCM_GAMUT_REMAP_MODE, mode_select);
//
// gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
// gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
// gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
// gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
//
// switch (*mode_select) {
// case MPCC_GAMUT_REMAP_MODE_SELECT_1:
// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]);
// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]);
// break;
// case MPCC_GAMUT_REMAP_MODE_SELECT_2:
// gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]);
// gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]);
// break;
// default:
// break;
// }
// }
//
// if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
// cm_helper_read_color_matrices(
// mpc42->base.ctx,
// regval,
// &gamut_regs);
// }
//}
//void mpc42_get_gamut_remap(struct mpc *mpc,
// int mpcc_id,
// struct mpc_grph_gamut_adjustment *adjust)
//{
// uint16_t arr_reg_val[12] = {0};
// uint32_t mode_select;
//
// read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select);
//
// if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
// return;
// }
//
// adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
// convert_hw_matrix(adjust->temperature_matrix,
// arr_reg_val, ARRAY_SIZE(arr_reg_val));
//}
void mpc42_read_mpcc_state(
struct mpc *mpc,
int mpcc_inst,
@ -755,7 +1071,14 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
.get_lut_mode = mpc401_get_lut_mode,
.mcm = {
.program_lut_read_write_control = mpc42_program_lut_read_write_control,
.program_3dlut_size = mpc42_program_3dlut_size,
.program_bias_scale = mpc42_program_3dlut_fl_bias_scale,
.program_bit_depth = mpc42_program_bit_depth,
.is_config_supported = mpc42_is_config_supported,
.populate_lut = mpc42_populate_lut,
},
.rmcm = {
.enable_3dlut_fl = mpc42_enable_3dlut_fl,
.update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select,
@ -764,6 +1087,7 @@ static const struct mpc_funcs dcn42_mpc_funcs = {
.program_3dlut_size = mpc42_program_rmcm_3dlut_size,
.program_bias_scale = mpc42_program_rmcm_3dlut_fast_load_bias_scale,
.program_bit_depth = mpc42_program_rmcm_bit_depth,
.is_config_supported = mpc42_is_rmcm_config_supported,
.power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut,
.populate_lut = mpc42_populate_rmcm_lut,
.fl_3dlut_configure = mpc42_set_fl_config,

View File

@ -884,6 +884,49 @@ void dcn42_mpc_construct(struct dcn42_mpc *mpc401,
void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
void mpc42_program_shaper_lutb_settings(
struct mpc *mpc,
const struct pwl_params *params,
uint32_t mpcc_id);
void mpc42_program_shaper_luta_settings(
struct mpc *mpc,
const struct pwl_params *params,
uint32_t mpcc_id);
void mpc42_configure_shaper_lut(
struct mpc *mpc,
bool is_ram_a,
uint32_t mpcc_id);
void mpc42_power_on_shaper_3dlut(
struct mpc *mpc,
uint32_t mpcc_id,
bool power_on);
void mpc42_program_3dlut_size(
struct mpc *mpc,
uint32_t width,
int mpcc_id);
void mpc42_program_3dlut_fl_bias_scale(
struct mpc *mpc,
uint16_t bias,
uint16_t scale,
int mpcc_id);
void mpc42_program_bit_depth(
struct mpc *mpc,
uint16_t bit_depth,
int mpcc_id);
void mpc42_populate_lut(
struct mpc *mpc,
const union mcm_lut_params params,
bool lut_bank_a,
int mpcc_id);
void mpc42_program_lut_read_write_control(
struct mpc *mpc,
const enum MCM_LUT_ID id,
bool lut_bank_a,
bool enabled,
int mpcc_id);
bool mpc42_is_config_supported(uint32_t width);
/* RMCM */
void mpc42_program_rmcm_shaper_lut(
struct mpc *mpc,
@ -927,12 +970,12 @@ void mpc42_program_rmcm_lut_read_write_control(
int mpcc_id);
void mpc42_program_lut_mode(
struct mpc *mpc,
bool enable,
const enum MCM_LUT_XABLE xable,
bool lut_bank_a,
int mpcc_id);
void mpc42_program_rmcm_3dlut_size(
struct mpc *mpc,
const enum dc_cm_lut_size size,
uint32_t width,
int mpcc_id);
void mpc42_program_rmcm_3dlut_fast_load_bias_scale(
struct mpc *mpc,
@ -944,6 +987,8 @@ void mpc42_program_rmcm_bit_depth(
uint16_t bit_depth,
int mpcc_id);
bool mpc42_is_rmcm_config_supported(uint32_t width);
void mpc42_set_fl_config(
struct mpc *mpc,
struct mpc_fl_3dlut_config *cfg,

View File

@ -666,7 +666,6 @@ static const struct resource_caps res_cap_dcn42 = {
.num_vmid = 16,
.num_mpc_3dlut = 2,
.num_dsc = 4,
.num_rmcm = 2,
};
static const struct dc_plane_cap plane_cap = {