Linux Audio

Check our new training course

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