File Index
Files and directories
Sign in
FILE

dcn30_dpp.c

File preview with syntax highlighting.

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