Home | History | Annotate | Line # | Download | only in dcn20
      1 /*	$NetBSD: amdgpu_dcn20_dpp_cm.c,v 1.2 2021/12/18 23:45:03 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2016 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dcn20_dpp_cm.c,v 1.2 2021/12/18 23:45:03 riastradh Exp $");
     30 
     31 #include "dm_services.h"
     32 
     33 #include "core_types.h"
     34 
     35 #include "reg_helper.h"
     36 #include "dcn20_dpp.h"
     37 #include "basics/conversion.h"
     38 
     39 #include "dcn10/dcn10_cm_common.h"
     40 
     41 #define REG(reg)\
     42 	dpp->tf_regs->reg
     43 
     44 #define IND_REG(index) \
     45 	(index)
     46 
     47 #define CTX \
     48 	dpp->base.ctx
     49 
     50 #undef FN
     51 #define FN(reg_name, field_name) \
     52 	dpp->tf_shift->field_name, dpp->tf_mask->field_name
     53 
     54 
     55 static void dpp2_enable_cm_block(
     56 		struct dpp *dpp_base)
     57 {
     58 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     59 
     60 	unsigned int cm_bypass_mode = 0;
     61 	//Temp, put CM in bypass mode
     62 	if (dpp_base->ctx->dc->debug.cm_in_bypass)
     63 		cm_bypass_mode = 1;
     64 
     65 	REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
     66 }
     67 
     68 
     69 static bool dpp2_degamma_ram_inuse(
     70 		struct dpp *dpp_base,
     71 		bool *ram_a_inuse)
     72 {
     73 	bool ret = false;
     74 	uint32_t status_reg = 0;
     75 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     76 
     77 	REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
     78 			&status_reg);
     79 
     80 	if (status_reg == 3) {
     81 		*ram_a_inuse = true;
     82 		ret = true;
     83 	} else if (status_reg == 4) {
     84 		*ram_a_inuse = false;
     85 		ret = true;
     86 	}
     87 	return ret;
     88 }
     89 
     90 static void dpp2_program_degamma_lut(
     91 		struct dpp *dpp_base,
     92 		const struct pwl_result_data *rgb,
     93 		uint32_t num,
     94 		bool is_ram_a)
     95 {
     96 	uint32_t i;
     97 
     98 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     99 	REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
    100 				CM_DGAM_LUT_WRITE_EN_MASK, 7);
    101 	REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
    102 					is_ram_a == true ? 0:1);
    103 
    104 	REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
    105 	for (i = 0 ; i < num; i++) {
    106 		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
    107 		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
    108 		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
    109 
    110 		REG_SET(CM_DGAM_LUT_DATA, 0,
    111 				CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
    112 		REG_SET(CM_DGAM_LUT_DATA, 0,
    113 				CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
    114 		REG_SET(CM_DGAM_LUT_DATA, 0,
    115 				CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
    116 
    117 	}
    118 
    119 }
    120 
    121 void dpp2_set_degamma_pwl(
    122 		struct dpp *dpp_base,
    123 		const struct pwl_params *params)
    124 {
    125 	bool is_ram_a = true;
    126 
    127 	dpp1_power_on_degamma_lut(dpp_base, true);
    128 	dpp2_enable_cm_block(dpp_base);
    129 	dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
    130 	if (is_ram_a == true)
    131 		dpp1_program_degamma_lutb_settings(dpp_base, params);
    132 	else
    133 		dpp1_program_degamma_luta_settings(dpp_base, params);
    134 
    135 	dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
    136 	dpp1_degamma_ram_select(dpp_base, !is_ram_a);
    137 }
    138 
    139 void dpp2_set_degamma(
    140 		struct dpp *dpp_base,
    141 		enum ipp_degamma_mode mode)
    142 {
    143 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    144 	dpp2_enable_cm_block(dpp_base);
    145 
    146 	switch (mode) {
    147 	case IPP_DEGAMMA_MODE_BYPASS:
    148 		/* Setting de gamma bypass for now */
    149 		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
    150 		break;
    151 	case IPP_DEGAMMA_MODE_HW_sRGB:
    152 		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
    153 		break;
    154 	case IPP_DEGAMMA_MODE_HW_xvYCC:
    155 		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
    156 			break;
    157 	case IPP_DEGAMMA_MODE_USER_PWL:
    158 		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
    159 		break;
    160 	default:
    161 		BREAK_TO_DEBUGGER();
    162 		break;
    163 	}
    164 }
    165 
    166 static void program_gamut_remap(
    167 		struct dcn20_dpp *dpp,
    168 		const uint16_t *regval,
    169 		enum dcn20_gamut_remap_select select)
    170 {
    171 	uint32_t cur_select = 0;
    172 	struct color_matrices_reg gam_regs;
    173 
    174 	if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
    175 		REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
    176 				CM_GAMUT_REMAP_MODE, 0);
    177 		return;
    178 	}
    179 
    180 	/* determine which gamut_remap coefficients (A or B) we are using
    181 	 * currently. select the alternate set to double buffer
    182 	 * the update so gamut_remap is updated on frame boundary
    183 	 */
    184 	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
    185 					CM_TEST_DEBUG_DATA_STATUS_IDX,
    186 					CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
    187 
    188 	/* value stored in dbg reg will be 1 greater than mode we want */
    189 	if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
    190 		select = DCN2_GAMUT_REMAP_COEF_A;
    191 	else
    192 		select = DCN2_GAMUT_REMAP_COEF_B;
    193 
    194 	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
    195 	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_GAMUT_REMAP_C11;
    196 	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
    197 	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
    198 
    199 	if (select == DCN2_GAMUT_REMAP_COEF_A) {
    200 		gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
    201 		gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
    202 	} else {
    203 		gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
    204 		gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
    205 	}
    206 
    207 	cm_helper_program_color_matrices(
    208 				dpp->base.ctx,
    209 				regval,
    210 				&gam_regs);
    211 
    212 	REG_SET(
    213 			CM_GAMUT_REMAP_CONTROL, 0,
    214 			CM_GAMUT_REMAP_MODE, select);
    215 
    216 }
    217 
    218 void dpp2_cm_set_gamut_remap(
    219 	struct dpp *dpp_base,
    220 	const struct dpp_grph_csc_adjustment *adjust)
    221 {
    222 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    223 	int i = 0;
    224 
    225 	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
    226 		/* Bypass if type is bypass or hw */
    227 		program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
    228 	else {
    229 		struct fixed31_32 arr_matrix[12];
    230 		uint16_t arr_reg_val[12];
    231 
    232 		for (i = 0; i < 12; i++)
    233 			arr_matrix[i] = adjust->temperature_matrix[i];
    234 
    235 		convert_float_matrix(
    236 			arr_reg_val, arr_matrix, 12);
    237 
    238 		program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
    239 	}
    240 }
    241 
    242 void dpp2_program_input_csc(
    243 		struct dpp *dpp_base,
    244 		enum dc_color_space color_space,
    245 		enum dcn20_input_csc_select input_select,
    246 		const struct out_csc_color_matrix *tbl_entry)
    247 {
    248 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    249 	int i;
    250 	int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
    251 	const uint16_t *regval = NULL;
    252 	uint32_t cur_select = 0;
    253 	enum dcn20_input_csc_select select;
    254 	struct color_matrices_reg icsc_regs;
    255 
    256 	if (input_select == DCN2_ICSC_SELECT_BYPASS) {
    257 		REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
    258 		return;
    259 	}
    260 
    261 	if (tbl_entry == NULL) {
    262 		for (i = 0; i < arr_size; i++)
    263 			if (dpp_input_csc_matrix[i].color_space == color_space) {
    264 				regval = dpp_input_csc_matrix[i].regval;
    265 				break;
    266 			}
    267 
    268 		if (regval == NULL) {
    269 			BREAK_TO_DEBUGGER();
    270 			return;
    271 		}
    272 	} else {
    273 		regval = tbl_entry->regval;
    274 	}
    275 
    276 	/* determine which CSC coefficients (A or B) we are using
    277 	 * currently.  select the alternate set to double buffer
    278 	 * the CSC update so CSC is updated on frame boundary
    279 	 */
    280 	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
    281 					CM_TEST_DEBUG_DATA_STATUS_IDX,
    282 					CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
    283 
    284 	if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
    285 		select = DCN2_ICSC_SELECT_ICSC_A;
    286 	else
    287 		select = DCN2_ICSC_SELECT_ICSC_B;
    288 
    289 	icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
    290 	icsc_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
    291 	icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
    292 	icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
    293 
    294 	if (select == DCN2_ICSC_SELECT_ICSC_A) {
    295 
    296 		icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
    297 		icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
    298 
    299 	} else {
    300 
    301 		icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
    302 		icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
    303 
    304 	}
    305 
    306 	cm_helper_program_color_matrices(
    307 			dpp->base.ctx,
    308 			regval,
    309 			&icsc_regs);
    310 
    311 	REG_SET(CM_ICSC_CONTROL, 0,
    312 				CM_ICSC_MODE, select);
    313 }
    314 
    315 static void dpp20_power_on_blnd_lut(
    316 	struct dpp *dpp_base,
    317 	bool power_on)
    318 {
    319 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    320 
    321 	REG_SET(CM_MEM_PWR_CTRL, 0,
    322 			BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
    323 
    324 }
    325 
    326 static void dpp20_configure_blnd_lut(
    327 		struct dpp *dpp_base,
    328 		bool is_ram_a)
    329 {
    330 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    331 
    332 	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    333 			CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
    334 	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    335 			CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
    336 	REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
    337 }
    338 
    339 static void dpp20_program_blnd_pwl(
    340 		struct dpp *dpp_base,
    341 		const struct pwl_result_data *rgb,
    342 		uint32_t num)
    343 {
    344 	uint32_t i;
    345 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    346 
    347 	for (i = 0 ; i < num; i++) {
    348 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
    349 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
    350 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
    351 
    352 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    353 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
    354 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    355 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
    356 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    357 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
    358 
    359 	}
    360 
    361 }
    362 
    363 static void dcn20_dpp_cm_get_reg_field(
    364 		struct dcn20_dpp *dpp,
    365 		struct xfer_func_reg *reg)
    366 {
    367 	reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
    368 	reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
    369 	reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
    370 	reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
    371 	reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
    372 	reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
    373 	reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
    374 	reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
    375 
    376 	reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
    377 	reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
    378 	reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
    379 	reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
    380 	reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
    381 	reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
    382 	reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
    383 	reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
    384 	reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
    385 	reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
    386 	reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
    387 	reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
    388 }
    389 
    390 /*program blnd lut RAM A*/
    391 static void dpp20_program_blnd_luta_settings(
    392 		struct dpp *dpp_base,
    393 		const struct pwl_params *params)
    394 {
    395 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    396 	struct xfer_func_reg gam_regs;
    397 
    398 	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
    399 
    400 	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
    401 	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
    402 	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
    403 	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
    404 	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
    405 	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
    406 	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
    407 	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
    408 	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
    409 	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
    410 	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
    411 	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
    412 	gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
    413 	gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
    414 
    415 	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
    416 }
    417 
    418 /*program blnd lut RAM B*/
    419 static void dpp20_program_blnd_lutb_settings(
    420 		struct dpp *dpp_base,
    421 		const struct pwl_params *params)
    422 {
    423 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    424 	struct xfer_func_reg gam_regs;
    425 
    426 	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
    427 
    428 	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
    429 	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
    430 	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
    431 	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
    432 	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
    433 	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
    434 	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
    435 	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
    436 	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
    437 	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
    438 	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
    439 	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
    440 	gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
    441 	gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
    442 
    443 	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
    444 }
    445 
    446 static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
    447 {
    448 	enum dc_lut_mode mode;
    449 	uint32_t state_mode;
    450 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    451 
    452 	REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    453 					CM_BLNDGAM_CONFIG_STATUS, &state_mode);
    454 
    455 		switch (state_mode) {
    456 		case 0:
    457 			mode = LUT_BYPASS;
    458 			break;
    459 		case 1:
    460 			mode = LUT_RAM_A;
    461 			break;
    462 		case 2:
    463 			mode = LUT_RAM_B;
    464 			break;
    465 		default:
    466 			mode = LUT_BYPASS;
    467 			break;
    468 		}
    469 		return mode;
    470 }
    471 
    472 bool dpp20_program_blnd_lut(
    473 	struct dpp *dpp_base, const struct pwl_params *params)
    474 {
    475 	enum dc_lut_mode current_mode;
    476 	enum dc_lut_mode next_mode;
    477 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    478 
    479 	if (params == NULL) {
    480 		REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
    481 		return false;
    482 	}
    483 	current_mode = dpp20_get_blndgam_current(dpp_base);
    484 	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
    485 		next_mode = LUT_RAM_B;
    486 	else
    487 		next_mode = LUT_RAM_A;
    488 
    489 	dpp20_power_on_blnd_lut(dpp_base, true);
    490 	dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A ? true:false);
    491 
    492 	if (next_mode == LUT_RAM_A)
    493 		dpp20_program_blnd_luta_settings(dpp_base, params);
    494 	else
    495 		dpp20_program_blnd_lutb_settings(dpp_base, params);
    496 
    497 	dpp20_program_blnd_pwl(
    498 			dpp_base, params->rgb_resulted, params->hw_points_num);
    499 
    500 	REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
    501 			next_mode == LUT_RAM_A ? 1:2);
    502 
    503 	return true;
    504 }
    505 
    506 
    507 static void dpp20_program_shaper_lut(
    508 		struct dpp *dpp_base,
    509 		const struct pwl_result_data *rgb,
    510 		uint32_t num)
    511 {
    512 	uint32_t i, red, green, blue;
    513 	uint32_t  red_delta, green_delta, blue_delta;
    514 	uint32_t  red_value, green_value, blue_value;
    515 
    516 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    517 
    518 	for (i = 0 ; i < num; i++) {
    519 
    520 		red   = rgb[i].red_reg;
    521 		green = rgb[i].green_reg;
    522 		blue  = rgb[i].blue_reg;
    523 
    524 		red_delta   = rgb[i].delta_red_reg;
    525 		green_delta = rgb[i].delta_green_reg;
    526 		blue_delta  = rgb[i].delta_blue_reg;
    527 
    528 		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
    529 		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
    530 		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
    531 
    532 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
    533 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
    534 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
    535 	}
    536 
    537 }
    538 
    539 static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
    540 {
    541 	enum dc_lut_mode mode;
    542 	uint32_t state_mode;
    543 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    544 
    545 	REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK,
    546 			CM_SHAPER_CONFIG_STATUS, &state_mode);
    547 
    548 		switch (state_mode) {
    549 		case 0:
    550 			mode = LUT_BYPASS;
    551 			break;
    552 		case 1:
    553 			mode = LUT_RAM_A;
    554 			break;
    555 		case 2:
    556 			mode = LUT_RAM_B;
    557 			break;
    558 		default:
    559 			mode = LUT_BYPASS;
    560 			break;
    561 		}
    562 		return mode;
    563 }
    564 
    565 static void dpp20_configure_shaper_lut(
    566 		struct dpp *dpp_base,
    567 		bool is_ram_a)
    568 {
    569 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    570 
    571 	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
    572 			CM_SHAPER_LUT_WRITE_EN_MASK, 7);
    573 	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
    574 			CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
    575 	REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
    576 }
    577 
    578 /*program shaper RAM A*/
    579 
    580 static void dpp20_program_shaper_luta_settings(
    581 		struct dpp *dpp_base,
    582 		const struct pwl_params *params)
    583 {
    584 	const struct gamma_curve *curve;
    585 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    586 
    587 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
    588 		CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
    589 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
    590 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
    591 		CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
    592 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
    593 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
    594 		CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
    595 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
    596 
    597 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
    598 		CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
    599 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
    600 
    601 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
    602 		CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
    603 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
    604 
    605 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
    606 		CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
    607 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
    608 
    609 	curve = params->arr_curve_points;
    610 	REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
    611 		CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
    612 		CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
    613 		CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
    614 		CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
    615 
    616 	curve += 2;
    617 	REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
    618 		CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
    619 		CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
    620 		CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
    621 		CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
    622 
    623 	curve += 2;
    624 	REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
    625 		CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
    626 		CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
    627 		CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
    628 		CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
    629 
    630 	curve += 2;
    631 	REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
    632 		CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
    633 		CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
    634 		CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
    635 		CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
    636 
    637 	curve += 2;
    638 	REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
    639 		CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
    640 		CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
    641 		CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
    642 		CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
    643 
    644 	curve += 2;
    645 	REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
    646 		CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
    647 		CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
    648 		CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
    649 		CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
    650 
    651 	curve += 2;
    652 	REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
    653 		CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
    654 		CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
    655 		CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
    656 		CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
    657 
    658 	curve += 2;
    659 	REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
    660 		CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
    661 		CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
    662 		CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
    663 		CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
    664 
    665 	curve += 2;
    666 	REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
    667 		CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
    668 		CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
    669 		CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
    670 		CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
    671 
    672 	curve += 2;
    673 	REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
    674 		CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
    675 		CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
    676 		CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
    677 		CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
    678 
    679 	curve += 2;
    680 	REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
    681 		CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
    682 		CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
    683 		CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
    684 		CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
    685 
    686 	curve += 2;
    687 	REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
    688 		CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
    689 		CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
    690 		CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
    691 		CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
    692 
    693 	curve += 2;
    694 	REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
    695 		CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
    696 		CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
    697 		CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
    698 		CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
    699 
    700 	curve += 2;
    701 	REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
    702 		CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
    703 		CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
    704 		CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
    705 		CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
    706 
    707 	curve += 2;
    708 	REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
    709 		CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
    710 		CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
    711 		CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
    712 		CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
    713 
    714 	curve += 2;
    715 	REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
    716 		CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
    717 		CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
    718 		CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
    719 		CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
    720 
    721 	curve += 2;
    722 	REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
    723 		CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
    724 		CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
    725 		CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
    726 		CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
    727 }
    728 
    729 /*program shaper RAM B*/
    730 static void dpp20_program_shaper_lutb_settings(
    731 		struct dpp *dpp_base,
    732 		const struct pwl_params *params)
    733 {
    734 	const struct gamma_curve *curve;
    735 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    736 
    737 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
    738 		CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
    739 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
    740 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
    741 		CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
    742 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
    743 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
    744 		CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
    745 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
    746 
    747 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
    748 		CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
    749 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
    750 
    751 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
    752 		CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
    753 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
    754 
    755 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
    756 		CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
    757 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
    758 
    759 	curve = params->arr_curve_points;
    760 	REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
    761 		CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
    762 		CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
    763 		CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
    764 		CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
    765 
    766 	curve += 2;
    767 	REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
    768 		CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
    769 		CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
    770 		CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
    771 		CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
    772 
    773 	curve += 2;
    774 	REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
    775 		CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
    776 		CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
    777 		CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
    778 		CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
    779 
    780 	curve += 2;
    781 	REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
    782 		CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
    783 		CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
    784 		CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
    785 		CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
    786 
    787 	curve += 2;
    788 	REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
    789 		CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
    790 		CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
    791 		CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
    792 		CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
    793 
    794 	curve += 2;
    795 	REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
    796 		CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
    797 		CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
    798 		CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
    799 		CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
    800 
    801 	curve += 2;
    802 	REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
    803 		CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
    804 		CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
    805 		CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
    806 		CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
    807 
    808 	curve += 2;
    809 	REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
    810 		CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
    811 		CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
    812 		CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
    813 		CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
    814 
    815 	curve += 2;
    816 	REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
    817 		CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
    818 		CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
    819 		CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
    820 		CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
    821 
    822 	curve += 2;
    823 	REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
    824 		CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
    825 		CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
    826 		CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
    827 		CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
    828 
    829 	curve += 2;
    830 	REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
    831 		CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
    832 		CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
    833 		CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
    834 		CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
    835 
    836 	curve += 2;
    837 	REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
    838 		CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
    839 		CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
    840 		CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
    841 		CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
    842 
    843 	curve += 2;
    844 	REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
    845 		CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
    846 		CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
    847 		CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
    848 		CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
    849 
    850 	curve += 2;
    851 	REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
    852 		CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
    853 		CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
    854 		CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
    855 		CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
    856 
    857 	curve += 2;
    858 	REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
    859 		CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
    860 		CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
    861 		CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
    862 		CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
    863 
    864 	curve += 2;
    865 	REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
    866 		CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
    867 		CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
    868 		CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
    869 		CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
    870 
    871 	curve += 2;
    872 	REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
    873 		CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
    874 		CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
    875 		CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
    876 		CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
    877 
    878 }
    879 
    880 
    881 bool dpp20_program_shaper(
    882 		struct dpp *dpp_base,
    883 		const struct pwl_params *params)
    884 {
    885 	enum dc_lut_mode current_mode;
    886 	enum dc_lut_mode next_mode;
    887 
    888 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    889 
    890 	if (params == NULL) {
    891 		REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
    892 		return false;
    893 	}
    894 	current_mode = dpp20_get_shaper_current(dpp_base);
    895 
    896 	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
    897 		next_mode = LUT_RAM_B;
    898 	else
    899 		next_mode = LUT_RAM_A;
    900 
    901 	dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A ? true:false);
    902 
    903 	if (next_mode == LUT_RAM_A)
    904 		dpp20_program_shaper_luta_settings(dpp_base, params);
    905 	else
    906 		dpp20_program_shaper_lutb_settings(dpp_base, params);
    907 
    908 	dpp20_program_shaper_lut(
    909 			dpp_base, params->rgb_resulted, params->hw_points_num);
    910 
    911 	REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
    912 
    913 	return true;
    914 
    915 }
    916 
    917 static enum dc_lut_mode get3dlut_config(
    918 			struct dpp *dpp_base,
    919 			bool *is_17x17x17,
    920 			bool *is_12bits_color_channel)
    921 {
    922 	uint32_t i_mode, i_enable_10bits, lut_size;
    923 	enum dc_lut_mode mode;
    924 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    925 
    926 	REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
    927 			CM_3DLUT_CONFIG_STATUS, &i_mode,
    928 			CM_3DLUT_30BIT_EN, &i_enable_10bits);
    929 
    930 	switch (i_mode) {
    931 	case 0:
    932 		mode = LUT_BYPASS;
    933 		break;
    934 	case 1:
    935 		mode = LUT_RAM_A;
    936 		break;
    937 	case 2:
    938 		mode = LUT_RAM_B;
    939 		break;
    940 	default:
    941 		mode = LUT_BYPASS;
    942 		break;
    943 	}
    944 	if (i_enable_10bits > 0)
    945 		*is_12bits_color_channel = false;
    946 	else
    947 		*is_12bits_color_channel = true;
    948 
    949 	REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
    950 
    951 	if (lut_size == 0)
    952 		*is_17x17x17 = true;
    953 	else
    954 		*is_17x17x17 = false;
    955 
    956 	return mode;
    957 }
    958 /*
    959  * select ramA or ramB, or bypass
    960  * select color channel size 10 or 12 bits
    961  * select 3dlut size 17x17x17 or 9x9x9
    962  */
    963 static void dpp20_set_3dlut_mode(
    964 		struct dpp *dpp_base,
    965 		enum dc_lut_mode mode,
    966 		bool is_color_channel_12bits,
    967 		bool is_lut_size17x17x17)
    968 {
    969 	uint32_t lut_mode;
    970 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    971 
    972 	if (mode == LUT_BYPASS)
    973 		lut_mode = 0;
    974 	else if (mode == LUT_RAM_A)
    975 		lut_mode = 1;
    976 	else
    977 		lut_mode = 2;
    978 
    979 	REG_UPDATE_2(CM_3DLUT_MODE,
    980 			CM_3DLUT_MODE, lut_mode,
    981 			CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
    982 }
    983 
    984 static void dpp20_select_3dlut_ram(
    985 		struct dpp *dpp_base,
    986 		enum dc_lut_mode mode,
    987 		bool is_color_channel_12bits)
    988 {
    989 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    990 
    991 	REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
    992 			CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
    993 			CM_3DLUT_30BIT_EN,
    994 			is_color_channel_12bits == true ? 0:1);
    995 }
    996 
    997 
    998 
    999 static void dpp20_set3dlut_ram12(
   1000 		struct dpp *dpp_base,
   1001 		const struct dc_rgb *lut,
   1002 		uint32_t entries)
   1003 {
   1004 	uint32_t i, red, green, blue, red1, green1, blue1;
   1005 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1006 
   1007 	for (i = 0 ; i < entries; i += 2) {
   1008 		red   = lut[i].red<<4;
   1009 		green = lut[i].green<<4;
   1010 		blue  = lut[i].blue<<4;
   1011 		red1   = lut[i+1].red<<4;
   1012 		green1 = lut[i+1].green<<4;
   1013 		blue1  = lut[i+1].blue<<4;
   1014 
   1015 		REG_SET_2(CM_3DLUT_DATA, 0,
   1016 				CM_3DLUT_DATA0, red,
   1017 				CM_3DLUT_DATA1, red1);
   1018 
   1019 		REG_SET_2(CM_3DLUT_DATA, 0,
   1020 				CM_3DLUT_DATA0, green,
   1021 				CM_3DLUT_DATA1, green1);
   1022 
   1023 		REG_SET_2(CM_3DLUT_DATA, 0,
   1024 				CM_3DLUT_DATA0, blue,
   1025 				CM_3DLUT_DATA1, blue1);
   1026 
   1027 	}
   1028 }
   1029 
   1030 /*
   1031  * load selected lut with 10 bits color channels
   1032  */
   1033 static void dpp20_set3dlut_ram10(
   1034 		struct dpp *dpp_base,
   1035 		const struct dc_rgb *lut,
   1036 		uint32_t entries)
   1037 {
   1038 	uint32_t i, red, green, blue, value;
   1039 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1040 
   1041 	for (i = 0; i < entries; i++) {
   1042 		red   = lut[i].red;
   1043 		green = lut[i].green;
   1044 		blue  = lut[i].blue;
   1045 
   1046 		value = (red<<20) | (green<<10) | blue;
   1047 
   1048 		REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
   1049 	}
   1050 
   1051 }
   1052 
   1053 
   1054 static void dpp20_select_3dlut_ram_mask(
   1055 		struct dpp *dpp_base,
   1056 		uint32_t ram_selection_mask)
   1057 {
   1058 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1059 
   1060 	REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
   1061 			ram_selection_mask);
   1062 	REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
   1063 }
   1064 
   1065 bool dpp20_program_3dlut(
   1066 		struct dpp *dpp_base,
   1067 		struct tetrahedral_params *params)
   1068 {
   1069 	enum dc_lut_mode mode;
   1070 	bool is_17x17x17;
   1071 	bool is_12bits_color_channel;
   1072 	struct dc_rgb *lut0;
   1073 	struct dc_rgb *lut1;
   1074 	struct dc_rgb *lut2;
   1075 	struct dc_rgb *lut3;
   1076 	int lut_size0;
   1077 	int lut_size;
   1078 
   1079 	if (params == NULL) {
   1080 		dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
   1081 		return false;
   1082 	}
   1083 	mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
   1084 
   1085 	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
   1086 		mode = LUT_RAM_A;
   1087 	else
   1088 		mode = LUT_RAM_B;
   1089 
   1090 	is_17x17x17 = !params->use_tetrahedral_9;
   1091 	is_12bits_color_channel = params->use_12bits;
   1092 	if (is_17x17x17) {
   1093 		lut0 = params->tetrahedral_17.lut0;
   1094 		lut1 = params->tetrahedral_17.lut1;
   1095 		lut2 = params->tetrahedral_17.lut2;
   1096 		lut3 = params->tetrahedral_17.lut3;
   1097 		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
   1098 					sizeof(params->tetrahedral_17.lut0[0]);
   1099 		lut_size  = sizeof(params->tetrahedral_17.lut1)/
   1100 					sizeof(params->tetrahedral_17.lut1[0]);
   1101 	} else {
   1102 		lut0 = params->tetrahedral_9.lut0;
   1103 		lut1 = params->tetrahedral_9.lut1;
   1104 		lut2 = params->tetrahedral_9.lut2;
   1105 		lut3 = params->tetrahedral_9.lut3;
   1106 		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
   1107 				sizeof(params->tetrahedral_9.lut0[0]);
   1108 		lut_size  = sizeof(params->tetrahedral_9.lut1)/
   1109 				sizeof(params->tetrahedral_9.lut1[0]);
   1110 		}
   1111 
   1112 	dpp20_select_3dlut_ram(dpp_base, mode,
   1113 				is_12bits_color_channel);
   1114 	dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
   1115 	if (is_12bits_color_channel)
   1116 		dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
   1117 	else
   1118 		dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
   1119 
   1120 	dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
   1121 	if (is_12bits_color_channel)
   1122 		dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
   1123 	else
   1124 		dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
   1125 
   1126 	dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
   1127 	if (is_12bits_color_channel)
   1128 		dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
   1129 	else
   1130 		dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
   1131 
   1132 	dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
   1133 	if (is_12bits_color_channel)
   1134 		dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
   1135 	else
   1136 		dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
   1137 
   1138 
   1139 	dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
   1140 					is_17x17x17);
   1141 
   1142 	return true;
   1143 }
   1144 
   1145 void dpp2_set_hdr_multiplier(
   1146 		struct dpp *dpp_base,
   1147 		uint32_t multiplier)
   1148 {
   1149 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1150 
   1151 	REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
   1152 }
   1153