xref: /linux/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c (revision d4a292c5f8e65d2784b703c67179f4f7d0c7846c)
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 
dpp30_read_state(struct dpp * dpp_base,struct dcn_dpp_state * s)44 void 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 
dpp30_read_reg_state(struct dpp * dpp_base,struct dcn_dpp_reg_state * dpp_reg_state)87 void 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*/
dpp3_program_post_csc(struct dpp * dpp_base,enum dc_color_space color_space,enum dcn10_input_csc_select input_select,const struct out_csc_color_matrix * tbl_entry)104 void 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*/
dpp3_set_pre_degam(struct dpp * dpp_base,enum dc_transfer_func_predefined tr)178 void 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 
dpp3_cnv_setup(struct dpp * dpp_base,enum surface_pixel_format format,enum expansion_mode mode,struct dc_csc_transform input_csc_color_matrix,enum dc_color_space input_color_space,struct cnv_alpha_2bit_lut * alpha_2bit_lut)220 void 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 
dpp3_set_cursor_attributes(struct dpp * dpp_base,struct dc_cursor_attributes * cursor_attributes)400 void 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 
dpp3_get_optimal_number_of_taps(struct dpp * dpp,struct scaler_data * scl_data,const struct scaling_taps * in_taps)438 bool 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 
dpp3_deferred_update(struct dpp * dpp_base)540 static 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 
dpp3_power_on_blnd_lut(struct dpp * dpp_base,bool power_on)587 static 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 
dpp3_power_on_hdr3dlut(struct dpp * dpp_base,bool power_on)604 static 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 
dpp3_power_on_shaper(struct dpp * dpp_base,bool power_on)621 static 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 
dpp3_configure_blnd_lut(struct dpp * dpp_base,bool is_ram_a)638 static 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 
dpp3_program_blnd_pwl(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)651 static 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 
dcn3_dpp_cm_get_reg_field(struct dcn3_dpp * dpp,struct dcn3_xfer_func_reg * reg)687 static 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*/
dpp3_program_blnd_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)715 static 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*/
dpp3_program_blnd_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)743 static 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 
dpp3_get_blndgam_current(struct dpp * dpp_base)770 static 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 
dpp3_program_blnd_lut(struct dpp * dpp_base,const struct pwl_params * params)801 static 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 
dpp3_program_shaper_lut(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)839 static 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 
dpp3_get_shaper_current(struct dpp * dpp_base)871 static 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 
dpp3_configure_shaper_lut(struct dpp * dpp_base,bool is_ram_a)897 static 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 
dpp3_program_shaper_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)912 static 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*/
dpp3_program_shaper_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)1062 static 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 
dpp3_program_shaper(struct dpp * dpp_base,const struct pwl_params * params)1213 static 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 
get3dlut_config(struct dpp * dpp_base,bool * is_17x17x17,bool * is_12bits_color_channel)1253 static 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  */
dpp3_set_3dlut_mode(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits,bool is_lut_size17x17x17)1300 static 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 
dpp3_select_3dlut_ram(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits)1321 static 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 
dpp3_set3dlut_ram12(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)1336 static 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  */
dpp3_set3dlut_ram10(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)1370 static 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 
dpp3_select_3dlut_ram_mask(struct dpp * dpp_base,uint32_t ram_selection_mask)1391 static 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 
dpp3_program_3dlut(struct dpp * dpp_base,const struct tetrahedral_params * params)1402 static 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 }
1485 static 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 
1518 static 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 
dpp3_construct(struct dcn3_dpp * dpp,struct dc_context * ctx,uint32_t inst,const struct dcn3_dpp_registers * tf_regs,const struct dcn3_dpp_shift * tf_shift,const struct dcn3_dpp_mask * tf_mask)1523 bool 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 
dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space)1544 bool 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 }
1559