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