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