From: Alvin Lee <[email protected]> [Description] - Gamcor light sleep must be disabled before gamcor programming - Mirror the programming sequence for DSCL light sleep - Create a dcn60 version for gamcor programming - Make dcn30 helper functions public so they can be called from the new dcn60 function
Signed-off-by: Alvin Lee <[email protected]> Signed-off-by: Fangzhi Zuo <[email protected]> Reviewed-by: Nicholas Kazlauskas <[email protected]> --- drivers/gpu/drm/amd/display/dc/dpp/Makefile | 2 +- .../drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h | 22 ++++ .../amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c | 10 +- .../drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c | 2 +- .../drm/amd/display/dc/dpp/dcn60/dcn60_dpp.h | 3 + .../amd/display/dc/dpp/dcn60/dcn60_dpp_cm.c | 124 ++++++++++++++++++ 6 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp_cm.c diff --git a/drivers/gpu/drm/amd/display/dc/dpp/Makefile b/drivers/gpu/drm/amd/display/dc/dpp/Makefile index f5da45aacfca..2aaa0e8a8bd6 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dpp/Makefile @@ -99,7 +99,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_DPP_DCN50) ############################################################################### -DPP_DCN60 = dcn60_dpp.o dcn60_dpp_dscl.o +DPP_DCN60 = dcn60_dpp.o dcn60_dpp_dscl.o dcn60_dpp_cm.o AMD_DAL_DPP_DCN60 = $(addprefix $(AMDDALPATH)/dc/dpp/dcn60/,$(DPP_DCN60)) diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h index 6a61b99d6a79..f397e8222ac9 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h @@ -587,6 +587,28 @@ bool dpp3_construct(struct dcn3_dpp *dpp3, bool dpp3_program_gamcor_lut( struct dpp *dpp_base, const struct pwl_params *params); +struct dcn3_xfer_func_reg; + +void dpp3_enable_cm_block( + struct dpp *dpp_base); + +enum dc_lut_mode dpp30_get_gamcor_current( + struct dpp *dpp_base); + +void dpp3_program_gammcor_lut( + struct dpp *dpp_base, + const struct pwl_result_data *rgb, + uint32_t num, + bool is_ram_a); + +void dpp3_gamcor_reg_field( + struct dcn3_dpp *dpp, + struct dcn3_xfer_func_reg *reg); + +void dpp3_configure_gamcor_lut( + struct dpp *dpp_base, + bool is_ram_a); + void dpp3_program_CM_dealpha( struct dpp *dpp_base, uint32_t enable, uint32_t additive_blending); diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c index 083ab6acb687..86f47d33ec64 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c @@ -42,7 +42,7 @@ #define FN(reg_name, field_name) \ dpp->tf_shift->field_name, dpp->tf_mask->field_name -static void dpp3_enable_cm_block( +void dpp3_enable_cm_block( struct dpp *dpp_base) { struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); @@ -56,7 +56,7 @@ static void dpp3_enable_cm_block( REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode); } -static enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) +enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) { enum dc_lut_mode mode = LUT_BYPASS; uint32_t state_mode; @@ -76,7 +76,7 @@ static enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) return mode; } -static void dpp3_program_gammcor_lut( +void dpp3_program_gammcor_lut( struct dpp *dpp_base, const struct pwl_result_data *rgb, uint32_t num, @@ -171,7 +171,7 @@ void dpp3_program_cm_bias( CM_BIAS_CB_B, bias_params->cm_bias_cb_b); } -static void dpp3_gamcor_reg_field( +void dpp3_gamcor_reg_field( struct dcn3_dpp *dpp, struct dcn3_xfer_func_reg *reg) { @@ -204,7 +204,7 @@ static void dpp3_gamcor_reg_field( reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; } -static void dpp3_configure_gamcor_lut( +void dpp3_configure_gamcor_lut( struct dpp *dpp_base, bool is_ram_a) { diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c index f02aebcedd70..be2effb14fc3 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c @@ -294,7 +294,7 @@ void dpp60_full_bypass(struct dpp *dpp_base) } static struct dpp_funcs dcn60_dpp_funcs = { - .dpp_program_gamcor_lut = dpp3_program_gamcor_lut, + .dpp_program_gamcor_lut = dpp6_program_gamcor_lut, .dpp_read_state = dpp401_read_state, .dpp_reset = dpp_reset, .dpp_set_scaler = dpp60_dscl_set_scaler_manual_scale, diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.h index a0cc57e79ff7..5d09fcd04553 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.h @@ -518,5 +518,8 @@ bool dpp60_construct(struct dcn60_dpp *dpp60, const struct dcn60_dpp_shift *tf_shift, const struct dcn60_dpp_mask *tf_mask); +bool dpp6_program_gamcor_lut( + struct dpp *dpp_base, const struct pwl_params *params); + #endif /* __DCN60_DPP_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp_cm.c new file mode 100644 index 000000000000..cb34a9f856c1 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp_cm.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2025 Advanced Micro Devices, Inc. + + +#include "dm_services.h" +#include "core_types.h" +#include "reg_helper.h" +#include "dcn60/dcn60_dpp.h" +#include "basics/conversion.h" +#include "dcn30/dcn30_cm_common.h" + +#define REG(reg)\ + dpp->tf_regs->reg + +#define CTX \ + dpp->base.ctx + +#undef FN +#define FN(reg_name, field_name) \ + dpp->tf_shift->field_name, dpp->tf_mask->field_name + +static void dpp6_power_on_gamcor_lut(struct dpp *dpp_base, bool power_on) +{ + struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base); + + if (power_on) { + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_DIS, 1); + REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 100); + } else { + if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.cm) { + dpp->base.ctx->dc->optimized_required = true; + dpp->base.deferred_reg_writes.bits.disable_gamcor = true; + } + } +} + +bool dpp6_program_gamcor_lut( + struct dpp *dpp_base, const struct pwl_params *params) +{ + enum dc_lut_mode current_mode; + enum dc_lut_mode next_mode; + struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base); + struct dcn3_xfer_func_reg gam_regs; + + dpp3_enable_cm_block(dpp_base); + + if (params == NULL) { //bypass if we have no pwl data + REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 0); + if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) + dpp6_power_on_gamcor_lut(dpp_base, false); + return false; + } + dpp6_power_on_gamcor_lut(dpp_base, true); + REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 2); + + current_mode = dpp30_get_gamcor_current(dpp_base); + if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) + next_mode = LUT_RAM_B; + else + next_mode = LUT_RAM_A; + + dpp6_power_on_gamcor_lut(dpp_base, true); + dpp3_configure_gamcor_lut(dpp_base, next_mode == LUT_RAM_A); + + if (next_mode == LUT_RAM_B) { + gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMB_START_CNTL_B); + gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMB_START_CNTL_G); + gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMB_START_CNTL_R); + gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_B); + gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_G); + gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_R); + gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMB_END_CNTL1_B); + gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMB_END_CNTL2_B); + gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMB_END_CNTL1_G); + gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMB_END_CNTL2_G); + gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMB_END_CNTL1_R); + gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMB_END_CNTL2_R); + gam_regs.region_start = REG(CM_GAMCOR_RAMB_REGION_0_1); + gam_regs.region_end = REG(CM_GAMCOR_RAMB_REGION_32_33); + gam_regs.offset_b = REG(CM_GAMCOR_RAMB_OFFSET_B); + gam_regs.offset_g = REG(CM_GAMCOR_RAMB_OFFSET_G); + gam_regs.offset_r = REG(CM_GAMCOR_RAMB_OFFSET_R); + gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_B); + gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_G); + gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_R); + } else { + gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMA_START_CNTL_B); + gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMA_START_CNTL_G); + gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMA_START_CNTL_R); + gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_B); + gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_G); + gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_R); + gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMA_END_CNTL1_B); + gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMA_END_CNTL2_B); + gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMA_END_CNTL1_G); + gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMA_END_CNTL2_G); + gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMA_END_CNTL1_R); + gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMA_END_CNTL2_R); + gam_regs.region_start = REG(CM_GAMCOR_RAMA_REGION_0_1); + gam_regs.region_end = REG(CM_GAMCOR_RAMA_REGION_32_33); + gam_regs.offset_b = REG(CM_GAMCOR_RAMA_OFFSET_B); + gam_regs.offset_g = REG(CM_GAMCOR_RAMA_OFFSET_G); + gam_regs.offset_r = REG(CM_GAMCOR_RAMA_OFFSET_R); + gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_B); + gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_G); + gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_R); + } + + //get register fields + dpp3_gamcor_reg_field(TO_DCN30_DPP(dpp_base), &gam_regs); + + //program register set for LUTA/LUTB + cm_helper_program_gamcor_xfer_func(dpp_base->ctx, params, &gam_regs); + + dpp3_program_gammcor_lut(dpp_base, params->rgb_resulted, params->hw_points_num, + next_mode == LUT_RAM_A); + + //select Gamma LUT to use for next frame + REG_UPDATE(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT, next_mode == LUT_RAM_A ? 0:1); + + return true; +} -- 2.53.0
