1 /*
2 * Copyright 2020 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 #include "core_types.h"
28 #include "reg_helper.h"
29 #include "dcn30/dcn30_dpp.h"
30 #include "basics/conversion.h"
31 #include "dcn30/dcn30_cm_common.h"
32
33 #define REG(reg)\
34 dpp->tf_regs->reg
35
36 #define CTX \
37 dpp->base.ctx
38
39 #undef FN
40 #define FN(reg_name, field_name) \
41 dpp->tf_shift->field_name, dpp->tf_mask->field_name
42
43
dpp30_read_state(struct dpp * dpp_base,struct dcn_dpp_state * s)44 void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s)
45 {
46 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
47 uint32_t gamcor_lut_mode, rgam_lut_mode;
48
49 REG_GET(DPP_CONTROL,
50 DPP_CLOCK_ENABLE, &s->is_enabled);
51
52 // Pre-degamma (ROM)
53 REG_GET_2(PRE_DEGAM,
54 PRE_DEGAM_MODE, &s->pre_dgam_mode,
55 PRE_DEGAM_SELECT, &s->pre_dgam_select);
56
57 // Gamma Correction (RAM)
58 REG_GET(CM_GAMCOR_CONTROL,
59 CM_GAMCOR_MODE_CURRENT, &s->gamcor_mode);
60 if (s->gamcor_mode) {
61 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, &gamcor_lut_mode);
62 if (!gamcor_lut_mode)
63 s->gamcor_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B
64 }
65
66 // Shaper LUT (RAM), 3D LUT (mode, bit-depth, size)
67 if (REG(CM_SHAPER_CONTROL))
68 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_LUT_MODE, &s->shaper_lut_mode);
69 if (REG(CM_3DLUT_MODE))
70 REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &s->lut3d_mode);
71 if (REG(CM_3DLUT_READ_WRITE_CONTROL))
72 REG_GET(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
73 if (REG(CM_3DLUT_MODE))
74 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &s->lut3d_size);
75
76 // Blend/Out Gamma (RAM)
77 if (REG(CM_BLNDGAM_CONTROL)) {
78 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &s->rgam_lut_mode);
79 if (s->rgam_lut_mode) {
80 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &rgam_lut_mode);
81 if (!rgam_lut_mode)
82 s->rgam_lut_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B
83 }
84 }
85 }
86
dpp30_read_reg_state(struct dpp * dpp_base,struct dcn_dpp_reg_state * dpp_reg_state)87 void dpp30_read_reg_state(struct dpp *dpp_base, struct dcn_dpp_reg_state *dpp_reg_state)
88 {
89 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
90
91 dpp_reg_state->recout_start = REG_READ(RECOUT_START);
92 dpp_reg_state->recout_size = REG_READ(RECOUT_SIZE);
93 dpp_reg_state->scl_horz_filter_scale_ratio = REG_READ(SCL_HORZ_FILTER_SCALE_RATIO);
94 dpp_reg_state->scl_vert_filter_scale_ratio = REG_READ(SCL_VERT_FILTER_SCALE_RATIO);
95 dpp_reg_state->scl_mode = REG_READ(SCL_MODE);
96 dpp_reg_state->cm_control = REG_READ(CM_CONTROL);
97 dpp_reg_state->dpp_control = REG_READ(DPP_CONTROL);
98 dpp_reg_state->dscl_control = REG_READ(DSCL_CONTROL);
99 dpp_reg_state->obuf_control = REG_READ(OBUF_CONTROL);
100 dpp_reg_state->mpc_size = REG_READ(MPC_SIZE);
101 }
102
103 /*program post scaler scs block in dpp CM*/
dpp3_program_post_csc(struct dpp * dpp_base,enum dc_color_space color_space,enum dcn10_input_csc_select input_select,const struct out_csc_color_matrix * tbl_entry)104 void dpp3_program_post_csc(
105 struct dpp *dpp_base,
106 enum dc_color_space color_space,
107 enum dcn10_input_csc_select input_select,
108 const struct out_csc_color_matrix *tbl_entry)
109 {
110 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
111 int i;
112 int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
113 const uint16_t *regval = NULL;
114 uint32_t cur_select = 0;
115 enum dcn10_input_csc_select select;
116 struct color_matrices_reg gam_regs;
117
118 if (input_select == INPUT_CSC_SELECT_BYPASS) {
119 REG_SET(CM_POST_CSC_CONTROL, 0, CM_POST_CSC_MODE, 0);
120 return;
121 }
122
123 if (tbl_entry == NULL) {
124 for (i = 0; i < arr_size; i++)
125 if (dpp_input_csc_matrix[i].color_space == color_space) {
126 regval = dpp_input_csc_matrix[i].regval;
127 break;
128 }
129
130 if (regval == NULL) {
131 BREAK_TO_DEBUGGER();
132 return;
133 }
134 } else {
135 regval = tbl_entry->regval;
136 }
137
138 /* determine which CSC matrix (icsc or coma) we are using
139 * currently. select the alternate set to double buffer
140 * the CSC update so CSC is updated on frame boundary
141 */
142 REG_GET(CM_POST_CSC_CONTROL,
143 CM_POST_CSC_MODE_CURRENT, &cur_select);
144
145 if (cur_select != INPUT_CSC_SELECT_ICSC)
146 select = INPUT_CSC_SELECT_ICSC;
147 else
148 select = INPUT_CSC_SELECT_COMA;
149
150 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_POST_CSC_C11;
151 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_POST_CSC_C11;
152 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_POST_CSC_C12;
153 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_POST_CSC_C12;
154
155 if (select == INPUT_CSC_SELECT_ICSC) {
156
157 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_C11_C12);
158 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_C33_C34);
159
160 } else {
161
162 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_B_C11_C12);
163 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_B_C33_C34);
164
165 }
166
167 cm_helper_program_color_matrices(
168 dpp->base.ctx,
169 regval,
170 &gam_regs);
171
172 REG_SET(CM_POST_CSC_CONTROL, 0,
173 CM_POST_CSC_MODE, select);
174 }
175
176
177 /*CNVC degam unit has read only LUTs*/
dpp3_set_pre_degam(struct dpp * dpp_base,enum dc_transfer_func_predefined tr)178 void dpp3_set_pre_degam(struct dpp *dpp_base, enum dc_transfer_func_predefined tr)
179 {
180 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
181 int pre_degam_en = 1;
182 int degamma_lut_selection = 0;
183
184 switch (tr) {
185 case TRANSFER_FUNCTION_LINEAR:
186 case TRANSFER_FUNCTION_UNITY:
187 pre_degam_en = 0; //bypass
188 break;
189 case TRANSFER_FUNCTION_SRGB:
190 degamma_lut_selection = 0;
191 break;
192 case TRANSFER_FUNCTION_BT709:
193 degamma_lut_selection = 4;
194 break;
195 case TRANSFER_FUNCTION_PQ:
196 degamma_lut_selection = 5;
197 break;
198 case TRANSFER_FUNCTION_HLG:
199 degamma_lut_selection = 6;
200 break;
201 case TRANSFER_FUNCTION_GAMMA22:
202 degamma_lut_selection = 1;
203 break;
204 case TRANSFER_FUNCTION_GAMMA24:
205 degamma_lut_selection = 2;
206 break;
207 case TRANSFER_FUNCTION_GAMMA26:
208 degamma_lut_selection = 3;
209 break;
210 default:
211 pre_degam_en = 0;
212 break;
213 }
214
215 REG_SET_2(PRE_DEGAM, 0,
216 PRE_DEGAM_MODE, pre_degam_en,
217 PRE_DEGAM_SELECT, degamma_lut_selection);
218 }
219
dpp3_cnv_setup(struct dpp * dpp_base,enum surface_pixel_format format,enum expansion_mode mode,struct dc_csc_transform input_csc_color_matrix,enum dc_color_space input_color_space,struct cnv_alpha_2bit_lut * alpha_2bit_lut)220 void dpp3_cnv_setup (
221 struct dpp *dpp_base,
222 enum surface_pixel_format format,
223 enum expansion_mode mode,
224 struct dc_csc_transform input_csc_color_matrix,
225 enum dc_color_space input_color_space,
226 struct cnv_alpha_2bit_lut *alpha_2bit_lut)
227 {
228 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
229 uint32_t pixel_format = 0;
230 uint32_t alpha_en = 1;
231 enum dc_color_space color_space = COLOR_SPACE_SRGB;
232 enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
233 bool force_disable_cursor = false;
234 uint32_t is_2bit = 0;
235 uint32_t alpha_plane_enable = 0;
236 uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
237 uint32_t realpha_en = 0, realpha_ablnd_en = 0;
238 struct out_csc_color_matrix tbl_entry;
239 int i;
240
241 REG_SET_2(FORMAT_CONTROL, 0,
242 CNVC_BYPASS, 0,
243 FORMAT_EXPANSION_MODE, mode);
244
245 REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0);
246 REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0);
247 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0);
248 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0);
249
250 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0);
251 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1);
252 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2);
253
254 switch (format) {
255 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
256 pixel_format = 1;
257 break;
258 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
259 pixel_format = 3;
260 alpha_en = 0;
261 break;
262 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
263 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
264 pixel_format = 8;
265 break;
266 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
267 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
268 pixel_format = 10;
269 is_2bit = 1;
270 break;
271 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
272 force_disable_cursor = false;
273 pixel_format = 65;
274 color_space = COLOR_SPACE_YCBCR709;
275 select = INPUT_CSC_SELECT_ICSC;
276 break;
277 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
278 force_disable_cursor = true;
279 pixel_format = 64;
280 color_space = COLOR_SPACE_YCBCR709;
281 select = INPUT_CSC_SELECT_ICSC;
282 break;
283 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
284 force_disable_cursor = true;
285 pixel_format = 67;
286 color_space = COLOR_SPACE_YCBCR709;
287 select = INPUT_CSC_SELECT_ICSC;
288 break;
289 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
290 force_disable_cursor = true;
291 pixel_format = 66;
292 color_space = COLOR_SPACE_YCBCR709;
293 select = INPUT_CSC_SELECT_ICSC;
294 break;
295 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
296 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
297 pixel_format = 26; /* ARGB16161616_UNORM */
298 break;
299 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
300 pixel_format = 24;
301 break;
302 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
303 pixel_format = 25;
304 break;
305 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
306 pixel_format = 12;
307 color_space = COLOR_SPACE_YCBCR709;
308 select = INPUT_CSC_SELECT_ICSC;
309 break;
310 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
311 pixel_format = 112;
312 alpha_en = 0;
313 break;
314 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
315 pixel_format = 113;
316 alpha_en = 0;
317 break;
318 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
319 pixel_format = 114;
320 color_space = COLOR_SPACE_YCBCR709;
321 select = INPUT_CSC_SELECT_ICSC;
322 is_2bit = 1;
323 break;
324 case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
325 pixel_format = 115;
326 color_space = COLOR_SPACE_YCBCR709;
327 select = INPUT_CSC_SELECT_ICSC;
328 is_2bit = 1;
329 break;
330 case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
331 pixel_format = 116;
332 alpha_plane_enable = 0;
333 break;
334 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
335 pixel_format = 116;
336 alpha_plane_enable = 1;
337 break;
338 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
339 pixel_format = 118;
340 alpha_en = 0;
341 break;
342 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
343 pixel_format = 119;
344 alpha_en = 0;
345 break;
346 default:
347 break;
348 }
349
350 /* Set default color space based on format if none is given. */
351 color_space = input_color_space ? input_color_space : color_space;
352
353 if (is_2bit == 1 && alpha_2bit_lut != NULL) {
354 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0);
355 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
356 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2);
357 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
358 }
359
360 REG_SET_2(CNVC_SURFACE_PIXEL_FORMAT, 0,
361 CNVC_SURFACE_PIXEL_FORMAT, pixel_format,
362 CNVC_ALPHA_PLANE_ENABLE, alpha_plane_enable);
363 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
364
365 REG_SET_2(PRE_DEALPHA, 0,
366 PRE_DEALPHA_EN, dealpha_en,
367 PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
368 REG_SET_2(PRE_REALPHA, 0,
369 PRE_REALPHA_EN, realpha_en,
370 PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
371
372 /* If input adjustment exists, program the ICSC with those values. */
373 if (input_csc_color_matrix.enable_adjustment == true) {
374 for (i = 0; i < 12; i++)
375 tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
376
377 tbl_entry.color_space = input_color_space;
378
379 if (dpp3_should_bypass_post_csc_for_colorspace(color_space))
380 select = INPUT_CSC_SELECT_BYPASS;
381 else
382 select = INPUT_CSC_SELECT_ICSC;
383
384 dpp3_program_post_csc(dpp_base, color_space, select,
385 &tbl_entry);
386 } else {
387 dpp3_program_post_csc(dpp_base, color_space, select, NULL);
388 }
389
390 if (force_disable_cursor) {
391 REG_UPDATE(CURSOR_CONTROL,
392 CURSOR_ENABLE, 0);
393 REG_UPDATE(CURSOR0_CONTROL,
394 CUR0_ENABLE, 0);
395 }
396 }
397
398 #define IDENTITY_RATIO(ratio) (dc_fixpt_u3d19(ratio) == (1 << 19))
399
dpp3_set_cursor_attributes(struct dpp * dpp_base,struct dc_cursor_attributes * cursor_attributes)400 void dpp3_set_cursor_attributes(
401 struct dpp *dpp_base,
402 struct dc_cursor_attributes *cursor_attributes)
403 {
404 enum dc_cursor_color_format color_format = cursor_attributes->color_format;
405 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
406 int cur_rom_en = 0;
407
408 if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
409 color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
410 if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) {
411 cur_rom_en = 1;
412 }
413 }
414
415 if (!dpp_base->cursor_offload)
416 REG_UPDATE_3(CURSOR0_CONTROL,
417 CUR0_MODE, color_format,
418 CUR0_EXPANSION_MODE, 0,
419 CUR0_ROM_EN, cur_rom_en);
420
421 if (color_format == CURSOR_MODE_MONO) {
422 /* todo: clarify what to program these to */
423
424 if (!dpp_base->cursor_offload) {
425 REG_UPDATE(CURSOR0_COLOR0,
426 CUR0_COLOR0, 0x00000000);
427 REG_UPDATE(CURSOR0_COLOR1,
428 CUR0_COLOR1, 0xFFFFFFFF);
429 }
430 }
431
432 dpp_base->att.cur0_ctl.bits.expansion_mode = 0;
433 dpp_base->att.cur0_ctl.bits.cur0_rom_en = cur_rom_en;
434 dpp_base->att.cur0_ctl.bits.mode = color_format;
435 }
436
437
dpp3_get_optimal_number_of_taps(struct dpp * dpp,struct scaler_data * scl_data,const struct scaling_taps * in_taps)438 bool dpp3_get_optimal_number_of_taps(
439 struct dpp *dpp,
440 struct scaler_data *scl_data,
441 const struct scaling_taps *in_taps)
442 {
443 int num_part_y, num_part_c;
444 int max_taps_y, max_taps_c;
445 int min_taps_y, min_taps_c;
446 enum lb_memory_config lb_config;
447
448 /*
449 * Set default taps if none are provided
450 * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling
451 * taps = 4 for upscaling
452 */
453 if (in_taps->h_taps == 0) {
454 if (dc_fixpt_ceil(scl_data->ratios.horz) > 1)
455 scl_data->taps.h_taps = min(2 * dc_fixpt_ceil(scl_data->ratios.horz), 8);
456 else
457 scl_data->taps.h_taps = 4;
458 } else
459 scl_data->taps.h_taps = in_taps->h_taps;
460 if (in_taps->v_taps == 0) {
461 if (dc_fixpt_ceil(scl_data->ratios.vert) > 1)
462 scl_data->taps.v_taps = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert, 2)), 8);
463 else
464 scl_data->taps.v_taps = 4;
465 } else
466 scl_data->taps.v_taps = in_taps->v_taps;
467 if (in_taps->v_taps_c == 0) {
468 if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 1)
469 scl_data->taps.v_taps_c = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert_c, 2)), 8);
470 else
471 scl_data->taps.v_taps_c = 4;
472 } else
473 scl_data->taps.v_taps_c = in_taps->v_taps_c;
474 if (in_taps->h_taps_c == 0) {
475 if (dc_fixpt_ceil(scl_data->ratios.horz_c) > 1)
476 scl_data->taps.h_taps_c = min(2 * dc_fixpt_ceil(scl_data->ratios.horz_c), 8);
477 else
478 scl_data->taps.h_taps_c = 4;
479 } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
480 /* Only 1 and even h_taps_c are supported by hw */
481 scl_data->taps.h_taps_c = in_taps->h_taps_c - 1;
482 else
483 scl_data->taps.h_taps_c = in_taps->h_taps_c;
484
485 // Avoid null data in the scl data with this early return, proceed non-adaptive calcualtion first
486 if (scl_data->viewport.width > scl_data->h_active &&
487 dpp->ctx->dc->debug.max_downscale_src_width != 0 &&
488 scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width)
489 return false;
490
491 /*Ensure we can support the requested number of vtaps*/
492 min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert);
493 min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
494
495 /* Use LB_MEMORY_CONFIG_3 for 4:2:0 */
496 if ((scl_data->format == PIXEL_FORMAT_420BPP8) || (scl_data->format == PIXEL_FORMAT_420BPP10))
497 lb_config = LB_MEMORY_CONFIG_3;
498 else
499 lb_config = LB_MEMORY_CONFIG_0;
500
501 dpp->caps->dscl_calc_lb_num_partitions(
502 scl_data, lb_config, &num_part_y, &num_part_c);
503
504 /* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */
505 if (dc_fixpt_ceil(scl_data->ratios.vert) > 2)
506 max_taps_y = num_part_y - (dc_fixpt_ceil(scl_data->ratios.vert) - 2);
507 else
508 max_taps_y = num_part_y;
509
510 if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 2)
511 max_taps_c = num_part_c - (dc_fixpt_ceil(scl_data->ratios.vert_c) - 2);
512 else
513 max_taps_c = num_part_c;
514
515 if (max_taps_y < min_taps_y)
516 return false;
517 else if (max_taps_c < min_taps_c)
518 return false;
519
520 if (scl_data->taps.v_taps > max_taps_y)
521 scl_data->taps.v_taps = max_taps_y;
522
523 if (scl_data->taps.v_taps_c > max_taps_c)
524 scl_data->taps.v_taps_c = max_taps_c;
525
526 if (!dpp->ctx->dc->debug.always_scale) {
527 if (IDENTITY_RATIO(scl_data->ratios.horz))
528 scl_data->taps.h_taps = 1;
529 if (IDENTITY_RATIO(scl_data->ratios.vert))
530 scl_data->taps.v_taps = 1;
531 if (IDENTITY_RATIO(scl_data->ratios.horz_c))
532 scl_data->taps.h_taps_c = 1;
533 if (IDENTITY_RATIO(scl_data->ratios.vert_c))
534 scl_data->taps.v_taps_c = 1;
535 }
536
537 return true;
538 }
539
dpp3_deferred_update(struct dpp * dpp_base)540 static void dpp3_deferred_update(struct dpp *dpp_base)
541 {
542 int bypass_state;
543 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
544
545 if (dpp_base->deferred_reg_writes.bits.disable_dscl) {
546 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
547 dpp_base->deferred_reg_writes.bits.disable_dscl = false;
548 }
549
550 if (dpp_base->deferred_reg_writes.bits.disable_gamcor) {
551 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state);
552 if (bypass_state == 0) { // only program if bypass was latched
553 REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3);
554 } else
555 ASSERT(0); // LUT select was updated again before vupdate
556 dpp_base->deferred_reg_writes.bits.disable_gamcor = false;
557 }
558
559 if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
560 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
561 if (bypass_state == 0) { // only program if bypass was latched
562 REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3);
563 } else
564 ASSERT(0); // LUT select was updated again before vupdate
565 dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false;
566 }
567
568 if (dpp_base->deferred_reg_writes.bits.disable_3dlut) {
569 REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state);
570 if (bypass_state == 0) { // only program if bypass was latched
571 REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3);
572 } else
573 ASSERT(0); // LUT select was updated again before vupdate
574 dpp_base->deferred_reg_writes.bits.disable_3dlut = false;
575 }
576
577 if (dpp_base->deferred_reg_writes.bits.disable_shaper) {
578 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state);
579 if (bypass_state == 0) { // only program if bypass was latched
580 REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3);
581 } else
582 ASSERT(0); // LUT select was updated again before vupdate
583 dpp_base->deferred_reg_writes.bits.disable_shaper = false;
584 }
585 }
586
dpp3_power_on_blnd_lut(struct dpp * dpp_base,bool power_on)587 static void dpp3_power_on_blnd_lut(
588 struct dpp *dpp_base,
589 bool power_on)
590 {
591 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
592
593 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
594 if (power_on) {
595 REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);
596 REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
597 } else {
598 dpp_base->ctx->dc->optimized_required = true;
599 dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
600 }
601 }
602 }
603
dpp3_power_on_hdr3dlut(struct dpp * dpp_base,bool power_on)604 static void dpp3_power_on_hdr3dlut(
605 struct dpp *dpp_base,
606 bool power_on)
607 {
608 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
609
610 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
611 if (power_on) {
612 REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);
613 REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
614 } else {
615 dpp_base->ctx->dc->optimized_required = true;
616 dpp_base->deferred_reg_writes.bits.disable_3dlut = true;
617 }
618 }
619 }
620
dpp3_power_on_shaper(struct dpp * dpp_base,bool power_on)621 static void dpp3_power_on_shaper(
622 struct dpp *dpp_base,
623 bool power_on)
624 {
625 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
626
627 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
628 if (power_on) {
629 REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);
630 REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
631 } else {
632 dpp_base->ctx->dc->optimized_required = true;
633 dpp_base->deferred_reg_writes.bits.disable_shaper = true;
634 }
635 }
636 }
637
dpp3_configure_blnd_lut(struct dpp * dpp_base,bool is_ram_a)638 static void dpp3_configure_blnd_lut(
639 struct dpp *dpp_base,
640 bool is_ram_a)
641 {
642 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
643
644 REG_UPDATE_2(CM_BLNDGAM_LUT_CONTROL,
645 CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 7,
646 CM_BLNDGAM_LUT_HOST_SEL, is_ram_a == true ? 0 : 1);
647
648 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
649 }
650
dpp3_program_blnd_pwl(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)651 static void dpp3_program_blnd_pwl(
652 struct dpp *dpp_base,
653 const struct pwl_result_data *rgb,
654 uint32_t num)
655 {
656 uint32_t i;
657 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
658 uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
659 uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
660 uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
661
662 if (is_rgb_equal(rgb, num)) {
663 for (i = 0 ; i < num; i++)
664 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
665 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
666 } else {
667 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
668 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 4);
669 for (i = 0 ; i < num; i++)
670 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
671 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
672
673 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
674 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 2);
675 for (i = 0 ; i < num; i++)
676 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
677 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_green);
678
679 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
680 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 1);
681 for (i = 0 ; i < num; i++)
682 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
683 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_blue);
684 }
685 }
686
dcn3_dpp_cm_get_reg_field(struct dcn3_dpp * dpp,struct dcn3_xfer_func_reg * reg)687 static void dcn3_dpp_cm_get_reg_field(
688 struct dcn3_dpp *dpp,
689 struct dcn3_xfer_func_reg *reg)
690 {
691 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
692 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
693 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
694 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
695 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
696 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
697 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
698 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
699
700 reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
701 reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
702 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
703 reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
704 reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
705 reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
706 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
707 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
708 reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
709 reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
710 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
711 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
712 }
713
714 /*program blnd lut RAM A*/
dpp3_program_blnd_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)715 static void dpp3_program_blnd_luta_settings(
716 struct dpp *dpp_base,
717 const struct pwl_params *params)
718 {
719 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
720 struct dcn3_xfer_func_reg gam_regs;
721
722 dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
723
724 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
725 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
726 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
727 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B);
728 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G);
729 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R);
730 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
731 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
732 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
733 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
734 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
735 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
736 gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
737 gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
738
739 cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
740 }
741
742 /*program blnd lut RAM B*/
dpp3_program_blnd_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)743 static void dpp3_program_blnd_lutb_settings(
744 struct dpp *dpp_base,
745 const struct pwl_params *params)
746 {
747 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
748 struct dcn3_xfer_func_reg gam_regs;
749
750 dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
751
752 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
753 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
754 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
755 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B);
756 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G);
757 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R);
758 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
759 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
760 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
761 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
762 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
763 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
764 gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
765 gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
766
767 cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
768 }
769
dpp3_get_blndgam_current(struct dpp * dpp_base)770 static enum dc_lut_mode dpp3_get_blndgam_current(struct dpp *dpp_base)
771 {
772 enum dc_lut_mode mode;
773 uint32_t mode_current = 0;
774 uint32_t in_use = 0;
775
776 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
777
778 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &mode_current);
779 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &in_use);
780
781 switch (mode_current) {
782 case 0:
783 case 1:
784 mode = LUT_BYPASS;
785 break;
786
787 case 2:
788 if (in_use == 0)
789 mode = LUT_RAM_A;
790 else
791 mode = LUT_RAM_B;
792 break;
793 default:
794 mode = LUT_BYPASS;
795 break;
796 }
797
798 return mode;
799 }
800
dpp3_program_blnd_lut(struct dpp * dpp_base,const struct pwl_params * params)801 static bool dpp3_program_blnd_lut(struct dpp *dpp_base,
802 const struct pwl_params *params)
803 {
804 enum dc_lut_mode current_mode;
805 enum dc_lut_mode next_mode;
806 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
807
808 if (params == NULL) {
809 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_MODE, 0);
810 dpp3_power_on_blnd_lut(dpp_base, false);
811 return false;
812 }
813
814 current_mode = dpp3_get_blndgam_current(dpp_base);
815 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_B)
816 next_mode = LUT_RAM_A;
817 else
818 next_mode = LUT_RAM_B;
819
820 dpp3_power_on_blnd_lut(dpp_base, true);
821 dpp3_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
822
823 if (next_mode == LUT_RAM_A)
824 dpp3_program_blnd_luta_settings(dpp_base, params);
825 else
826 dpp3_program_blnd_lutb_settings(dpp_base, params);
827
828 dpp3_program_blnd_pwl(
829 dpp_base, params->rgb_resulted, params->hw_points_num);
830
831 REG_UPDATE_2(CM_BLNDGAM_CONTROL,
832 CM_BLNDGAM_MODE, 2,
833 CM_BLNDGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1);
834
835 return true;
836 }
837
838
dpp3_program_shaper_lut(struct dpp * dpp_base,const struct pwl_result_data * rgb,uint32_t num)839 static void dpp3_program_shaper_lut(
840 struct dpp *dpp_base,
841 const struct pwl_result_data *rgb,
842 uint32_t num)
843 {
844 uint32_t i, red, green, blue;
845 uint32_t red_delta, green_delta, blue_delta;
846 uint32_t red_value, green_value, blue_value;
847
848 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
849
850 for (i = 0 ; i < num; i++) {
851
852 red = rgb[i].red_reg;
853 green = rgb[i].green_reg;
854 blue = rgb[i].blue_reg;
855
856 red_delta = rgb[i].delta_red_reg;
857 green_delta = rgb[i].delta_green_reg;
858 blue_delta = rgb[i].delta_blue_reg;
859
860 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
861 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
862 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
863
864 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
865 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
866 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
867 }
868
869 }
870
dpp3_get_shaper_current(struct dpp * dpp_base)871 static enum dc_lut_mode dpp3_get_shaper_current(struct dpp *dpp_base)
872 {
873 enum dc_lut_mode mode;
874 uint32_t state_mode;
875 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
876
877 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &state_mode);
878
879 switch (state_mode) {
880 case 0:
881 mode = LUT_BYPASS;
882 break;
883 case 1:
884 mode = LUT_RAM_A;
885 break;
886 case 2:
887 mode = LUT_RAM_B;
888 break;
889 default:
890 mode = LUT_BYPASS;
891 break;
892 }
893
894 return mode;
895 }
896
dpp3_configure_shaper_lut(struct dpp * dpp_base,bool is_ram_a)897 static void dpp3_configure_shaper_lut(
898 struct dpp *dpp_base,
899 bool is_ram_a)
900 {
901 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
902
903 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
904 CM_SHAPER_LUT_WRITE_EN_MASK, 7);
905 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
906 CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
907 REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
908 }
909
910 /*program shaper RAM A*/
911
dpp3_program_shaper_luta_settings(struct dpp * dpp_base,const struct pwl_params * params)912 static void dpp3_program_shaper_luta_settings(
913 struct dpp *dpp_base,
914 const struct pwl_params *params)
915 {
916 const struct gamma_curve *curve;
917 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
918
919 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
920 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
921 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
922 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
923 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
924 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
925 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
926 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
927 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
928
929 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
930 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
931 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
932
933 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
934 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
935 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
936
937 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
938 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
939 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
940
941 curve = params->arr_curve_points;
942 REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
943 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
944 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
945 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
946 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
947
948 curve += 2;
949 REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
950 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
951 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
952 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
953 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
954
955 curve += 2;
956 REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
957 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
958 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
959 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
960 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
961
962 curve += 2;
963 REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
964 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
965 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
966 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
967 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
968
969 curve += 2;
970 REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
971 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
972 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
973 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
974 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
975
976 curve += 2;
977 REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
978 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
979 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
980 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
981 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
982
983 curve += 2;
984 REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
985 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
986 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
987 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
988 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
989
990 curve += 2;
991 REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
992 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
993 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
994 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
995 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
996
997 curve += 2;
998 REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
999 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
1000 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
1001 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
1002 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
1003
1004 curve += 2;
1005 REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
1006 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
1007 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
1008 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
1009 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
1010
1011 curve += 2;
1012 REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
1013 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
1014 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
1015 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
1016 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
1017
1018 curve += 2;
1019 REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
1020 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
1021 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
1022 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
1023 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
1024
1025 curve += 2;
1026 REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
1027 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
1028 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
1029 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
1030 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
1031
1032 curve += 2;
1033 REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
1034 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
1035 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
1036 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
1037 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
1038
1039 curve += 2;
1040 REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
1041 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
1042 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
1043 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
1044 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
1045
1046 curve += 2;
1047 REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
1048 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
1049 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
1050 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
1051 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
1052
1053 curve += 2;
1054 REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
1055 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
1056 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
1057 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
1058 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
1059 }
1060
1061 /*program shaper RAM B*/
dpp3_program_shaper_lutb_settings(struct dpp * dpp_base,const struct pwl_params * params)1062 static void dpp3_program_shaper_lutb_settings(
1063 struct dpp *dpp_base,
1064 const struct pwl_params *params)
1065 {
1066 const struct gamma_curve *curve;
1067 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1068
1069 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
1070 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
1071 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
1072 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
1073 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
1074 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
1075 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
1076 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
1077 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
1078
1079 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
1080 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
1081 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
1082
1083 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
1084 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
1085 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
1086
1087 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
1088 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
1089 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
1090
1091 curve = params->arr_curve_points;
1092 REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
1093 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
1094 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
1095 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
1096 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
1097
1098 curve += 2;
1099 REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
1100 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
1101 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
1102 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
1103 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
1104
1105 curve += 2;
1106 REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
1107 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
1108 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
1109 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
1110 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
1111
1112 curve += 2;
1113 REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
1114 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
1115 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
1116 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
1117 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
1118
1119 curve += 2;
1120 REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
1121 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
1122 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
1123 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
1124 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
1125
1126 curve += 2;
1127 REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
1128 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
1129 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
1130 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
1131 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
1132
1133 curve += 2;
1134 REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
1135 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
1136 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
1137 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
1138 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
1139
1140 curve += 2;
1141 REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
1142 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
1143 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
1144 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
1145 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
1146
1147 curve += 2;
1148 REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
1149 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
1150 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
1151 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
1152 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
1153
1154 curve += 2;
1155 REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
1156 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
1157 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
1158 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
1159 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
1160
1161 curve += 2;
1162 REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
1163 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
1164 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
1165 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
1166 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
1167
1168 curve += 2;
1169 REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
1170 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
1171 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
1172 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
1173 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
1174
1175 curve += 2;
1176 REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
1177 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
1178 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
1179 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
1180 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
1181
1182 curve += 2;
1183 REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
1184 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
1185 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
1186 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
1187 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
1188
1189 curve += 2;
1190 REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
1191 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
1192 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
1193 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
1194 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
1195
1196 curve += 2;
1197 REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
1198 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
1199 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
1200 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
1201 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
1202
1203 curve += 2;
1204 REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
1205 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
1206 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
1207 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
1208 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
1209
1210 }
1211
1212
dpp3_program_shaper(struct dpp * dpp_base,const struct pwl_params * params)1213 static bool dpp3_program_shaper(struct dpp *dpp_base,
1214 const struct pwl_params *params)
1215 {
1216 enum dc_lut_mode current_mode;
1217 enum dc_lut_mode next_mode;
1218
1219 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1220
1221 if (params == NULL) {
1222 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
1223 dpp3_power_on_shaper(dpp_base, false);
1224 return false;
1225 }
1226
1227 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1228 dpp3_power_on_shaper(dpp_base, true);
1229
1230 current_mode = dpp3_get_shaper_current(dpp_base);
1231
1232 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
1233 next_mode = LUT_RAM_B;
1234 else
1235 next_mode = LUT_RAM_A;
1236
1237 dpp3_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
1238
1239 if (next_mode == LUT_RAM_A)
1240 dpp3_program_shaper_luta_settings(dpp_base, params);
1241 else
1242 dpp3_program_shaper_lutb_settings(dpp_base, params);
1243
1244 dpp3_program_shaper_lut(
1245 dpp_base, params->rgb_resulted, params->hw_points_num);
1246
1247 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
1248
1249 return true;
1250
1251 }
1252
get3dlut_config(struct dpp * dpp_base,bool * is_17x17x17,bool * is_12bits_color_channel)1253 static enum dc_lut_mode get3dlut_config(
1254 struct dpp *dpp_base,
1255 bool *is_17x17x17,
1256 bool *is_12bits_color_channel)
1257 {
1258 uint32_t i_mode, i_enable_10bits, lut_size;
1259 enum dc_lut_mode mode;
1260 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1261
1262 REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
1263 CM_3DLUT_30BIT_EN, &i_enable_10bits);
1264 REG_GET(CM_3DLUT_MODE,
1265 CM_3DLUT_MODE_CURRENT, &i_mode);
1266
1267 switch (i_mode) {
1268 case 0:
1269 mode = LUT_BYPASS;
1270 break;
1271 case 1:
1272 mode = LUT_RAM_A;
1273 break;
1274 case 2:
1275 mode = LUT_RAM_B;
1276 break;
1277 default:
1278 mode = LUT_BYPASS;
1279 break;
1280 }
1281 if (i_enable_10bits > 0)
1282 *is_12bits_color_channel = false;
1283 else
1284 *is_12bits_color_channel = true;
1285
1286 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
1287
1288 if (lut_size == 0)
1289 *is_17x17x17 = true;
1290 else
1291 *is_17x17x17 = false;
1292
1293 return mode;
1294 }
1295 /*
1296 * select ramA or ramB, or bypass
1297 * select color channel size 10 or 12 bits
1298 * select 3dlut size 17x17x17 or 9x9x9
1299 */
dpp3_set_3dlut_mode(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits,bool is_lut_size17x17x17)1300 static void dpp3_set_3dlut_mode(
1301 struct dpp *dpp_base,
1302 enum dc_lut_mode mode,
1303 bool is_color_channel_12bits,
1304 bool is_lut_size17x17x17)
1305 {
1306 uint32_t lut_mode;
1307 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1308
1309 if (mode == LUT_BYPASS)
1310 lut_mode = 0;
1311 else if (mode == LUT_RAM_A)
1312 lut_mode = 1;
1313 else
1314 lut_mode = 2;
1315
1316 REG_UPDATE_2(CM_3DLUT_MODE,
1317 CM_3DLUT_MODE, lut_mode,
1318 CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
1319 }
1320
dpp3_select_3dlut_ram(struct dpp * dpp_base,enum dc_lut_mode mode,bool is_color_channel_12bits)1321 static void dpp3_select_3dlut_ram(
1322 struct dpp *dpp_base,
1323 enum dc_lut_mode mode,
1324 bool is_color_channel_12bits)
1325 {
1326 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1327
1328 REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
1329 CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
1330 CM_3DLUT_30BIT_EN,
1331 is_color_channel_12bits == true ? 0:1);
1332 }
1333
1334
1335
dpp3_set3dlut_ram12(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)1336 static void dpp3_set3dlut_ram12(
1337 struct dpp *dpp_base,
1338 const struct dc_rgb *lut,
1339 uint32_t entries)
1340 {
1341 uint32_t i, red, green, blue, red1, green1, blue1;
1342 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1343
1344 for (i = 0 ; i < entries; i += 2) {
1345 red = lut[i].red<<4;
1346 green = lut[i].green<<4;
1347 blue = lut[i].blue<<4;
1348 red1 = lut[i+1].red<<4;
1349 green1 = lut[i+1].green<<4;
1350 blue1 = lut[i+1].blue<<4;
1351
1352 REG_SET_2(CM_3DLUT_DATA, 0,
1353 CM_3DLUT_DATA0, red,
1354 CM_3DLUT_DATA1, red1);
1355
1356 REG_SET_2(CM_3DLUT_DATA, 0,
1357 CM_3DLUT_DATA0, green,
1358 CM_3DLUT_DATA1, green1);
1359
1360 REG_SET_2(CM_3DLUT_DATA, 0,
1361 CM_3DLUT_DATA0, blue,
1362 CM_3DLUT_DATA1, blue1);
1363
1364 }
1365 }
1366
1367 /*
1368 * load selected lut with 10 bits color channels
1369 */
dpp3_set3dlut_ram10(struct dpp * dpp_base,const struct dc_rgb * lut,uint32_t entries)1370 static void dpp3_set3dlut_ram10(
1371 struct dpp *dpp_base,
1372 const struct dc_rgb *lut,
1373 uint32_t entries)
1374 {
1375 uint32_t i, red, green, blue, value;
1376 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1377
1378 for (i = 0; i < entries; i++) {
1379 red = lut[i].red;
1380 green = lut[i].green;
1381 blue = lut[i].blue;
1382
1383 value = (red<<20) | (green<<10) | blue;
1384
1385 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1386 }
1387
1388 }
1389
1390
dpp3_select_3dlut_ram_mask(struct dpp * dpp_base,uint32_t ram_selection_mask)1391 static void dpp3_select_3dlut_ram_mask(
1392 struct dpp *dpp_base,
1393 uint32_t ram_selection_mask)
1394 {
1395 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
1396
1397 REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1398 ram_selection_mask);
1399 REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1400 }
1401
dpp3_program_3dlut(struct dpp * dpp_base,const struct tetrahedral_params * params)1402 static bool dpp3_program_3dlut(struct dpp *dpp_base,
1403 const struct tetrahedral_params *params)
1404 {
1405 enum dc_lut_mode mode;
1406 bool is_17x17x17;
1407 bool is_12bits_color_channel;
1408 const struct dc_rgb *lut0;
1409 const struct dc_rgb *lut1;
1410 const struct dc_rgb *lut2;
1411 const struct dc_rgb *lut3;
1412 int lut_size0;
1413 int lut_size;
1414
1415 if (params == NULL) {
1416 dpp3_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1417 dpp3_power_on_hdr3dlut(dpp_base, false);
1418 return false;
1419 }
1420
1421 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
1422 dpp3_power_on_hdr3dlut(dpp_base, true);
1423
1424 mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1425
1426 if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1427 mode = LUT_RAM_A;
1428 else
1429 mode = LUT_RAM_B;
1430
1431 is_17x17x17 = !params->use_tetrahedral_9;
1432 is_12bits_color_channel = params->use_12bits;
1433 if (is_17x17x17) {
1434 lut0 = params->tetrahedral_17.lut0;
1435 lut1 = params->tetrahedral_17.lut1;
1436 lut2 = params->tetrahedral_17.lut2;
1437 lut3 = params->tetrahedral_17.lut3;
1438 lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1439 sizeof(params->tetrahedral_17.lut0[0]);
1440 lut_size = sizeof(params->tetrahedral_17.lut1)/
1441 sizeof(params->tetrahedral_17.lut1[0]);
1442 } else {
1443 lut0 = params->tetrahedral_9.lut0;
1444 lut1 = params->tetrahedral_9.lut1;
1445 lut2 = params->tetrahedral_9.lut2;
1446 lut3 = params->tetrahedral_9.lut3;
1447 lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1448 sizeof(params->tetrahedral_9.lut0[0]);
1449 lut_size = sizeof(params->tetrahedral_9.lut1)/
1450 sizeof(params->tetrahedral_9.lut1[0]);
1451 }
1452
1453 dpp3_select_3dlut_ram(dpp_base, mode,
1454 is_12bits_color_channel);
1455 dpp3_select_3dlut_ram_mask(dpp_base, 0x1);
1456 if (is_12bits_color_channel)
1457 dpp3_set3dlut_ram12(dpp_base, lut0, lut_size0);
1458 else
1459 dpp3_set3dlut_ram10(dpp_base, lut0, lut_size0);
1460
1461 dpp3_select_3dlut_ram_mask(dpp_base, 0x2);
1462 if (is_12bits_color_channel)
1463 dpp3_set3dlut_ram12(dpp_base, lut1, lut_size);
1464 else
1465 dpp3_set3dlut_ram10(dpp_base, lut1, lut_size);
1466
1467 dpp3_select_3dlut_ram_mask(dpp_base, 0x4);
1468 if (is_12bits_color_channel)
1469 dpp3_set3dlut_ram12(dpp_base, lut2, lut_size);
1470 else
1471 dpp3_set3dlut_ram10(dpp_base, lut2, lut_size);
1472
1473 dpp3_select_3dlut_ram_mask(dpp_base, 0x8);
1474 if (is_12bits_color_channel)
1475 dpp3_set3dlut_ram12(dpp_base, lut3, lut_size);
1476 else
1477 dpp3_set3dlut_ram10(dpp_base, lut3, lut_size);
1478
1479
1480 dpp3_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1481 is_17x17x17);
1482
1483 return true;
1484 }
1485 static struct dpp_funcs dcn30_dpp_funcs = {
1486 .dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
1487 .dpp_read_state = dpp30_read_state,
1488 .dpp_reset = dpp_reset,
1489 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
1490 .dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps,
1491 .dpp_set_gamut_remap = dpp3_cm_set_gamut_remap,
1492 .dpp_set_csc_adjustment = NULL,
1493 .dpp_set_csc_default = NULL,
1494 .dpp_program_regamma_pwl = NULL,
1495 .dpp_set_pre_degam = dpp3_set_pre_degam,
1496 .dpp_program_input_lut = NULL,
1497 .dpp_full_bypass = dpp1_full_bypass,
1498 .dpp_setup = dpp3_cnv_setup,
1499 .dpp_program_degamma_pwl = NULL,
1500 .dpp_program_cm_dealpha = dpp3_program_cm_dealpha,
1501 .dpp_program_cm_bias = dpp3_program_cm_bias,
1502 .dpp_program_blnd_lut = dpp3_program_blnd_lut,
1503 .dpp_program_shaper_lut = dpp3_program_shaper,
1504 .dpp_program_3dlut = dpp3_program_3dlut,
1505 .dpp_deferred_update = dpp3_deferred_update,
1506 .dpp_program_bias_and_scale = NULL,
1507 .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer,
1508 .set_cursor_attributes = dpp3_set_cursor_attributes,
1509 .set_cursor_position = dpp1_set_cursor_position,
1510 .set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes,
1511 .dpp_dppclk_control = dpp1_dppclk_control,
1512 .dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier,
1513 .dpp_get_gamut_remap = dpp3_cm_get_gamut_remap,
1514 .dpp_force_disable_cursor = dpp_force_disable_cursor,
1515 };
1516
1517
1518 static struct dpp_caps dcn30_dpp_cap = {
1519 .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
1520 .dscl_calc_lb_num_partitions = dscl2_calc_lb_num_partitions,
1521 };
1522
dpp3_construct(struct dcn3_dpp * dpp,struct dc_context * ctx,uint32_t inst,const struct dcn3_dpp_registers * tf_regs,const struct dcn3_dpp_shift * tf_shift,const struct dcn3_dpp_mask * tf_mask)1523 bool dpp3_construct(
1524 struct dcn3_dpp *dpp,
1525 struct dc_context *ctx,
1526 uint32_t inst,
1527 const struct dcn3_dpp_registers *tf_regs,
1528 const struct dcn3_dpp_shift *tf_shift,
1529 const struct dcn3_dpp_mask *tf_mask)
1530 {
1531 dpp->base.ctx = ctx;
1532
1533 dpp->base.inst = inst;
1534 dpp->base.funcs = &dcn30_dpp_funcs;
1535 dpp->base.caps = &dcn30_dpp_cap;
1536
1537 dpp->tf_regs = tf_regs;
1538 dpp->tf_shift = tf_shift;
1539 dpp->tf_mask = tf_mask;
1540
1541 return true;
1542 }
1543
dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space)1544 bool dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space)
1545 {
1546 switch (dc_color_space) {
1547 case COLOR_SPACE_UNKNOWN:
1548 case COLOR_SPACE_SRGB:
1549 case COLOR_SPACE_XR_RGB:
1550 case COLOR_SPACE_SRGB_LIMITED:
1551 case COLOR_SPACE_MSREF_SCRGB:
1552 case COLOR_SPACE_2020_RGB_FULLRANGE:
1553 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
1554 return true;
1555 default:
1556 return false;
1557 }
1558 }
1559