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