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