Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
   1/*
   2 * Copyright 2020 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#include "core_types.h"
  28#include "reg_helper.h"
  29#include "dcn30_dpp.h"
  30#include "basics/conversion.h"
  31#include "dcn30_cm_common.h"
  32
  33#define REG(reg)\
  34	dpp->tf_regs->reg
  35
  36#define CTX \
  37	dpp->base.ctx
  38
  39#undef FN
  40#define FN(reg_name, field_name) \
  41	dpp->tf_shift->field_name, dpp->tf_mask->field_name
  42
  43
  44void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s)
  45{
  46	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
  47	uint32_t gamcor_lut_mode, rgam_lut_mode;
  48
  49	REG_GET(DPP_CONTROL,
  50		DPP_CLOCK_ENABLE, &s->is_enabled);
  51
  52	// Pre-degamma (ROM)
  53	REG_GET_2(PRE_DEGAM,
  54		  PRE_DEGAM_MODE, &s->pre_dgam_mode,
  55		  PRE_DEGAM_SELECT, &s->pre_dgam_select);
  56
  57	// Gamma Correction (RAM)
  58	REG_GET(CM_GAMCOR_CONTROL,
  59		CM_GAMCOR_MODE_CURRENT, &s->gamcor_mode);
  60	if (s->gamcor_mode) {
  61		REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, &gamcor_lut_mode);
  62		if (!gamcor_lut_mode)
  63			s->gamcor_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B
  64	}
  65
  66	// Shaper LUT (RAM), 3D LUT (mode, bit-depth, size)
  67	REG_GET(CM_SHAPER_CONTROL,
  68		CM_SHAPER_LUT_MODE, &s->shaper_lut_mode);
  69	REG_GET(CM_3DLUT_MODE,
  70		CM_3DLUT_MODE_CURRENT, &s->lut3d_mode);
  71	REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
  72		CM_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
  73	REG_GET(CM_3DLUT_MODE,
  74		CM_3DLUT_SIZE, &s->lut3d_size);
  75
  76	// Blend/Out Gamma (RAM)
  77	REG_GET(CM_BLNDGAM_CONTROL,
  78		CM_BLNDGAM_MODE_CURRENT, &s->rgam_lut_mode);
  79	if (s->rgam_lut_mode){
  80		REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &rgam_lut_mode);
  81		if (!rgam_lut_mode)
  82			s->rgam_lut_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B
  83	}
  84}
  85
  86/*program post scaler scs block in dpp CM*/
  87void dpp3_program_post_csc(
  88		struct dpp *dpp_base,
  89		enum dc_color_space color_space,
  90		enum dcn10_input_csc_select input_select,
  91		const struct out_csc_color_matrix *tbl_entry)
  92{
  93	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
  94	int i;
  95	int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
  96	const uint16_t *regval = NULL;
  97	uint32_t cur_select = 0;
  98	enum dcn10_input_csc_select select;
  99	struct color_matrices_reg gam_regs;
 100
 101	if (input_select == INPUT_CSC_SELECT_BYPASS) {
 102		REG_SET(CM_POST_CSC_CONTROL, 0, CM_POST_CSC_MODE, 0);
 103		return;
 104	}
 105
 106	if (tbl_entry == NULL) {
 107		for (i = 0; i < arr_size; i++)
 108			if (dpp_input_csc_matrix[i].color_space == color_space) {
 109				regval = dpp_input_csc_matrix[i].regval;
 110				break;
 111			}
 112
 113		if (regval == NULL) {
 114			BREAK_TO_DEBUGGER();
 115			return;
 116		}
 117	} else {
 118		regval = tbl_entry->regval;
 119	}
 120
 121	/* determine which CSC matrix (icsc or coma) we are using
 122	 * currently.  select the alternate set to double buffer
 123	 * the CSC update so CSC is updated on frame boundary
 124	 */
 125	REG_GET(CM_POST_CSC_CONTROL,
 126			CM_POST_CSC_MODE_CURRENT, &cur_select);
 127
 128	if (cur_select != INPUT_CSC_SELECT_ICSC)
 129		select = INPUT_CSC_SELECT_ICSC;
 130	else
 131		select = INPUT_CSC_SELECT_COMA;
 132
 133	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_POST_CSC_C11;
 134	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_POST_CSC_C11;
 135	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_POST_CSC_C12;
 136	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_POST_CSC_C12;
 137
 138	if (select == INPUT_CSC_SELECT_ICSC) {
 139
 140		gam_regs.csc_c11_c12 = REG(CM_POST_CSC_C11_C12);
 141		gam_regs.csc_c33_c34 = REG(CM_POST_CSC_C33_C34);
 142
 143	} else {
 144
 145		gam_regs.csc_c11_c12 = REG(CM_POST_CSC_B_C11_C12);
 146		gam_regs.csc_c33_c34 = REG(CM_POST_CSC_B_C33_C34);
 147
 148	}
 149
 150	cm_helper_program_color_matrices(
 151			dpp->base.ctx,
 152			regval,
 153			&gam_regs);
 154
 155	REG_SET(CM_POST_CSC_CONTROL, 0,
 156			CM_POST_CSC_MODE, select);
 157}
 158
 159
 160/*CNVC degam unit has read only LUTs*/
 161void dpp3_set_pre_degam(struct dpp *dpp_base, enum dc_transfer_func_predefined tr)
 162{
 163	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 164	int pre_degam_en = 1;
 165	int degamma_lut_selection = 0;
 166
 167	switch (tr) {
 168	case TRANSFER_FUNCTION_LINEAR:
 169	case TRANSFER_FUNCTION_UNITY:
 170		pre_degam_en = 0; //bypass
 171		break;
 172	case TRANSFER_FUNCTION_SRGB:
 173		degamma_lut_selection = 0;
 174		break;
 175	case TRANSFER_FUNCTION_BT709:
 176		degamma_lut_selection = 4;
 177		break;
 178	case TRANSFER_FUNCTION_PQ:
 179		degamma_lut_selection = 5;
 180		break;
 181	case TRANSFER_FUNCTION_HLG:
 182		degamma_lut_selection = 6;
 183		break;
 184	case TRANSFER_FUNCTION_GAMMA22:
 185		degamma_lut_selection = 1;
 186		break;
 187	case TRANSFER_FUNCTION_GAMMA24:
 188		degamma_lut_selection = 2;
 189		break;
 190	case TRANSFER_FUNCTION_GAMMA26:
 191		degamma_lut_selection = 3;
 192		break;
 193	default:
 194		pre_degam_en = 0;
 195		break;
 196	}
 197
 198	REG_SET_2(PRE_DEGAM, 0,
 199			PRE_DEGAM_MODE, pre_degam_en,
 200			PRE_DEGAM_SELECT, degamma_lut_selection);
 201}
 202
 203void dpp3_cnv_setup (
 204		struct dpp *dpp_base,
 205		enum surface_pixel_format format,
 206		enum expansion_mode mode,
 207		struct dc_csc_transform input_csc_color_matrix,
 208		enum dc_color_space input_color_space,
 209		struct cnv_alpha_2bit_lut *alpha_2bit_lut)
 210{
 211	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 212	uint32_t pixel_format = 0;
 213	uint32_t alpha_en = 1;
 214	enum dc_color_space color_space = COLOR_SPACE_SRGB;
 215	enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
 216	bool force_disable_cursor = false;
 217	uint32_t is_2bit = 0;
 218	uint32_t alpha_plane_enable = 0;
 219	uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
 220	uint32_t realpha_en = 0, realpha_ablnd_en = 0;
 221	uint32_t program_prealpha_dealpha = 0;
 222	struct out_csc_color_matrix tbl_entry;
 223	int i;
 224
 225	REG_SET_2(FORMAT_CONTROL, 0,
 226		CNVC_BYPASS, 0,
 227		FORMAT_EXPANSION_MODE, mode);
 228
 229	REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0);
 230	REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0);
 231	REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0);
 232	REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0);
 233
 234	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0);
 235	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1);
 236	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2);
 237
 238	switch (format) {
 239	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
 240		pixel_format = 1;
 241		break;
 242	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
 243		pixel_format = 3;
 244		alpha_en = 0;
 245		break;
 246	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
 247	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
 248		pixel_format = 8;
 249		break;
 250	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
 251	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
 252		pixel_format = 10;
 253		is_2bit = 1;
 254		break;
 255	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
 256		force_disable_cursor = false;
 257		pixel_format = 65;
 258		color_space = COLOR_SPACE_YCBCR709;
 259		select = INPUT_CSC_SELECT_ICSC;
 260		break;
 261	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
 262		force_disable_cursor = true;
 263		pixel_format = 64;
 264		color_space = COLOR_SPACE_YCBCR709;
 265		select = INPUT_CSC_SELECT_ICSC;
 266		break;
 267	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
 268		force_disable_cursor = true;
 269		pixel_format = 67;
 270		color_space = COLOR_SPACE_YCBCR709;
 271		select = INPUT_CSC_SELECT_ICSC;
 272		break;
 273	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
 274		force_disable_cursor = true;
 275		pixel_format = 66;
 276		color_space = COLOR_SPACE_YCBCR709;
 277		select = INPUT_CSC_SELECT_ICSC;
 278		break;
 279	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
 280	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
 281		pixel_format = 26; /* ARGB16161616_UNORM */
 282		break;
 283	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
 284		pixel_format = 24;
 285		break;
 286	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
 287		pixel_format = 25;
 288		break;
 289	case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
 290		pixel_format = 12;
 291		color_space = COLOR_SPACE_YCBCR709;
 292		select = INPUT_CSC_SELECT_ICSC;
 293		break;
 294	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
 295		pixel_format = 112;
 296		break;
 297	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
 298		pixel_format = 113;
 299		break;
 300	case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
 301		pixel_format = 114;
 302		color_space = COLOR_SPACE_YCBCR709;
 303		select = INPUT_CSC_SELECT_ICSC;
 304		is_2bit = 1;
 305		break;
 306	case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
 307		pixel_format = 115;
 308		color_space = COLOR_SPACE_YCBCR709;
 309		select = INPUT_CSC_SELECT_ICSC;
 310		is_2bit = 1;
 311		break;
 312	case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
 313		pixel_format = 116;
 314		alpha_plane_enable = 0;
 315		break;
 316	case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
 317		pixel_format = 116;
 318		alpha_plane_enable = 1;
 319		break;
 320	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
 321		pixel_format = 118;
 322		break;
 323	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
 324		pixel_format = 119;
 325		break;
 326	default:
 327		break;
 328	}
 329
 330	/* Set default color space based on format if none is given. */
 331	color_space = input_color_space ? input_color_space : color_space;
 332
 333	if (is_2bit == 1 && alpha_2bit_lut != NULL) {
 334		REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0);
 335		REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
 336		REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2);
 337		REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
 338	}
 339
 340	REG_SET_2(CNVC_SURFACE_PIXEL_FORMAT, 0,
 341			CNVC_SURFACE_PIXEL_FORMAT, pixel_format,
 342			CNVC_ALPHA_PLANE_ENABLE, alpha_plane_enable);
 343	REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
 344
 345	if (program_prealpha_dealpha) {
 346		dealpha_en = 1;
 347		realpha_en = 1;
 348	}
 349	REG_SET_2(PRE_DEALPHA, 0,
 350			PRE_DEALPHA_EN, dealpha_en,
 351			PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
 352	REG_SET_2(PRE_REALPHA, 0,
 353			PRE_REALPHA_EN, realpha_en,
 354			PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
 355
 356	/* If input adjustment exists, program the ICSC with those values. */
 357	if (input_csc_color_matrix.enable_adjustment == true) {
 358		for (i = 0; i < 12; i++)
 359			tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
 360
 361		tbl_entry.color_space = input_color_space;
 362
 363		if (color_space >= COLOR_SPACE_YCBCR601)
 364			select = INPUT_CSC_SELECT_ICSC;
 365		else
 366			select = INPUT_CSC_SELECT_BYPASS;
 367
 368		dpp3_program_post_csc(dpp_base, color_space, select,
 369				      &tbl_entry);
 370	} else {
 371		dpp3_program_post_csc(dpp_base, color_space, select, NULL);
 372	}
 373
 374	if (force_disable_cursor) {
 375		REG_UPDATE(CURSOR_CONTROL,
 376				CURSOR_ENABLE, 0);
 377		REG_UPDATE(CURSOR0_CONTROL,
 378				CUR0_ENABLE, 0);
 379	}
 380}
 381
 382#define IDENTITY_RATIO(ratio) (dc_fixpt_u3d19(ratio) == (1 << 19))
 383
 384void dpp3_set_cursor_attributes(
 385		struct dpp *dpp_base,
 386		struct dc_cursor_attributes *cursor_attributes)
 387{
 388	enum dc_cursor_color_format color_format = cursor_attributes->color_format;
 389	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 390	int cur_rom_en = 0;
 391
 392	if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
 393		color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
 394		if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) {
 395			cur_rom_en = 1;
 396		}
 397	}
 398
 399	REG_UPDATE_3(CURSOR0_CONTROL,
 400			CUR0_MODE, color_format,
 401			CUR0_EXPANSION_MODE, 0,
 402			CUR0_ROM_EN, cur_rom_en);
 403
 404	if (color_format == CURSOR_MODE_MONO) {
 405		/* todo: clarify what to program these to */
 406		REG_UPDATE(CURSOR0_COLOR0,
 407				CUR0_COLOR0, 0x00000000);
 408		REG_UPDATE(CURSOR0_COLOR1,
 409				CUR0_COLOR1, 0xFFFFFFFF);
 410	}
 411
 412	dpp_base->att.cur0_ctl.bits.expansion_mode = 0;
 413	dpp_base->att.cur0_ctl.bits.cur0_rom_en = cur_rom_en;
 414	dpp_base->att.cur0_ctl.bits.mode = color_format;
 415}
 416
 417
 418bool dpp3_get_optimal_number_of_taps(
 419		struct dpp *dpp,
 420		struct scaler_data *scl_data,
 421		const struct scaling_taps *in_taps)
 422{
 423	int num_part_y, num_part_c;
 424	int max_taps_y, max_taps_c;
 425	int min_taps_y, min_taps_c;
 426	enum lb_memory_config lb_config;
 427
 428	if (scl_data->viewport.width > scl_data->h_active &&
 429		dpp->ctx->dc->debug.max_downscale_src_width != 0 &&
 430		scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width)
 431		return false;
 432
 433	/*
 434	 * Set default taps if none are provided
 435	 * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling
 436	 * taps = 4 for upscaling
 437	 */
 438	if (in_taps->h_taps == 0) {
 439		if (dc_fixpt_ceil(scl_data->ratios.horz) > 1)
 440			scl_data->taps.h_taps = min(2 * dc_fixpt_ceil(scl_data->ratios.horz), 8);
 441		else
 442			scl_data->taps.h_taps = 4;
 443	} else
 444		scl_data->taps.h_taps = in_taps->h_taps;
 445	if (in_taps->v_taps == 0) {
 446		if (dc_fixpt_ceil(scl_data->ratios.vert) > 1)
 447			scl_data->taps.v_taps = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert, 2)), 8);
 448		else
 449			scl_data->taps.v_taps = 4;
 450	} else
 451		scl_data->taps.v_taps = in_taps->v_taps;
 452	if (in_taps->v_taps_c == 0) {
 453		if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 1)
 454			scl_data->taps.v_taps_c = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert_c, 2)), 8);
 455		else
 456			scl_data->taps.v_taps_c = 4;
 457	} else
 458		scl_data->taps.v_taps_c = in_taps->v_taps_c;
 459	if (in_taps->h_taps_c == 0) {
 460		if (dc_fixpt_ceil(scl_data->ratios.horz_c) > 1)
 461			scl_data->taps.h_taps_c = min(2 * dc_fixpt_ceil(scl_data->ratios.horz_c), 8);
 462		else
 463			scl_data->taps.h_taps_c = 4;
 464	} else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
 465		/* Only 1 and even h_taps_c are supported by hw */
 466		scl_data->taps.h_taps_c = in_taps->h_taps_c - 1;
 467	else
 468		scl_data->taps.h_taps_c = in_taps->h_taps_c;
 469
 470	/*Ensure we can support the requested number of vtaps*/
 471	min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert);
 472	min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
 473
 474	/* Use LB_MEMORY_CONFIG_3 for 4:2:0 */
 475	if ((scl_data->format == PIXEL_FORMAT_420BPP8) || (scl_data->format == PIXEL_FORMAT_420BPP10))
 476		lb_config = LB_MEMORY_CONFIG_3;
 477	else
 478		lb_config = LB_MEMORY_CONFIG_0;
 479
 480	dpp->caps->dscl_calc_lb_num_partitions(
 481			scl_data, lb_config, &num_part_y, &num_part_c);
 482
 483	/* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */
 484	if (dc_fixpt_ceil(scl_data->ratios.vert) > 2)
 485		max_taps_y = num_part_y - (dc_fixpt_ceil(scl_data->ratios.vert) - 2);
 486	else
 487		max_taps_y = num_part_y;
 488
 489	if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 2)
 490		max_taps_c = num_part_c - (dc_fixpt_ceil(scl_data->ratios.vert_c) - 2);
 491	else
 492		max_taps_c = num_part_c;
 493
 494	if (max_taps_y < min_taps_y)
 495		return false;
 496	else if (max_taps_c < min_taps_c)
 497		return false;
 498
 499	if (scl_data->taps.v_taps > max_taps_y)
 500		scl_data->taps.v_taps = max_taps_y;
 501
 502	if (scl_data->taps.v_taps_c > max_taps_c)
 503		scl_data->taps.v_taps_c = max_taps_c;
 504
 505	if (!dpp->ctx->dc->debug.always_scale) {
 506		if (IDENTITY_RATIO(scl_data->ratios.horz))
 507			scl_data->taps.h_taps = 1;
 508		if (IDENTITY_RATIO(scl_data->ratios.vert))
 509			scl_data->taps.v_taps = 1;
 510		if (IDENTITY_RATIO(scl_data->ratios.horz_c))
 511			scl_data->taps.h_taps_c = 1;
 512		if (IDENTITY_RATIO(scl_data->ratios.vert_c))
 513			scl_data->taps.v_taps_c = 1;
 514	}
 515
 516	return true;
 517}
 518
 519static void dpp3_deferred_update(struct dpp *dpp_base)
 520{
 521	int bypass_state;
 522	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 523
 524	if (dpp_base->deferred_reg_writes.bits.disable_dscl) {
 525		REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
 526		dpp_base->deferred_reg_writes.bits.disable_dscl = false;
 527	}
 528
 529	if (dpp_base->deferred_reg_writes.bits.disable_gamcor) {
 530		REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state);
 531		if (bypass_state == 0) {	// only program if bypass was latched
 532			REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3);
 533		} else
 534			ASSERT(0); // LUT select was updated again before vupdate
 535		dpp_base->deferred_reg_writes.bits.disable_gamcor = false;
 536	}
 537
 538	if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
 539		REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
 540		if (bypass_state == 0) {	// only program if bypass was latched
 541			REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3);
 542		} else
 543			ASSERT(0); // LUT select was updated again before vupdate
 544		dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false;
 545	}
 546
 547	if (dpp_base->deferred_reg_writes.bits.disable_3dlut) {
 548		REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state);
 549		if (bypass_state == 0) {	// only program if bypass was latched
 550			REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3);
 551		} else
 552			ASSERT(0); // LUT select was updated again before vupdate
 553		dpp_base->deferred_reg_writes.bits.disable_3dlut = false;
 554	}
 555
 556	if (dpp_base->deferred_reg_writes.bits.disable_shaper) {
 557		REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state);
 558		if (bypass_state == 0) {	// only program if bypass was latched
 559			REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3);
 560		} else
 561			ASSERT(0); // LUT select was updated again before vupdate
 562		dpp_base->deferred_reg_writes.bits.disable_shaper = false;
 563	}
 564}
 565
 566static void dpp3_power_on_blnd_lut(
 567	struct dpp *dpp_base,
 568	bool power_on)
 569{
 570	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 571
 572	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
 573		if (power_on) {
 574			REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);
 575			REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
 576		} else {
 577			dpp_base->ctx->dc->optimized_required = true;
 578			dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
 579		}
 580	} else {
 581		REG_SET(CM_MEM_PWR_CTRL, 0,
 582				BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
 583	}
 584}
 585
 586static void dpp3_power_on_hdr3dlut(
 587	struct dpp *dpp_base,
 588	bool power_on)
 589{
 590	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 591
 592	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
 593		if (power_on) {
 594			REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);
 595			REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
 596		} else {
 597			dpp_base->ctx->dc->optimized_required = true;
 598			dpp_base->deferred_reg_writes.bits.disable_3dlut = true;
 599		}
 600	}
 601}
 602
 603static void dpp3_power_on_shaper(
 604	struct dpp *dpp_base,
 605	bool power_on)
 606{
 607	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 608
 609	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
 610		if (power_on) {
 611			REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);
 612			REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
 613		} else {
 614			dpp_base->ctx->dc->optimized_required = true;
 615			dpp_base->deferred_reg_writes.bits.disable_shaper = true;
 616		}
 617	}
 618}
 619
 620static void dpp3_configure_blnd_lut(
 621		struct dpp *dpp_base,
 622		bool is_ram_a)
 623{
 624	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 625
 626	REG_UPDATE_2(CM_BLNDGAM_LUT_CONTROL,
 627			CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 7,
 628			CM_BLNDGAM_LUT_HOST_SEL, is_ram_a == true ? 0 : 1);
 629
 630	REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 631}
 632
 633static void dpp3_program_blnd_pwl(
 634		struct dpp *dpp_base,
 635		const struct pwl_result_data *rgb,
 636		uint32_t num)
 637{
 638	uint32_t i;
 639	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 640	uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
 641	uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
 642	uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
 643
 644	if (is_rgb_equal(rgb, num)) {
 645		for (i = 0 ; i < num; i++)
 646			REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
 647		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
 648	} else {
 649		REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 650		REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 4);
 651		for (i = 0 ; i < num; i++)
 652			REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
 653		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
 654
 655		REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 656		REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 2);
 657		for (i = 0 ; i < num; i++)
 658			REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
 659		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_green);
 660
 661		REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 662		REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 1);
 663		for (i = 0 ; i < num; i++)
 664			REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
 665		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_blue);
 666	}
 667}
 668
 669static void dcn3_dpp_cm_get_reg_field(
 670		struct dcn3_dpp *dpp,
 671		struct dcn3_xfer_func_reg *reg)
 672{
 673	reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 674	reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 675	reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 676	reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 677	reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 678	reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 679	reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 680	reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 681
 682	reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 683	reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 684	reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 685	reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 686	reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 687	reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 688	reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
 689	reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
 690	reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 691	reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 692	reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 693	reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 694}
 695
 696/*program blnd lut RAM A*/
 697static void dpp3_program_blnd_luta_settings(
 698		struct dpp *dpp_base,
 699		const struct pwl_params *params)
 700{
 701	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 702	struct dcn3_xfer_func_reg gam_regs;
 703
 704	dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
 705
 706	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
 707	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
 708	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
 709	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B);
 710	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G);
 711	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R);
 712	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
 713	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
 714	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
 715	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
 716	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
 717	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
 718	gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
 719	gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
 720
 721	cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
 722}
 723
 724/*program blnd lut RAM B*/
 725static void dpp3_program_blnd_lutb_settings(
 726		struct dpp *dpp_base,
 727		const struct pwl_params *params)
 728{
 729	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 730	struct dcn3_xfer_func_reg gam_regs;
 731
 732	dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
 733
 734	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
 735	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
 736	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
 737	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B);
 738	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G);
 739	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R);
 740	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
 741	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
 742	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
 743	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
 744	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
 745	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
 746	gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
 747	gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
 748
 749	cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
 750}
 751
 752static enum dc_lut_mode dpp3_get_blndgam_current(struct dpp *dpp_base)
 753{
 754	enum dc_lut_mode mode;
 755	uint32_t mode_current = 0;
 756	uint32_t in_use = 0;
 757
 758	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 759
 760	REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &mode_current);
 761	REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &in_use);
 762
 763	switch (mode_current) {
 764	case 0:
 765	case 1:
 766		mode = LUT_BYPASS;
 767		break;
 768
 769	case 2:
 770		if (in_use == 0)
 771			mode = LUT_RAM_A;
 772		else
 773			mode = LUT_RAM_B;
 774		break;
 775	default:
 776		mode = LUT_BYPASS;
 777		break;
 778	}
 779
 780	return mode;
 781}
 782
 783static bool dpp3_program_blnd_lut(struct dpp *dpp_base,
 784				  const struct pwl_params *params)
 785{
 786	enum dc_lut_mode current_mode;
 787	enum dc_lut_mode next_mode;
 788	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 789
 790	if (params == NULL) {
 791		REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_MODE, 0);
 792		if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
 793			dpp3_power_on_blnd_lut(dpp_base, false);
 794		return false;
 795	}
 796
 797	current_mode = dpp3_get_blndgam_current(dpp_base);
 798	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_B)
 799		next_mode = LUT_RAM_A;
 800	else
 801		next_mode = LUT_RAM_B;
 802
 803	dpp3_power_on_blnd_lut(dpp_base, true);
 804	dpp3_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
 805
 806	if (next_mode == LUT_RAM_A)
 807		dpp3_program_blnd_luta_settings(dpp_base, params);
 808	else
 809		dpp3_program_blnd_lutb_settings(dpp_base, params);
 810
 811	dpp3_program_blnd_pwl(
 812			dpp_base, params->rgb_resulted, params->hw_points_num);
 813
 814	REG_UPDATE_2(CM_BLNDGAM_CONTROL,
 815			CM_BLNDGAM_MODE, 2,
 816			CM_BLNDGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1);
 817
 818	return true;
 819}
 820
 821
 822static void dpp3_program_shaper_lut(
 823		struct dpp *dpp_base,
 824		const struct pwl_result_data *rgb,
 825		uint32_t num)
 826{
 827	uint32_t i, red, green, blue;
 828	uint32_t  red_delta, green_delta, blue_delta;
 829	uint32_t  red_value, green_value, blue_value;
 830
 831	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 832
 833	for (i = 0 ; i < num; i++) {
 834
 835		red   = rgb[i].red_reg;
 836		green = rgb[i].green_reg;
 837		blue  = rgb[i].blue_reg;
 838
 839		red_delta   = rgb[i].delta_red_reg;
 840		green_delta = rgb[i].delta_green_reg;
 841		blue_delta  = rgb[i].delta_blue_reg;
 842
 843		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 844		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 845		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 846
 847		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
 848		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
 849		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
 850	}
 851
 852}
 853
 854static enum dc_lut_mode dpp3_get_shaper_current(struct dpp *dpp_base)
 855{
 856	enum dc_lut_mode mode;
 857	uint32_t state_mode;
 858	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 859
 860	REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &state_mode);
 861
 862	switch (state_mode) {
 863	case 0:
 864		mode = LUT_BYPASS;
 865		break;
 866	case 1:
 867		mode = LUT_RAM_A;
 868		break;
 869	case 2:
 870		mode = LUT_RAM_B;
 871		break;
 872	default:
 873		mode = LUT_BYPASS;
 874		break;
 875	}
 876
 877	return mode;
 878}
 879
 880static void dpp3_configure_shaper_lut(
 881		struct dpp *dpp_base,
 882		bool is_ram_a)
 883{
 884	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 885
 886	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 887			CM_SHAPER_LUT_WRITE_EN_MASK, 7);
 888	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 889			CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 890	REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
 891}
 892
 893/*program shaper RAM A*/
 894
 895static void dpp3_program_shaper_luta_settings(
 896		struct dpp *dpp_base,
 897		const struct pwl_params *params)
 898{
 899	const struct gamma_curve *curve;
 900	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 901
 902	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
 903		CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 904		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 905	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
 906		CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
 907		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
 908	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
 909		CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
 910		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
 911
 912	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
 913		CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 914		CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 915
 916	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
 917		CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
 918		CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
 919
 920	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
 921		CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
 922		CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
 923
 924	curve = params->arr_curve_points;
 925	REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
 926		CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 927		CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 928		CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 929		CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 930
 931	curve += 2;
 932	REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
 933		CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
 934		CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
 935		CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
 936		CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
 937
 938	curve += 2;
 939	REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
 940		CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
 941		CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
 942		CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
 943		CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
 944
 945	curve += 2;
 946	REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
 947		CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
 948		CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
 949		CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
 950		CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
 951
 952	curve += 2;
 953	REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
 954		CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
 955		CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
 956		CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
 957		CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
 958
 959	curve += 2;
 960	REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
 961		CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
 962		CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
 963		CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
 964		CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
 965
 966	curve += 2;
 967	REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
 968		CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
 969		CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
 970		CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
 971		CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
 972
 973	curve += 2;
 974	REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
 975		CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
 976		CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
 977		CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
 978		CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
 979
 980	curve += 2;
 981	REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
 982		CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
 983		CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
 984		CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
 985		CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
 986
 987	curve += 2;
 988	REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
 989		CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
 990		CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
 991		CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
 992		CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
 993
 994	curve += 2;
 995	REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
 996		CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
 997		CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
 998		CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
 999		CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
1000
1001	curve += 2;
1002	REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
1003		CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
1004		CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
1005		CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
1006		CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
1007
1008	curve += 2;
1009	REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
1010		CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
1011		CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
1012		CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
1013		CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
1014
1015	curve += 2;
1016	REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
1017		CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
1018		CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
1019		CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
1020		CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
1021
1022	curve += 2;
1023	REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
1024		CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
1025		CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
1026		CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
1027		CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
1028
1029	curve += 2;
1030	REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
1031		CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
1032		CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
1033		CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
1034		CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
1035
1036	curve += 2;
1037	REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
1038		CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
1039		CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
1040		CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
1041		CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
1042}
1043
1044/*program shaper RAM B*/
1045static void dpp3_program_shaper_lutb_settings(
1046		struct dpp *dpp_base,
1047		const struct pwl_params *params)
1048{
1049	const struct gamma_curve *curve;
1050	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1051
1052	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
1053		CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
1054		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
1055	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
1056		CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
1057		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
1058	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
1059		CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
1060		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
1061
1062	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
1063		CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
1064		CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
1065
1066	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
1067		CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
1068		CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
1069
1070	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
1071		CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
1072		CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
1073
1074	curve = params->arr_curve_points;
1075	REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
1076		CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
1077		CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
1078		CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
1079		CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
1080
1081	curve += 2;
1082	REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
1083		CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
1084		CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
1085		CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
1086		CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
1087
1088	curve += 2;
1089	REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
1090		CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
1091		CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
1092		CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
1093		CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
1094
1095	curve += 2;
1096	REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
1097		CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
1098		CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
1099		CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
1100		CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
1101
1102	curve += 2;
1103	REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
1104		CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
1105		CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
1106		CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
1107		CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
1108
1109	curve += 2;
1110	REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
1111		CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
1112		CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
1113		CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
1114		CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
1115
1116	curve += 2;
1117	REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
1118		CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
1119		CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
1120		CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
1121		CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
1122
1123	curve += 2;
1124	REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
1125		CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
1126		CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
1127		CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
1128		CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
1129
1130	curve += 2;
1131	REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
1132		CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
1133		CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
1134		CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
1135		CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
1136
1137	curve += 2;
1138	REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
1139		CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
1140		CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
1141		CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
1142		CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
1143
1144	curve += 2;
1145	REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
1146		CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
1147		CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
1148		CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
1149		CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
1150
1151	curve += 2;
1152	REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
1153		CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
1154		CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
1155		CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
1156		CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
1157
1158	curve += 2;
1159	REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
1160		CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
1161		CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
1162		CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
1163		CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
1164
1165	curve += 2;
1166	REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
1167		CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
1168		CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
1169		CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
1170		CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
1171
1172	curve += 2;
1173	REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
1174		CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
1175		CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
1176		CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
1177		CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
1178
1179	curve += 2;
1180	REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
1181		CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
1182		CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
1183		CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
1184		CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
1185
1186	curve += 2;
1187	REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
1188		CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
1189		CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
1190		CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
1191		CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
1192
1193}
1194
1195
1196static bool dpp3_program_shaper(struct dpp *dpp_base,
1197				const struct pwl_params *params)
1198{
1199	enum dc_lut_mode current_mode;
1200	enum dc_lut_mode next_mode;
1201
1202	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1203
1204	if (params == NULL) {
1205		REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
1206		if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1207			dpp3_power_on_shaper(dpp_base, false);
1208		return false;
1209	}
1210
1211	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1212		dpp3_power_on_shaper(dpp_base, true);
1213
1214	current_mode = dpp3_get_shaper_current(dpp_base);
1215
1216	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
1217		next_mode = LUT_RAM_B;
1218	else
1219		next_mode = LUT_RAM_A;
1220
1221	dpp3_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
1222
1223	if (next_mode == LUT_RAM_A)
1224		dpp3_program_shaper_luta_settings(dpp_base, params);
1225	else
1226		dpp3_program_shaper_lutb_settings(dpp_base, params);
1227
1228	dpp3_program_shaper_lut(
1229			dpp_base, params->rgb_resulted, params->hw_points_num);
1230
1231	REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
1232
1233	return true;
1234
1235}
1236
1237static enum dc_lut_mode get3dlut_config(
1238			struct dpp *dpp_base,
1239			bool *is_17x17x17,
1240			bool *is_12bits_color_channel)
1241{
1242	uint32_t i_mode, i_enable_10bits, lut_size;
1243	enum dc_lut_mode mode;
1244	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1245
1246	REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
1247			CM_3DLUT_30BIT_EN, &i_enable_10bits);
1248	REG_GET(CM_3DLUT_MODE,
1249			CM_3DLUT_MODE_CURRENT, &i_mode);
1250
1251	switch (i_mode) {
1252	case 0:
1253		mode = LUT_BYPASS;
1254		break;
1255	case 1:
1256		mode = LUT_RAM_A;
1257		break;
1258	case 2:
1259		mode = LUT_RAM_B;
1260		break;
1261	default:
1262		mode = LUT_BYPASS;
1263		break;
1264	}
1265	if (i_enable_10bits > 0)
1266		*is_12bits_color_channel = false;
1267	else
1268		*is_12bits_color_channel = true;
1269
1270	REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
1271
1272	if (lut_size == 0)
1273		*is_17x17x17 = true;
1274	else
1275		*is_17x17x17 = false;
1276
1277	return mode;
1278}
1279/*
1280 * select ramA or ramB, or bypass
1281 * select color channel size 10 or 12 bits
1282 * select 3dlut size 17x17x17 or 9x9x9
1283 */
1284static void dpp3_set_3dlut_mode(
1285		struct dpp *dpp_base,
1286		enum dc_lut_mode mode,
1287		bool is_color_channel_12bits,
1288		bool is_lut_size17x17x17)
1289{
1290	uint32_t lut_mode;
1291	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1292
1293	if (mode == LUT_BYPASS)
1294		lut_mode = 0;
1295	else if (mode == LUT_RAM_A)
1296		lut_mode = 1;
1297	else
1298		lut_mode = 2;
1299
1300	REG_UPDATE_2(CM_3DLUT_MODE,
1301			CM_3DLUT_MODE, lut_mode,
1302			CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
1303}
1304
1305static void dpp3_select_3dlut_ram(
1306		struct dpp *dpp_base,
1307		enum dc_lut_mode mode,
1308		bool is_color_channel_12bits)
1309{
1310	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1311
1312	REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
1313			CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
1314			CM_3DLUT_30BIT_EN,
1315			is_color_channel_12bits == true ? 0:1);
1316}
1317
1318
1319
1320static void dpp3_set3dlut_ram12(
1321		struct dpp *dpp_base,
1322		const struct dc_rgb *lut,
1323		uint32_t entries)
1324{
1325	uint32_t i, red, green, blue, red1, green1, blue1;
1326	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1327
1328	for (i = 0 ; i < entries; i += 2) {
1329		red   = lut[i].red<<4;
1330		green = lut[i].green<<4;
1331		blue  = lut[i].blue<<4;
1332		red1   = lut[i+1].red<<4;
1333		green1 = lut[i+1].green<<4;
1334		blue1  = lut[i+1].blue<<4;
1335
1336		REG_SET_2(CM_3DLUT_DATA, 0,
1337				CM_3DLUT_DATA0, red,
1338				CM_3DLUT_DATA1, red1);
1339
1340		REG_SET_2(CM_3DLUT_DATA, 0,
1341				CM_3DLUT_DATA0, green,
1342				CM_3DLUT_DATA1, green1);
1343
1344		REG_SET_2(CM_3DLUT_DATA, 0,
1345				CM_3DLUT_DATA0, blue,
1346				CM_3DLUT_DATA1, blue1);
1347
1348	}
1349}
1350
1351/*
1352 * load selected lut with 10 bits color channels
1353 */
1354static void dpp3_set3dlut_ram10(
1355		struct dpp *dpp_base,
1356		const struct dc_rgb *lut,
1357		uint32_t entries)
1358{
1359	uint32_t i, red, green, blue, value;
1360	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1361
1362	for (i = 0; i < entries; i++) {
1363		red   = lut[i].red;
1364		green = lut[i].green;
1365		blue  = lut[i].blue;
1366
1367		value = (red<<20) | (green<<10) | blue;
1368
1369		REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1370	}
1371
1372}
1373
1374
1375static void dpp3_select_3dlut_ram_mask(
1376		struct dpp *dpp_base,
1377		uint32_t ram_selection_mask)
1378{
1379	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1380
1381	REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1382			ram_selection_mask);
1383	REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1384}
1385
1386static bool dpp3_program_3dlut(struct dpp *dpp_base,
1387			       struct tetrahedral_params *params)
1388{
1389	enum dc_lut_mode mode;
1390	bool is_17x17x17;
1391	bool is_12bits_color_channel;
1392	struct dc_rgb *lut0;
1393	struct dc_rgb *lut1;
1394	struct dc_rgb *lut2;
1395	struct dc_rgb *lut3;
1396	int lut_size0;
1397	int lut_size;
1398
1399	if (params == NULL) {
1400		dpp3_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1401		if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1402			dpp3_power_on_hdr3dlut(dpp_base, false);
1403		return false;
1404	}
1405
1406	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1407		dpp3_power_on_hdr3dlut(dpp_base, true);
1408
1409	mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1410
1411	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1412		mode = LUT_RAM_A;
1413	else
1414		mode = LUT_RAM_B;
1415
1416	is_17x17x17 = !params->use_tetrahedral_9;
1417	is_12bits_color_channel = params->use_12bits;
1418	if (is_17x17x17) {
1419		lut0 = params->tetrahedral_17.lut0;
1420		lut1 = params->tetrahedral_17.lut1;
1421		lut2 = params->tetrahedral_17.lut2;
1422		lut3 = params->tetrahedral_17.lut3;
1423		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1424					sizeof(params->tetrahedral_17.lut0[0]);
1425		lut_size  = sizeof(params->tetrahedral_17.lut1)/
1426					sizeof(params->tetrahedral_17.lut1[0]);
1427	} else {
1428		lut0 = params->tetrahedral_9.lut0;
1429		lut1 = params->tetrahedral_9.lut1;
1430		lut2 = params->tetrahedral_9.lut2;
1431		lut3 = params->tetrahedral_9.lut3;
1432		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1433				sizeof(params->tetrahedral_9.lut0[0]);
1434		lut_size  = sizeof(params->tetrahedral_9.lut1)/
1435				sizeof(params->tetrahedral_9.lut1[0]);
1436		}
1437
1438	dpp3_select_3dlut_ram(dpp_base, mode,
1439				is_12bits_color_channel);
1440	dpp3_select_3dlut_ram_mask(dpp_base, 0x1);
1441	if (is_12bits_color_channel)
1442		dpp3_set3dlut_ram12(dpp_base, lut0, lut_size0);
1443	else
1444		dpp3_set3dlut_ram10(dpp_base, lut0, lut_size0);
1445
1446	dpp3_select_3dlut_ram_mask(dpp_base, 0x2);
1447	if (is_12bits_color_channel)
1448		dpp3_set3dlut_ram12(dpp_base, lut1, lut_size);
1449	else
1450		dpp3_set3dlut_ram10(dpp_base, lut1, lut_size);
1451
1452	dpp3_select_3dlut_ram_mask(dpp_base, 0x4);
1453	if (is_12bits_color_channel)
1454		dpp3_set3dlut_ram12(dpp_base, lut2, lut_size);
1455	else
1456		dpp3_set3dlut_ram10(dpp_base, lut2, lut_size);
1457
1458	dpp3_select_3dlut_ram_mask(dpp_base, 0x8);
1459	if (is_12bits_color_channel)
1460		dpp3_set3dlut_ram12(dpp_base, lut3, lut_size);
1461	else
1462		dpp3_set3dlut_ram10(dpp_base, lut3, lut_size);
1463
1464
1465	dpp3_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1466					is_17x17x17);
1467
1468	return true;
1469}
1470static struct dpp_funcs dcn30_dpp_funcs = {
1471	.dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
1472	.dpp_read_state			= dpp30_read_state,
1473	.dpp_reset			= dpp_reset,
1474	.dpp_set_scaler			= dpp1_dscl_set_scaler_manual_scale,
1475	.dpp_get_optimal_number_of_taps	= dpp3_get_optimal_number_of_taps,
1476	.dpp_set_gamut_remap		= dpp3_cm_set_gamut_remap,
1477	.dpp_set_csc_adjustment		= NULL,
1478	.dpp_set_csc_default		= NULL,
1479	.dpp_program_regamma_pwl	= NULL,
1480	.dpp_set_pre_degam		= dpp3_set_pre_degam,
1481	.dpp_program_input_lut		= NULL,
1482	.dpp_full_bypass		= dpp1_full_bypass,
1483	.dpp_setup			= dpp3_cnv_setup,
1484	.dpp_program_degamma_pwl	= NULL,
1485	.dpp_program_cm_dealpha = dpp3_program_cm_dealpha,
1486	.dpp_program_cm_bias = dpp3_program_cm_bias,
1487	.dpp_program_blnd_lut = dpp3_program_blnd_lut,
1488	.dpp_program_shaper_lut = dpp3_program_shaper,
1489	.dpp_program_3dlut = dpp3_program_3dlut,
1490	.dpp_deferred_update = dpp3_deferred_update,
1491	.dpp_program_bias_and_scale	= NULL,
1492	.dpp_cnv_set_alpha_keyer	= dpp2_cnv_set_alpha_keyer,
1493	.set_cursor_attributes		= dpp3_set_cursor_attributes,
1494	.set_cursor_position		= dpp1_set_cursor_position,
1495	.set_optional_cursor_attributes	= dpp1_cnv_set_optional_cursor_attributes,
1496	.dpp_dppclk_control		= dpp1_dppclk_control,
1497	.dpp_set_hdr_multiplier		= dpp3_set_hdr_multiplier,
1498	.dpp_get_gamut_remap		= dpp3_cm_get_gamut_remap,
1499};
1500
1501
1502static struct dpp_caps dcn30_dpp_cap = {
1503	.dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
1504	.dscl_calc_lb_num_partitions = dscl2_calc_lb_num_partitions,
1505};
1506
1507bool dpp3_construct(
1508	struct dcn3_dpp *dpp,
1509	struct dc_context *ctx,
1510	uint32_t inst,
1511	const struct dcn3_dpp_registers *tf_regs,
1512	const struct dcn3_dpp_shift *tf_shift,
1513	const struct dcn3_dpp_mask *tf_mask)
1514{
1515	dpp->base.ctx = ctx;
1516
1517	dpp->base.inst = inst;
1518	dpp->base.funcs = &dcn30_dpp_funcs;
1519	dpp->base.caps = &dcn30_dpp_cap;
1520
1521	dpp->tf_regs = tf_regs;
1522	dpp->tf_shift = tf_shift;
1523	dpp->tf_mask = tf_mask;
1524
1525	return true;
1526}
1527