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_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 
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)237 void dpp2_program_input_csc(
238 		struct dpp *dpp_base,
239 		enum dc_color_space color_space,
240 		enum dcn20_input_csc_select input_select,
241 		const struct out_csc_color_matrix *tbl_entry)
242 {
243 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
244 	int i;
245 	int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
246 	const uint16_t *regval = NULL;
247 	uint32_t cur_select = 0;
248 	enum dcn20_input_csc_select select;
249 	struct color_matrices_reg icsc_regs;
250 
251 	if (input_select == DCN2_ICSC_SELECT_BYPASS) {
252 		REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
253 		return;
254 	}
255 
256 	if (tbl_entry == NULL) {
257 		for (i = 0; i < arr_size; i++)
258 			if (dpp_input_csc_matrix[i].color_space == color_space) {
259 				regval = dpp_input_csc_matrix[i].regval;
260 				break;
261 			}
262 
263 		if (regval == NULL) {
264 			BREAK_TO_DEBUGGER();
265 			return;
266 		}
267 	} else {
268 		regval = tbl_entry->regval;
269 	}
270 
271 	/* determine which CSC coefficients (A or B) we are using
272 	 * currently.  select the alternate set to double buffer
273 	 * the CSC update so CSC is updated on frame boundary
274 	 */
275 	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
276 					CM_TEST_DEBUG_DATA_STATUS_IDX,
277 					CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
278 
279 	if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
280 		select = DCN2_ICSC_SELECT_ICSC_A;
281 	else
282 		select = DCN2_ICSC_SELECT_ICSC_B;
283 
284 	icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
285 	icsc_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
286 	icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
287 	icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
288 
289 	if (select == DCN2_ICSC_SELECT_ICSC_A) {
290 
291 		icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
292 		icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
293 
294 	} else {
295 
296 		icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
297 		icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
298 
299 	}
300 
301 	cm_helper_program_color_matrices(
302 			dpp->base.ctx,
303 			regval,
304 			&icsc_regs);
305 
306 	REG_SET(CM_ICSC_CONTROL, 0,
307 				CM_ICSC_MODE, select);
308 }
309 
dpp20_power_on_blnd_lut(struct dpp * dpp_base,bool power_on)310 static void dpp20_power_on_blnd_lut(
311 	struct dpp *dpp_base,
312 	bool power_on)
313 {
314 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
315 
316 	REG_SET(CM_MEM_PWR_CTRL, 0,
317 			BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
318 
319 }
320 
dpp20_configure_blnd_lut(struct dpp * dpp_base,bool is_ram_a)321 static void dpp20_configure_blnd_lut(
322 		struct dpp *dpp_base,
323 		bool is_ram_a)
324 {
325 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
326 
327 	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
328 			CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
329 	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
330 			CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
331 	REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
332 }
333 
dpp20_program_blnd_pwl(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)334 static void dpp20_program_blnd_pwl(
335 		struct dpp *dpp_base,
336 		const struct pwl_result_data *rgb,
337 		uint32_t num)
338 {
339 	uint32_t i;
340 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
341 
342 	for (i = 0 ; i < num; i++) {
343 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
344 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
345 		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
346 
347 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
348 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
349 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
350 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
351 		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
352 				CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
353 
354 	}
355 
356 }
357 
dcn20_dpp_cm_get_reg_field(struct dcn20_dpp * dpp,struct xfer_func_reg * reg)358 static void dcn20_dpp_cm_get_reg_field(
359 		struct dcn20_dpp *dpp,
360 		struct xfer_func_reg *reg)
361 {
362 	reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
363 	reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
364 	reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
365 	reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
366 	reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
367 	reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
368 	reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
369 	reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
370 
371 	reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
372 	reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
373 	reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
374 	reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
375 	reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
376 	reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
377 	reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
378 	reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
379 	reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
380 	reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
381 	reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
382 	reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
383 }
384 
385 /*program blnd lut RAM A*/
dpp20_program_blnd_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)386 static void dpp20_program_blnd_luta_settings(
387 		struct dpp *dpp_base,
388 		const struct pwl_params *params)
389 {
390 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
391 	struct xfer_func_reg gam_regs;
392 
393 	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
394 
395 	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
396 	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
397 	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
398 	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
399 	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
400 	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
401 	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
402 	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
403 	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
404 	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
405 	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
406 	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
407 	gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
408 	gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
409 
410 	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
411 }
412 
413 /*program blnd lut RAM B*/
dpp20_program_blnd_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)414 static void dpp20_program_blnd_lutb_settings(
415 		struct dpp *dpp_base,
416 		const struct pwl_params *params)
417 {
418 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
419 	struct xfer_func_reg gam_regs;
420 
421 	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
422 
423 	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
424 	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
425 	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
426 	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
427 	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
428 	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
429 	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
430 	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
431 	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
432 	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
433 	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
434 	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
435 	gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
436 	gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
437 
438 	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
439 }
440 
dpp20_get_blndgam_current(struct dpp * dpp_base)441 static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
442 {
443 	enum dc_lut_mode mode;
444 	uint32_t state_mode;
445 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
446 
447 	REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK, CM_BLNDGAM_CONFIG_STATUS, &state_mode);
448 
449 	switch (state_mode) {
450 	case 0:
451 		mode = LUT_BYPASS;
452 		break;
453 	case 1:
454 		mode = LUT_RAM_A;
455 		break;
456 	case 2:
457 		mode = LUT_RAM_B;
458 		break;
459 	default:
460 		mode = LUT_BYPASS;
461 		break;
462 	}
463 
464 	return mode;
465 }
466 
dpp20_program_blnd_lut(struct dpp * dpp_base,const struct pwl_params * params)467 bool dpp20_program_blnd_lut(
468 	struct dpp *dpp_base, const struct pwl_params *params)
469 {
470 	enum dc_lut_mode current_mode;
471 	enum dc_lut_mode next_mode;
472 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
473 
474 	if (params == NULL) {
475 		REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
476 		return false;
477 	}
478 	current_mode = dpp20_get_blndgam_current(dpp_base);
479 	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
480 		next_mode = LUT_RAM_B;
481 	else
482 		next_mode = LUT_RAM_A;
483 
484 	dpp20_power_on_blnd_lut(dpp_base, true);
485 	dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
486 
487 	if (next_mode == LUT_RAM_A)
488 		dpp20_program_blnd_luta_settings(dpp_base, params);
489 	else
490 		dpp20_program_blnd_lutb_settings(dpp_base, params);
491 
492 	dpp20_program_blnd_pwl(
493 			dpp_base, params->rgb_resulted, params->hw_points_num);
494 
495 	REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
496 			next_mode == LUT_RAM_A ? 1:2);
497 
498 	return true;
499 }
500 
501 
dpp20_program_shaper_lut(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)502 static void dpp20_program_shaper_lut(
503 		struct dpp *dpp_base,
504 		const struct pwl_result_data *rgb,
505 		uint32_t num)
506 {
507 	uint32_t i, red, green, blue;
508 	uint32_t  red_delta, green_delta, blue_delta;
509 	uint32_t  red_value, green_value, blue_value;
510 
511 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
512 
513 	for (i = 0 ; i < num; i++) {
514 
515 		red   = rgb[i].red_reg;
516 		green = rgb[i].green_reg;
517 		blue  = rgb[i].blue_reg;
518 
519 		red_delta   = rgb[i].delta_red_reg;
520 		green_delta = rgb[i].delta_green_reg;
521 		blue_delta  = rgb[i].delta_blue_reg;
522 
523 		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
524 		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
525 		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
526 
527 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
528 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
529 		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
530 	}
531 
532 }
533 
dpp20_get_shaper_current(struct dpp * dpp_base)534 static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
535 {
536 	enum dc_lut_mode mode;
537 	uint32_t state_mode;
538 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
539 
540 	REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK, CM_SHAPER_CONFIG_STATUS, &state_mode);
541 
542 	switch (state_mode) {
543 	case 0:
544 		mode = LUT_BYPASS;
545 		break;
546 	case 1:
547 		mode = LUT_RAM_A;
548 		break;
549 	case 2:
550 		mode = LUT_RAM_B;
551 		break;
552 	default:
553 		mode = LUT_BYPASS;
554 		break;
555 	}
556 
557 	return mode;
558 }
559 
dpp20_configure_shaper_lut(struct dpp * dpp_base,bool is_ram_a)560 static void dpp20_configure_shaper_lut(
561 		struct dpp *dpp_base,
562 		bool is_ram_a)
563 {
564 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
565 
566 	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
567 			CM_SHAPER_LUT_WRITE_EN_MASK, 7);
568 	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
569 			CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
570 	REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
571 }
572 
573 /*program shaper RAM A*/
574 
dpp20_program_shaper_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)575 static void dpp20_program_shaper_luta_settings(
576 		struct dpp *dpp_base,
577 		const struct pwl_params *params)
578 {
579 	const struct gamma_curve *curve;
580 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
581 
582 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
583 		CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
584 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
585 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
586 		CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
587 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
588 	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
589 		CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
590 		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
591 
592 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
593 		CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
594 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
595 
596 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
597 		CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
598 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
599 
600 	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
601 		CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
602 		CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
603 
604 	curve = params->arr_curve_points;
605 	REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
606 		CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
607 		CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
608 		CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
609 		CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
610 
611 	curve += 2;
612 	REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
613 		CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
614 		CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
615 		CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
616 		CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
617 
618 	curve += 2;
619 	REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
620 		CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
621 		CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
622 		CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
623 		CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
624 
625 	curve += 2;
626 	REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
627 		CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
628 		CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
629 		CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
630 		CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
631 
632 	curve += 2;
633 	REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
634 		CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
635 		CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
636 		CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
637 		CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
638 
639 	curve += 2;
640 	REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
641 		CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
642 		CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
643 		CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
644 		CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
645 
646 	curve += 2;
647 	REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
648 		CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
649 		CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
650 		CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
651 		CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
652 
653 	curve += 2;
654 	REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
655 		CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
656 		CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
657 		CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
658 		CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
659 
660 	curve += 2;
661 	REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
662 		CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
663 		CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
664 		CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
665 		CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
666 
667 	curve += 2;
668 	REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
669 		CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
670 		CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
671 		CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
672 		CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
673 
674 	curve += 2;
675 	REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
676 		CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
677 		CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
678 		CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
679 		CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
680 
681 	curve += 2;
682 	REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
683 		CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
684 		CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
685 		CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
686 		CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
687 
688 	curve += 2;
689 	REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
690 		CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
691 		CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
692 		CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
693 		CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
694 
695 	curve += 2;
696 	REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
697 		CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
698 		CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
699 		CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
700 		CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
701 
702 	curve += 2;
703 	REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
704 		CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
705 		CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
706 		CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
707 		CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
708 
709 	curve += 2;
710 	REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
711 		CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
712 		CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
713 		CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
714 		CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
715 
716 	curve += 2;
717 	REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
718 		CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
719 		CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
720 		CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
721 		CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
722 }
723 
724 /*program shaper RAM B*/
dpp20_program_shaper_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)725 static void dpp20_program_shaper_lutb_settings(
726 		struct dpp *dpp_base,
727 		const struct pwl_params *params)
728 {
729 	const struct gamma_curve *curve;
730 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
731 
732 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
733 		CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
734 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
735 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
736 		CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
737 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
738 	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
739 		CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
740 		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
741 
742 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
743 		CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
744 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
745 
746 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
747 		CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
748 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
749 
750 	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
751 		CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
752 		CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
753 
754 	curve = params->arr_curve_points;
755 	REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
756 		CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
757 		CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
758 		CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
759 		CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
760 
761 	curve += 2;
762 	REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
763 		CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
764 		CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
765 		CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
766 		CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
767 
768 	curve += 2;
769 	REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
770 		CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
771 		CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
772 		CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
773 		CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
774 
775 	curve += 2;
776 	REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
777 		CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
778 		CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
779 		CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
780 		CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
781 
782 	curve += 2;
783 	REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
784 		CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
785 		CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
786 		CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
787 		CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
788 
789 	curve += 2;
790 	REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
791 		CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
792 		CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
793 		CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
794 		CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
795 
796 	curve += 2;
797 	REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
798 		CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
799 		CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
800 		CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
801 		CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
802 
803 	curve += 2;
804 	REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
805 		CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
806 		CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
807 		CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
808 		CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
809 
810 	curve += 2;
811 	REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
812 		CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
813 		CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
814 		CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
815 		CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
816 
817 	curve += 2;
818 	REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
819 		CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
820 		CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
821 		CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
822 		CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
823 
824 	curve += 2;
825 	REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
826 		CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
827 		CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
828 		CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
829 		CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
830 
831 	curve += 2;
832 	REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
833 		CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
834 		CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
835 		CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
836 		CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
837 
838 	curve += 2;
839 	REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
840 		CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
841 		CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
842 		CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
843 		CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
844 
845 	curve += 2;
846 	REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
847 		CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
848 		CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
849 		CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
850 		CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
851 
852 	curve += 2;
853 	REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
854 		CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
855 		CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
856 		CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
857 		CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
858 
859 	curve += 2;
860 	REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
861 		CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
862 		CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
863 		CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
864 		CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
865 
866 	curve += 2;
867 	REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
868 		CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
869 		CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
870 		CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
871 		CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
872 
873 }
874 
875 
dpp20_program_shaper(struct dpp * dpp_base,const struct pwl_params * params)876 bool dpp20_program_shaper(
877 		struct dpp *dpp_base,
878 		const struct pwl_params *params)
879 {
880 	enum dc_lut_mode current_mode;
881 	enum dc_lut_mode next_mode;
882 
883 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
884 
885 	if (params == NULL) {
886 		REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
887 		return false;
888 	}
889 	current_mode = dpp20_get_shaper_current(dpp_base);
890 
891 	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
892 		next_mode = LUT_RAM_B;
893 	else
894 		next_mode = LUT_RAM_A;
895 
896 	dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
897 
898 	if (next_mode == LUT_RAM_A)
899 		dpp20_program_shaper_luta_settings(dpp_base, params);
900 	else
901 		dpp20_program_shaper_lutb_settings(dpp_base, params);
902 
903 	dpp20_program_shaper_lut(
904 			dpp_base, params->rgb_resulted, params->hw_points_num);
905 
906 	REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
907 
908 	return true;
909 
910 }
911 
get3dlut_config(struct dpp * dpp_base,bool * is_17x17x17,bool * is_12bits_color_channel)912 static enum dc_lut_mode get3dlut_config(
913 			struct dpp *dpp_base,
914 			bool *is_17x17x17,
915 			bool *is_12bits_color_channel)
916 {
917 	uint32_t i_mode, i_enable_10bits, lut_size;
918 	enum dc_lut_mode mode;
919 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
920 
921 	REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
922 			CM_3DLUT_CONFIG_STATUS, &i_mode,
923 			CM_3DLUT_30BIT_EN, &i_enable_10bits);
924 
925 	switch (i_mode) {
926 	case 0:
927 		mode = LUT_BYPASS;
928 		break;
929 	case 1:
930 		mode = LUT_RAM_A;
931 		break;
932 	case 2:
933 		mode = LUT_RAM_B;
934 		break;
935 	default:
936 		mode = LUT_BYPASS;
937 		break;
938 	}
939 	if (i_enable_10bits > 0)
940 		*is_12bits_color_channel = false;
941 	else
942 		*is_12bits_color_channel = true;
943 
944 	REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
945 
946 	if (lut_size == 0)
947 		*is_17x17x17 = true;
948 	else
949 		*is_17x17x17 = false;
950 
951 	return mode;
952 }
953 /*
954  * select ramA or ramB, or bypass
955  * select color channel size 10 or 12 bits
956  * select 3dlut size 17x17x17 or 9x9x9
957  */
dpp20_set_3dlut_mode(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits,bool is_lut_size17x17x17)958 static void dpp20_set_3dlut_mode(
959 		struct dpp *dpp_base,
960 		enum dc_lut_mode mode,
961 		bool is_color_channel_12bits,
962 		bool is_lut_size17x17x17)
963 {
964 	uint32_t lut_mode;
965 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
966 
967 	if (mode == LUT_BYPASS)
968 		lut_mode = 0;
969 	else if (mode == LUT_RAM_A)
970 		lut_mode = 1;
971 	else
972 		lut_mode = 2;
973 
974 	REG_UPDATE_2(CM_3DLUT_MODE,
975 			CM_3DLUT_MODE, lut_mode,
976 			CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
977 }
978 
dpp20_select_3dlut_ram(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits)979 static void dpp20_select_3dlut_ram(
980 		struct dpp *dpp_base,
981 		enum dc_lut_mode mode,
982 		bool is_color_channel_12bits)
983 {
984 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
985 
986 	REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
987 			CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
988 			CM_3DLUT_30BIT_EN,
989 			is_color_channel_12bits == true ? 0:1);
990 }
991 
992 
993 
dpp20_set3dlut_ram12(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)994 static void dpp20_set3dlut_ram12(
995 		struct dpp *dpp_base,
996 		const struct dc_rgb *lut,
997 		uint32_t entries)
998 {
999 	uint32_t i, red, green, blue, red1, green1, blue1;
1000 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1001 
1002 	for (i = 0 ; i < entries; i += 2) {
1003 		red   = lut[i].red<<4;
1004 		green = lut[i].green<<4;
1005 		blue  = lut[i].blue<<4;
1006 		red1   = lut[i+1].red<<4;
1007 		green1 = lut[i+1].green<<4;
1008 		blue1  = lut[i+1].blue<<4;
1009 
1010 		REG_SET_2(CM_3DLUT_DATA, 0,
1011 				CM_3DLUT_DATA0, red,
1012 				CM_3DLUT_DATA1, red1);
1013 
1014 		REG_SET_2(CM_3DLUT_DATA, 0,
1015 				CM_3DLUT_DATA0, green,
1016 				CM_3DLUT_DATA1, green1);
1017 
1018 		REG_SET_2(CM_3DLUT_DATA, 0,
1019 				CM_3DLUT_DATA0, blue,
1020 				CM_3DLUT_DATA1, blue1);
1021 
1022 	}
1023 }
1024 
1025 /*
1026  * load selected lut with 10 bits color channels
1027  */
dpp20_set3dlut_ram10(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)1028 static void dpp20_set3dlut_ram10(
1029 		struct dpp *dpp_base,
1030 		const struct dc_rgb *lut,
1031 		uint32_t entries)
1032 {
1033 	uint32_t i, red, green, blue, value;
1034 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1035 
1036 	for (i = 0; i < entries; i++) {
1037 		red   = lut[i].red;
1038 		green = lut[i].green;
1039 		blue  = lut[i].blue;
1040 
1041 		value = (red<<20) | (green<<10) | blue;
1042 
1043 		REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1044 	}
1045 
1046 }
1047 
1048 
dpp20_select_3dlut_ram_mask(struct dpp * dpp_base,uint32_t ram_selection_mask)1049 static void dpp20_select_3dlut_ram_mask(
1050 		struct dpp *dpp_base,
1051 		uint32_t ram_selection_mask)
1052 {
1053 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1054 
1055 	REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1056 			ram_selection_mask);
1057 	REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1058 }
1059 
dpp20_program_3dlut(struct dpp * dpp_base,struct tetrahedral_params * params)1060 bool dpp20_program_3dlut(
1061 		struct dpp *dpp_base,
1062 		struct tetrahedral_params *params)
1063 {
1064 	enum dc_lut_mode mode;
1065 	bool is_17x17x17;
1066 	bool is_12bits_color_channel;
1067 	struct dc_rgb *lut0;
1068 	struct dc_rgb *lut1;
1069 	struct dc_rgb *lut2;
1070 	struct dc_rgb *lut3;
1071 	int lut_size0;
1072 	int lut_size;
1073 
1074 	if (params == NULL) {
1075 		dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1076 		return false;
1077 	}
1078 	mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1079 
1080 	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1081 		mode = LUT_RAM_A;
1082 	else
1083 		mode = LUT_RAM_B;
1084 
1085 	is_17x17x17 = !params->use_tetrahedral_9;
1086 	is_12bits_color_channel = params->use_12bits;
1087 	if (is_17x17x17) {
1088 		lut0 = params->tetrahedral_17.lut0;
1089 		lut1 = params->tetrahedral_17.lut1;
1090 		lut2 = params->tetrahedral_17.lut2;
1091 		lut3 = params->tetrahedral_17.lut3;
1092 		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1093 					sizeof(params->tetrahedral_17.lut0[0]);
1094 		lut_size  = sizeof(params->tetrahedral_17.lut1)/
1095 					sizeof(params->tetrahedral_17.lut1[0]);
1096 	} else {
1097 		lut0 = params->tetrahedral_9.lut0;
1098 		lut1 = params->tetrahedral_9.lut1;
1099 		lut2 = params->tetrahedral_9.lut2;
1100 		lut3 = params->tetrahedral_9.lut3;
1101 		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1102 				sizeof(params->tetrahedral_9.lut0[0]);
1103 		lut_size  = sizeof(params->tetrahedral_9.lut1)/
1104 				sizeof(params->tetrahedral_9.lut1[0]);
1105 		}
1106 
1107 	dpp20_select_3dlut_ram(dpp_base, mode,
1108 				is_12bits_color_channel);
1109 	dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
1110 	if (is_12bits_color_channel)
1111 		dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
1112 	else
1113 		dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
1114 
1115 	dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
1116 	if (is_12bits_color_channel)
1117 		dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
1118 	else
1119 		dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
1120 
1121 	dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
1122 	if (is_12bits_color_channel)
1123 		dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
1124 	else
1125 		dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
1126 
1127 	dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
1128 	if (is_12bits_color_channel)
1129 		dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
1130 	else
1131 		dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
1132 
1133 
1134 	dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1135 					is_17x17x17);
1136 
1137 	return true;
1138 }
1139 
dpp2_set_hdr_multiplier(struct dpp * dpp_base,uint32_t multiplier)1140 void dpp2_set_hdr_multiplier(
1141 		struct dpp *dpp_base,
1142 		uint32_t multiplier)
1143 {
1144 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1145 
1146 	REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
1147 }
1148