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,
448 CM_BLNDGAM_CONFIG_STATUS, &state_mode);
449
450 switch (state_mode) {
451 case 0:
452 mode = LUT_BYPASS;
453 break;
454 case 1:
455 mode = LUT_RAM_A;
456 break;
457 case 2:
458 mode = LUT_RAM_B;
459 break;
460 default:
461 mode = LUT_BYPASS;
462 break;
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 ? true:false);
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,
541 CM_SHAPER_CONFIG_STATUS, &state_mode);
542
543 switch (state_mode) {
544 case 0:
545 mode = LUT_BYPASS;
546 break;
547 case 1:
548 mode = LUT_RAM_A;
549 break;
550 case 2:
551 mode = LUT_RAM_B;
552 break;
553 default:
554 mode = LUT_BYPASS;
555 break;
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 ? true:false);
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