103f54d7dSBhawanpreet Lakha /* 203f54d7dSBhawanpreet Lakha * Copyright 2020 Advanced Micro Devices, Inc. 303f54d7dSBhawanpreet Lakha * 403f54d7dSBhawanpreet Lakha * Permission is hereby granted, free of charge, to any person obtaining a 503f54d7dSBhawanpreet Lakha * copy of this software and associated documentation files (the "Software"), 603f54d7dSBhawanpreet Lakha * to deal in the Software without restriction, including without limitation 703f54d7dSBhawanpreet Lakha * the rights to use, copy, modify, merge, publish, distribute, sublicense, 803f54d7dSBhawanpreet Lakha * and/or sell copies of the Software, and to permit persons to whom the 903f54d7dSBhawanpreet Lakha * Software is furnished to do so, subject to the following conditions: 1003f54d7dSBhawanpreet Lakha * 1103f54d7dSBhawanpreet Lakha * The above copyright notice and this permission notice shall be included in 1203f54d7dSBhawanpreet Lakha * all copies or substantial portions of the Software. 1303f54d7dSBhawanpreet Lakha * 1403f54d7dSBhawanpreet Lakha * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1503f54d7dSBhawanpreet Lakha * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1603f54d7dSBhawanpreet Lakha * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1703f54d7dSBhawanpreet Lakha * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1803f54d7dSBhawanpreet Lakha * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1903f54d7dSBhawanpreet Lakha * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2003f54d7dSBhawanpreet Lakha * OTHER DEALINGS IN THE SOFTWARE. 2103f54d7dSBhawanpreet Lakha * 2203f54d7dSBhawanpreet Lakha * Authors: AMD 2303f54d7dSBhawanpreet Lakha * 2403f54d7dSBhawanpreet Lakha */ 2503f54d7dSBhawanpreet Lakha 2603f54d7dSBhawanpreet Lakha #include "dm_services.h" 2703f54d7dSBhawanpreet Lakha #include "core_types.h" 2803f54d7dSBhawanpreet Lakha #include "reg_helper.h" 2903f54d7dSBhawanpreet Lakha #include "dcn30_dpp.h" 3003f54d7dSBhawanpreet Lakha #include "basics/conversion.h" 3103f54d7dSBhawanpreet Lakha #include "dcn30_cm_common.h" 3203f54d7dSBhawanpreet Lakha 3303f54d7dSBhawanpreet Lakha #define REG(reg)\ 3403f54d7dSBhawanpreet Lakha dpp->tf_regs->reg 3503f54d7dSBhawanpreet Lakha 3603f54d7dSBhawanpreet Lakha #define CTX \ 3703f54d7dSBhawanpreet Lakha dpp->base.ctx 3803f54d7dSBhawanpreet Lakha 3903f54d7dSBhawanpreet Lakha #undef FN 4003f54d7dSBhawanpreet Lakha #define FN(reg_name, field_name) \ 4103f54d7dSBhawanpreet Lakha dpp->tf_shift->field_name, dpp->tf_mask->field_name 4203f54d7dSBhawanpreet Lakha 4303f54d7dSBhawanpreet Lakha static void dpp3_enable_cm_block( 4403f54d7dSBhawanpreet Lakha struct dpp *dpp_base) 4503f54d7dSBhawanpreet Lakha { 4603f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 4703f54d7dSBhawanpreet Lakha 4803f54d7dSBhawanpreet Lakha unsigned int cm_bypass_mode = 0; 4903f54d7dSBhawanpreet Lakha 5003f54d7dSBhawanpreet Lakha // debug option: put CM in bypass mode 5103f54d7dSBhawanpreet Lakha if (dpp_base->ctx->dc->debug.cm_in_bypass) 5203f54d7dSBhawanpreet Lakha cm_bypass_mode = 1; 5303f54d7dSBhawanpreet Lakha 5403f54d7dSBhawanpreet Lakha REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode); 5503f54d7dSBhawanpreet Lakha } 5603f54d7dSBhawanpreet Lakha 5703f54d7dSBhawanpreet Lakha static enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) 5803f54d7dSBhawanpreet Lakha { 5903f54d7dSBhawanpreet Lakha enum dc_lut_mode mode; 6003f54d7dSBhawanpreet Lakha uint32_t state_mode; 6103f54d7dSBhawanpreet Lakha uint32_t lut_mode; 6203f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 6303f54d7dSBhawanpreet Lakha 6403f54d7dSBhawanpreet Lakha REG_GET(CM_GAMCOR_CONTROL, 6503f54d7dSBhawanpreet Lakha CM_GAMCOR_MODE_CURRENT, &state_mode); 6603f54d7dSBhawanpreet Lakha 6703f54d7dSBhawanpreet Lakha if (state_mode == 0) 6803f54d7dSBhawanpreet Lakha mode = LUT_BYPASS; 6903f54d7dSBhawanpreet Lakha 7003f54d7dSBhawanpreet Lakha if (state_mode == 2) {//Programmable RAM LUT 7103f54d7dSBhawanpreet Lakha REG_GET(CM_GAMCOR_CONTROL, 7203f54d7dSBhawanpreet Lakha CM_GAMCOR_SELECT_CURRENT, &lut_mode); 7303f54d7dSBhawanpreet Lakha 7403f54d7dSBhawanpreet Lakha if (lut_mode == 0) 7503f54d7dSBhawanpreet Lakha mode = LUT_RAM_A; 7603f54d7dSBhawanpreet Lakha else 7703f54d7dSBhawanpreet Lakha mode = LUT_RAM_B; 7803f54d7dSBhawanpreet Lakha } 7903f54d7dSBhawanpreet Lakha 8003f54d7dSBhawanpreet Lakha return mode; 8103f54d7dSBhawanpreet Lakha } 8203f54d7dSBhawanpreet Lakha 8303f54d7dSBhawanpreet Lakha static void dpp3_program_gammcor_lut( 8403f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 8503f54d7dSBhawanpreet Lakha const struct pwl_result_data *rgb, 8603f54d7dSBhawanpreet Lakha uint32_t num, 8703f54d7dSBhawanpreet Lakha bool is_ram_a) 8803f54d7dSBhawanpreet Lakha { 8903f54d7dSBhawanpreet Lakha uint32_t i; 9003f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 9103f54d7dSBhawanpreet Lakha uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; 9203f54d7dSBhawanpreet Lakha uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; 9303f54d7dSBhawanpreet Lakha uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; 9403f54d7dSBhawanpreet Lakha 9503f54d7dSBhawanpreet Lakha /*fill in the LUT with all base values to be used by pwl module 9603f54d7dSBhawanpreet Lakha * HW auto increments the LUT index: back-to-back write 9703f54d7dSBhawanpreet Lakha */ 9803f54d7dSBhawanpreet Lakha if (is_rgb_equal(rgb, num)) { 9903f54d7dSBhawanpreet Lakha for (i = 0 ; i < num; i++) 10003f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].red_reg); 10103f54d7dSBhawanpreet Lakha 10203f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_red); 10303f54d7dSBhawanpreet Lakha 10403f54d7dSBhawanpreet Lakha } else { 10503f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 10603f54d7dSBhawanpreet Lakha CM_GAMCOR_LUT_WRITE_COLOR_MASK, 4); 10703f54d7dSBhawanpreet Lakha for (i = 0 ; i < num; i++) 10803f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].red_reg); 10903f54d7dSBhawanpreet Lakha 11003f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_red); 11103f54d7dSBhawanpreet Lakha 11203f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 11303f54d7dSBhawanpreet Lakha 11403f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 11503f54d7dSBhawanpreet Lakha CM_GAMCOR_LUT_WRITE_COLOR_MASK, 2); 11603f54d7dSBhawanpreet Lakha for (i = 0 ; i < num; i++) 11703f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].green_reg); 11803f54d7dSBhawanpreet Lakha 11903f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_green); 12003f54d7dSBhawanpreet Lakha 12103f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 12203f54d7dSBhawanpreet Lakha 12303f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 12403f54d7dSBhawanpreet Lakha CM_GAMCOR_LUT_WRITE_COLOR_MASK, 1); 12503f54d7dSBhawanpreet Lakha for (i = 0 ; i < num; i++) 12603f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].blue_reg); 12703f54d7dSBhawanpreet Lakha 12803f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_blue); 12903f54d7dSBhawanpreet Lakha } 13003f54d7dSBhawanpreet Lakha } 13103f54d7dSBhawanpreet Lakha 13203f54d7dSBhawanpreet Lakha static void dpp3_power_on_gamcor_lut( 13303f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 13403f54d7dSBhawanpreet Lakha bool power_on) 13503f54d7dSBhawanpreet Lakha { 13603f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 13703f54d7dSBhawanpreet Lakha 1383ba0a5f3SJacky Liao if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 139*5fdccd5bSMichael Strauss if (power_on) { 140*5fdccd5bSMichael Strauss REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); 1413ba0a5f3SJacky Liao REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); 142*5fdccd5bSMichael Strauss } else { 143*5fdccd5bSMichael Strauss dpp_base->ctx->dc->optimized_required = true; 144*5fdccd5bSMichael Strauss dpp_base->deferred_reg_writes.bits.disable_gamcor = true; 145*5fdccd5bSMichael Strauss } 1463ba0a5f3SJacky Liao } else 14703f54d7dSBhawanpreet Lakha REG_SET(CM_MEM_PWR_CTRL, 0, 14803f54d7dSBhawanpreet Lakha GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); 14903f54d7dSBhawanpreet Lakha } 15003f54d7dSBhawanpreet Lakha 15103f54d7dSBhawanpreet Lakha void dpp3_program_cm_dealpha( 15203f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 15303f54d7dSBhawanpreet Lakha uint32_t enable, uint32_t additive_blending) 15403f54d7dSBhawanpreet Lakha { 15503f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 15603f54d7dSBhawanpreet Lakha 15703f54d7dSBhawanpreet Lakha REG_SET_2(CM_DEALPHA, 0, 15803f54d7dSBhawanpreet Lakha CM_DEALPHA_EN, enable, 15903f54d7dSBhawanpreet Lakha CM_DEALPHA_ABLND, additive_blending); 16003f54d7dSBhawanpreet Lakha } 16103f54d7dSBhawanpreet Lakha 16203f54d7dSBhawanpreet Lakha void dpp3_program_cm_bias( 16303f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 16403f54d7dSBhawanpreet Lakha struct CM_bias_params *bias_params) 16503f54d7dSBhawanpreet Lakha { 16603f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 16703f54d7dSBhawanpreet Lakha 16803f54d7dSBhawanpreet Lakha REG_SET(CM_BIAS_CR_R, 0, CM_BIAS_CR_R, bias_params->cm_bias_cr_r); 16903f54d7dSBhawanpreet Lakha REG_SET_2(CM_BIAS_Y_G_CB_B, 0, 17003f54d7dSBhawanpreet Lakha CM_BIAS_Y_G, bias_params->cm_bias_y_g, 17103f54d7dSBhawanpreet Lakha CM_BIAS_CB_B, bias_params->cm_bias_cb_b); 17203f54d7dSBhawanpreet Lakha } 17303f54d7dSBhawanpreet Lakha 17403f54d7dSBhawanpreet Lakha static void dpp3_gamcor_reg_field( 17503f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp, 17603f54d7dSBhawanpreet Lakha struct dcn3_xfer_func_reg *reg) 17703f54d7dSBhawanpreet Lakha { 17803f54d7dSBhawanpreet Lakha 17903f54d7dSBhawanpreet Lakha reg->shifts.field_region_start_base = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_BASE_B; 18003f54d7dSBhawanpreet Lakha reg->masks.field_region_start_base = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_BASE_B; 18103f54d7dSBhawanpreet Lakha reg->shifts.field_offset = dpp->tf_shift->CM_GAMCOR_RAMA_OFFSET_B; 18203f54d7dSBhawanpreet Lakha reg->masks.field_offset = dpp->tf_mask->CM_GAMCOR_RAMA_OFFSET_B; 18303f54d7dSBhawanpreet Lakha 18403f54d7dSBhawanpreet Lakha reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET; 18503f54d7dSBhawanpreet Lakha reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET; 18603f54d7dSBhawanpreet Lakha reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS; 18703f54d7dSBhawanpreet Lakha reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS; 18803f54d7dSBhawanpreet Lakha reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET; 18903f54d7dSBhawanpreet Lakha reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET; 19003f54d7dSBhawanpreet Lakha reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS; 19103f54d7dSBhawanpreet Lakha reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS; 19203f54d7dSBhawanpreet Lakha 19303f54d7dSBhawanpreet Lakha reg->shifts.field_region_end = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_B; 19403f54d7dSBhawanpreet Lakha reg->masks.field_region_end = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_B; 19503f54d7dSBhawanpreet Lakha reg->shifts.field_region_end_slope = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B; 19603f54d7dSBhawanpreet Lakha reg->masks.field_region_end_slope = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B; 19703f54d7dSBhawanpreet Lakha reg->shifts.field_region_end_base = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_BASE_B; 19803f54d7dSBhawanpreet Lakha reg->masks.field_region_end_base = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_BASE_B; 19903f54d7dSBhawanpreet Lakha reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B; 20003f54d7dSBhawanpreet Lakha reg->masks.field_region_linear_slope = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B; 20103f54d7dSBhawanpreet Lakha reg->shifts.exp_region_start = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_B; 20203f54d7dSBhawanpreet Lakha reg->masks.exp_region_start = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_B; 20303f54d7dSBhawanpreet Lakha reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; 20403f54d7dSBhawanpreet Lakha reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; 20503f54d7dSBhawanpreet Lakha } 20603f54d7dSBhawanpreet Lakha 20703f54d7dSBhawanpreet Lakha static void dpp3_configure_gamcor_lut( 20803f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 20903f54d7dSBhawanpreet Lakha bool is_ram_a) 21003f54d7dSBhawanpreet Lakha { 21103f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 21203f54d7dSBhawanpreet Lakha 21303f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 21403f54d7dSBhawanpreet Lakha CM_GAMCOR_LUT_WRITE_COLOR_MASK, 7); 21503f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 21603f54d7dSBhawanpreet Lakha CM_GAMCOR_LUT_HOST_SEL, is_ram_a == true ? 0:1); 21703f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 21803f54d7dSBhawanpreet Lakha } 21903f54d7dSBhawanpreet Lakha 22003f54d7dSBhawanpreet Lakha 22103f54d7dSBhawanpreet Lakha bool dpp3_program_gamcor_lut( 22203f54d7dSBhawanpreet Lakha struct dpp *dpp_base, const struct pwl_params *params) 22303f54d7dSBhawanpreet Lakha { 22403f54d7dSBhawanpreet Lakha enum dc_lut_mode current_mode; 22503f54d7dSBhawanpreet Lakha enum dc_lut_mode next_mode; 22603f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 22703f54d7dSBhawanpreet Lakha struct dcn3_xfer_func_reg gam_regs; 22803f54d7dSBhawanpreet Lakha 22903f54d7dSBhawanpreet Lakha dpp3_enable_cm_block(dpp_base); 23003f54d7dSBhawanpreet Lakha 23103f54d7dSBhawanpreet Lakha if (params == NULL) { //bypass if we have no pwl data 23203f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 0); 2333ba0a5f3SJacky Liao if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) 2343ba0a5f3SJacky Liao dpp3_power_on_gamcor_lut(dpp_base, false); 23503f54d7dSBhawanpreet Lakha return false; 23603f54d7dSBhawanpreet Lakha } 23703f54d7dSBhawanpreet Lakha dpp3_power_on_gamcor_lut(dpp_base, true); 23803f54d7dSBhawanpreet Lakha REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 2); 23903f54d7dSBhawanpreet Lakha 24003f54d7dSBhawanpreet Lakha current_mode = dpp30_get_gamcor_current(dpp_base); 24103f54d7dSBhawanpreet Lakha if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 24203f54d7dSBhawanpreet Lakha next_mode = LUT_RAM_B; 24303f54d7dSBhawanpreet Lakha else 24403f54d7dSBhawanpreet Lakha next_mode = LUT_RAM_A; 24503f54d7dSBhawanpreet Lakha 24603f54d7dSBhawanpreet Lakha dpp3_power_on_gamcor_lut(dpp_base, true); 247439e6bbbSJiapeng Chong dpp3_configure_gamcor_lut(dpp_base, next_mode == LUT_RAM_A); 24803f54d7dSBhawanpreet Lakha 24903f54d7dSBhawanpreet Lakha if (next_mode == LUT_RAM_B) { 25003f54d7dSBhawanpreet Lakha gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMB_START_CNTL_B); 25103f54d7dSBhawanpreet Lakha gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMB_START_CNTL_G); 25203f54d7dSBhawanpreet Lakha gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMB_START_CNTL_R); 25303f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_B); 25403f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_G); 25503f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_R); 25603f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMB_END_CNTL1_B); 25703f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMB_END_CNTL2_B); 25803f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMB_END_CNTL1_G); 25903f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMB_END_CNTL2_G); 26003f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMB_END_CNTL1_R); 26103f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMB_END_CNTL2_R); 26203f54d7dSBhawanpreet Lakha gam_regs.region_start = REG(CM_GAMCOR_RAMB_REGION_0_1); 26303f54d7dSBhawanpreet Lakha gam_regs.region_end = REG(CM_GAMCOR_RAMB_REGION_32_33); 26403f54d7dSBhawanpreet Lakha //New registers in DCN3AG/DCN GAMCOR block 26503f54d7dSBhawanpreet Lakha gam_regs.offset_b = REG(CM_GAMCOR_RAMB_OFFSET_B); 26603f54d7dSBhawanpreet Lakha gam_regs.offset_g = REG(CM_GAMCOR_RAMB_OFFSET_G); 26703f54d7dSBhawanpreet Lakha gam_regs.offset_r = REG(CM_GAMCOR_RAMB_OFFSET_R); 26803f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_B); 26903f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_G); 27003f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_R); 27103f54d7dSBhawanpreet Lakha } else { 27203f54d7dSBhawanpreet Lakha gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMA_START_CNTL_B); 27303f54d7dSBhawanpreet Lakha gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMA_START_CNTL_G); 27403f54d7dSBhawanpreet Lakha gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMA_START_CNTL_R); 27503f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_B); 27603f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_G); 27703f54d7dSBhawanpreet Lakha gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_R); 27803f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMA_END_CNTL1_B); 27903f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMA_END_CNTL2_B); 28003f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMA_END_CNTL1_G); 28103f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMA_END_CNTL2_G); 28203f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMA_END_CNTL1_R); 28303f54d7dSBhawanpreet Lakha gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMA_END_CNTL2_R); 28403f54d7dSBhawanpreet Lakha gam_regs.region_start = REG(CM_GAMCOR_RAMA_REGION_0_1); 28503f54d7dSBhawanpreet Lakha gam_regs.region_end = REG(CM_GAMCOR_RAMA_REGION_32_33); 28603f54d7dSBhawanpreet Lakha //New registers in DCN3AG/DCN GAMCOR block 28703f54d7dSBhawanpreet Lakha gam_regs.offset_b = REG(CM_GAMCOR_RAMA_OFFSET_B); 28803f54d7dSBhawanpreet Lakha gam_regs.offset_g = REG(CM_GAMCOR_RAMA_OFFSET_G); 28903f54d7dSBhawanpreet Lakha gam_regs.offset_r = REG(CM_GAMCOR_RAMA_OFFSET_R); 29003f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_B); 29103f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_G); 29203f54d7dSBhawanpreet Lakha gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_R); 29303f54d7dSBhawanpreet Lakha } 29403f54d7dSBhawanpreet Lakha 29503f54d7dSBhawanpreet Lakha //get register fields 29603f54d7dSBhawanpreet Lakha dpp3_gamcor_reg_field(dpp, &gam_regs); 29703f54d7dSBhawanpreet Lakha 29803f54d7dSBhawanpreet Lakha //program register set for LUTA/LUTB 29903f54d7dSBhawanpreet Lakha cm_helper_program_gamcor_xfer_func(dpp_base->ctx, params, &gam_regs); 30003f54d7dSBhawanpreet Lakha 30103f54d7dSBhawanpreet Lakha dpp3_program_gammcor_lut(dpp_base, params->rgb_resulted, params->hw_points_num, 302db6c5b85SJiapeng Chong next_mode == LUT_RAM_A); 30303f54d7dSBhawanpreet Lakha 30403f54d7dSBhawanpreet Lakha //select Gamma LUT to use for next frame 30503f54d7dSBhawanpreet Lakha REG_UPDATE(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT, next_mode == LUT_RAM_A ? 0:1); 30603f54d7dSBhawanpreet Lakha 30703f54d7dSBhawanpreet Lakha return true; 30803f54d7dSBhawanpreet Lakha } 30903f54d7dSBhawanpreet Lakha 31003f54d7dSBhawanpreet Lakha void dpp3_set_hdr_multiplier( 31103f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 31203f54d7dSBhawanpreet Lakha uint32_t multiplier) 31303f54d7dSBhawanpreet Lakha { 31403f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 31503f54d7dSBhawanpreet Lakha 31603f54d7dSBhawanpreet Lakha REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier); 31703f54d7dSBhawanpreet Lakha } 31803f54d7dSBhawanpreet Lakha 31903f54d7dSBhawanpreet Lakha 32003f54d7dSBhawanpreet Lakha static void program_gamut_remap( 32103f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp, 32203f54d7dSBhawanpreet Lakha const uint16_t *regval, 32303f54d7dSBhawanpreet Lakha int select) 32403f54d7dSBhawanpreet Lakha { 32503f54d7dSBhawanpreet Lakha uint16_t selection = 0; 32603f54d7dSBhawanpreet Lakha struct color_matrices_reg gam_regs; 32703f54d7dSBhawanpreet Lakha 32803f54d7dSBhawanpreet Lakha if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 32903f54d7dSBhawanpreet Lakha REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 33003f54d7dSBhawanpreet Lakha CM_GAMUT_REMAP_MODE, 0); 33103f54d7dSBhawanpreet Lakha return; 33203f54d7dSBhawanpreet Lakha } 33303f54d7dSBhawanpreet Lakha switch (select) { 33403f54d7dSBhawanpreet Lakha case GAMUT_REMAP_COEFF: 33503f54d7dSBhawanpreet Lakha selection = 1; 33603f54d7dSBhawanpreet Lakha break; 33703f54d7dSBhawanpreet Lakha /*this corresponds to GAMUT_REMAP coefficients set B 33803f54d7dSBhawanpreet Lakha *we don't have common coefficient sets in dcn3ag/dcn3 33903f54d7dSBhawanpreet Lakha */ 34003f54d7dSBhawanpreet Lakha case GAMUT_REMAP_COMA_COEFF: 34103f54d7dSBhawanpreet Lakha selection = 2; 34203f54d7dSBhawanpreet Lakha break; 34303f54d7dSBhawanpreet Lakha default: 34403f54d7dSBhawanpreet Lakha break; 34503f54d7dSBhawanpreet Lakha } 34603f54d7dSBhawanpreet Lakha 34703f54d7dSBhawanpreet Lakha gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; 34803f54d7dSBhawanpreet Lakha gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; 34903f54d7dSBhawanpreet Lakha gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; 35003f54d7dSBhawanpreet Lakha gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; 35103f54d7dSBhawanpreet Lakha 35203f54d7dSBhawanpreet Lakha 35303f54d7dSBhawanpreet Lakha if (select == GAMUT_REMAP_COEFF) { 35403f54d7dSBhawanpreet Lakha gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12); 35503f54d7dSBhawanpreet Lakha gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 35603f54d7dSBhawanpreet Lakha 35703f54d7dSBhawanpreet Lakha cm_helper_program_color_matrices( 35803f54d7dSBhawanpreet Lakha dpp->base.ctx, 35903f54d7dSBhawanpreet Lakha regval, 36003f54d7dSBhawanpreet Lakha &gam_regs); 36103f54d7dSBhawanpreet Lakha 36203f54d7dSBhawanpreet Lakha } else if (select == GAMUT_REMAP_COMA_COEFF) { 36303f54d7dSBhawanpreet Lakha 36403f54d7dSBhawanpreet Lakha gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12); 36503f54d7dSBhawanpreet Lakha gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34); 36603f54d7dSBhawanpreet Lakha 36703f54d7dSBhawanpreet Lakha cm_helper_program_color_matrices( 36803f54d7dSBhawanpreet Lakha dpp->base.ctx, 36903f54d7dSBhawanpreet Lakha regval, 37003f54d7dSBhawanpreet Lakha &gam_regs); 37103f54d7dSBhawanpreet Lakha 37203f54d7dSBhawanpreet Lakha } 37303f54d7dSBhawanpreet Lakha //select coefficient set to use 37403f54d7dSBhawanpreet Lakha REG_SET( 37503f54d7dSBhawanpreet Lakha CM_GAMUT_REMAP_CONTROL, 0, 37603f54d7dSBhawanpreet Lakha CM_GAMUT_REMAP_MODE, selection); 37703f54d7dSBhawanpreet Lakha } 37803f54d7dSBhawanpreet Lakha 37903f54d7dSBhawanpreet Lakha void dpp3_cm_set_gamut_remap( 38003f54d7dSBhawanpreet Lakha struct dpp *dpp_base, 38103f54d7dSBhawanpreet Lakha const struct dpp_grph_csc_adjustment *adjust) 38203f54d7dSBhawanpreet Lakha { 38303f54d7dSBhawanpreet Lakha struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 38403f54d7dSBhawanpreet Lakha int i = 0; 38503f54d7dSBhawanpreet Lakha int gamut_mode; 38603f54d7dSBhawanpreet Lakha 38703f54d7dSBhawanpreet Lakha if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 38803f54d7dSBhawanpreet Lakha /* Bypass if type is bypass or hw */ 38903f54d7dSBhawanpreet Lakha program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS); 39003f54d7dSBhawanpreet Lakha else { 39103f54d7dSBhawanpreet Lakha struct fixed31_32 arr_matrix[12]; 39203f54d7dSBhawanpreet Lakha uint16_t arr_reg_val[12]; 39303f54d7dSBhawanpreet Lakha 39403f54d7dSBhawanpreet Lakha for (i = 0; i < 12; i++) 39503f54d7dSBhawanpreet Lakha arr_matrix[i] = adjust->temperature_matrix[i]; 39603f54d7dSBhawanpreet Lakha 39703f54d7dSBhawanpreet Lakha convert_float_matrix( 39803f54d7dSBhawanpreet Lakha arr_reg_val, arr_matrix, 12); 39903f54d7dSBhawanpreet Lakha 40003f54d7dSBhawanpreet Lakha //current coefficient set in use 40103f54d7dSBhawanpreet Lakha REG_GET(CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE_CURRENT, &gamut_mode); 40203f54d7dSBhawanpreet Lakha 40303f54d7dSBhawanpreet Lakha if (gamut_mode == 0) 40403f54d7dSBhawanpreet Lakha gamut_mode = 1; //use coefficient set A 40503f54d7dSBhawanpreet Lakha else if (gamut_mode == 1) 40603f54d7dSBhawanpreet Lakha gamut_mode = 2; 40703f54d7dSBhawanpreet Lakha else 40803f54d7dSBhawanpreet Lakha gamut_mode = 1; 40903f54d7dSBhawanpreet Lakha 41003f54d7dSBhawanpreet Lakha //follow dcn2 approach for now - using only coefficient set A 41103f54d7dSBhawanpreet Lakha program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF); 41203f54d7dSBhawanpreet Lakha } 41303f54d7dSBhawanpreet Lakha } 414