Line data Source code
1 : /*
2 : * Copyright 2012-15 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 "dce110_transform_v.h"
28 : #include "basics/conversion.h"
29 :
30 : /* include DCE11 register header files */
31 : #include "dce/dce_11_0_d.h"
32 : #include "dce/dce_11_0_sh_mask.h"
33 : #include "dce/dce_11_0_enum.h"
34 :
35 : enum {
36 : OUTPUT_CSC_MATRIX_SIZE = 12
37 : };
38 :
39 : /* constrast:0 - 2.0, default 1.0 */
40 : #define UNDERLAY_CONTRAST_DEFAULT 100
41 : #define UNDERLAY_CONTRAST_MAX 200
42 : #define UNDERLAY_CONTRAST_MIN 0
43 : #define UNDERLAY_CONTRAST_STEP 1
44 : #define UNDERLAY_CONTRAST_DIVIDER 100
45 :
46 : /* Saturation: 0 - 2.0; default 1.0 */
47 : #define UNDERLAY_SATURATION_DEFAULT 100 /*1.00*/
48 : #define UNDERLAY_SATURATION_MIN 0
49 : #define UNDERLAY_SATURATION_MAX 200 /* 2.00 */
50 : #define UNDERLAY_SATURATION_STEP 1 /* 0.01 */
51 : /*actual max overlay saturation
52 : * value = UNDERLAY_SATURATION_MAX /UNDERLAY_SATURATION_DIVIDER
53 : */
54 :
55 : /* Hue */
56 : #define UNDERLAY_HUE_DEFAULT 0
57 : #define UNDERLAY_HUE_MIN -300
58 : #define UNDERLAY_HUE_MAX 300
59 : #define UNDERLAY_HUE_STEP 5
60 : #define UNDERLAY_HUE_DIVIDER 10 /* HW range: -30 ~ +30 */
61 : #define UNDERLAY_SATURATION_DIVIDER 100
62 :
63 : /* Brightness: in DAL usually -.25 ~ .25.
64 : * In MMD is -100 to +100 in 16-235 range; which when scaled to full range is
65 : * ~-116 to +116. When normalized this is about 0.4566.
66 : * With 100 divider this becomes 46, but we may use another for better precision
67 : * The ideal one is 100/219 ((100/255)*(255/219)),
68 : * i.e. min/max = +-100, divider = 219
69 : * default 0.0
70 : */
71 : #define UNDERLAY_BRIGHTNESS_DEFAULT 0
72 : #define UNDERLAY_BRIGHTNESS_MIN -46 /* ~116/255 */
73 : #define UNDERLAY_BRIGHTNESS_MAX 46
74 : #define UNDERLAY_BRIGHTNESS_STEP 1 /* .01 */
75 : #define UNDERLAY_BRIGHTNESS_DIVIDER 100
76 :
77 : static const struct out_csc_color_matrix global_color_matrix[] = {
78 : { COLOR_SPACE_SRGB,
79 : { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
80 : { COLOR_SPACE_SRGB_LIMITED,
81 : { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
82 : { COLOR_SPACE_YCBCR601,
83 : { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
84 : 0xF6B9, 0xE00, 0x1000} },
85 : { COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
86 : 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
87 : /* TODO: correct values below */
88 : { COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
89 : 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
90 : { COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
91 : 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
92 : };
93 :
94 : enum csc_color_mode {
95 : /* 00 - BITS2:0 Bypass */
96 : CSC_COLOR_MODE_GRAPHICS_BYPASS,
97 : /* 01 - hard coded coefficient TV RGB */
98 : CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
99 : /* 04 - programmable OUTPUT CSC coefficient */
100 : CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
101 : };
102 :
103 : enum grph_color_adjust_option {
104 : GRPH_COLOR_MATRIX_HW_DEFAULT = 1,
105 : GRPH_COLOR_MATRIX_SW
106 : };
107 :
108 0 : static void program_color_matrix_v(
109 : struct dce_transform *xfm_dce,
110 : const struct out_csc_color_matrix *tbl_entry,
111 : enum grph_color_adjust_option options)
112 : {
113 0 : struct dc_context *ctx = xfm_dce->base.ctx;
114 0 : uint32_t cntl_value = dm_read_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL);
115 0 : bool use_set_a = (get_reg_field_value(cntl_value,
116 : COL_MAN_OUTPUT_CSC_CONTROL,
117 : OUTPUT_CSC_MODE) != 4);
118 :
119 0 : set_reg_field_value(
120 : cntl_value,
121 : 0,
122 : COL_MAN_OUTPUT_CSC_CONTROL,
123 : OUTPUT_CSC_MODE);
124 :
125 0 : if (use_set_a) {
126 : {
127 0 : uint32_t value = 0;
128 0 : uint32_t addr = mmOUTPUT_CSC_C11_C12_A;
129 : /* fixed S2.13 format */
130 0 : set_reg_field_value(
131 : value,
132 : tbl_entry->regval[0],
133 : OUTPUT_CSC_C11_C12_A,
134 : OUTPUT_CSC_C11_A);
135 :
136 0 : set_reg_field_value(
137 : value,
138 : tbl_entry->regval[1],
139 : OUTPUT_CSC_C11_C12_A,
140 : OUTPUT_CSC_C12_A);
141 :
142 0 : dm_write_reg(ctx, addr, value);
143 : }
144 : {
145 0 : uint32_t value = 0;
146 0 : uint32_t addr = mmOUTPUT_CSC_C13_C14_A;
147 : /* fixed S2.13 format */
148 0 : set_reg_field_value(
149 : value,
150 : tbl_entry->regval[2],
151 : OUTPUT_CSC_C13_C14_A,
152 : OUTPUT_CSC_C13_A);
153 : /* fixed S0.13 format */
154 0 : set_reg_field_value(
155 : value,
156 : tbl_entry->regval[3],
157 : OUTPUT_CSC_C13_C14_A,
158 : OUTPUT_CSC_C14_A);
159 :
160 0 : dm_write_reg(ctx, addr, value);
161 : }
162 : {
163 0 : uint32_t value = 0;
164 0 : uint32_t addr = mmOUTPUT_CSC_C21_C22_A;
165 : /* fixed S2.13 format */
166 0 : set_reg_field_value(
167 : value,
168 : tbl_entry->regval[4],
169 : OUTPUT_CSC_C21_C22_A,
170 : OUTPUT_CSC_C21_A);
171 : /* fixed S2.13 format */
172 0 : set_reg_field_value(
173 : value,
174 : tbl_entry->regval[5],
175 : OUTPUT_CSC_C21_C22_A,
176 : OUTPUT_CSC_C22_A);
177 :
178 0 : dm_write_reg(ctx, addr, value);
179 : }
180 : {
181 0 : uint32_t value = 0;
182 0 : uint32_t addr = mmOUTPUT_CSC_C23_C24_A;
183 : /* fixed S2.13 format */
184 0 : set_reg_field_value(
185 : value,
186 : tbl_entry->regval[6],
187 : OUTPUT_CSC_C23_C24_A,
188 : OUTPUT_CSC_C23_A);
189 : /* fixed S0.13 format */
190 0 : set_reg_field_value(
191 : value,
192 : tbl_entry->regval[7],
193 : OUTPUT_CSC_C23_C24_A,
194 : OUTPUT_CSC_C24_A);
195 :
196 0 : dm_write_reg(ctx, addr, value);
197 : }
198 : {
199 0 : uint32_t value = 0;
200 0 : uint32_t addr = mmOUTPUT_CSC_C31_C32_A;
201 : /* fixed S2.13 format */
202 0 : set_reg_field_value(
203 : value,
204 : tbl_entry->regval[8],
205 : OUTPUT_CSC_C31_C32_A,
206 : OUTPUT_CSC_C31_A);
207 : /* fixed S0.13 format */
208 0 : set_reg_field_value(
209 : value,
210 : tbl_entry->regval[9],
211 : OUTPUT_CSC_C31_C32_A,
212 : OUTPUT_CSC_C32_A);
213 :
214 0 : dm_write_reg(ctx, addr, value);
215 : }
216 : {
217 0 : uint32_t value = 0;
218 0 : uint32_t addr = mmOUTPUT_CSC_C33_C34_A;
219 : /* fixed S2.13 format */
220 0 : set_reg_field_value(
221 : value,
222 : tbl_entry->regval[10],
223 : OUTPUT_CSC_C33_C34_A,
224 : OUTPUT_CSC_C33_A);
225 : /* fixed S0.13 format */
226 0 : set_reg_field_value(
227 : value,
228 : tbl_entry->regval[11],
229 : OUTPUT_CSC_C33_C34_A,
230 : OUTPUT_CSC_C34_A);
231 :
232 0 : dm_write_reg(ctx, addr, value);
233 : }
234 0 : set_reg_field_value(
235 : cntl_value,
236 : 4,
237 : COL_MAN_OUTPUT_CSC_CONTROL,
238 : OUTPUT_CSC_MODE);
239 : } else {
240 : {
241 0 : uint32_t value = 0;
242 0 : uint32_t addr = mmOUTPUT_CSC_C11_C12_B;
243 : /* fixed S2.13 format */
244 0 : set_reg_field_value(
245 : value,
246 : tbl_entry->regval[0],
247 : OUTPUT_CSC_C11_C12_B,
248 : OUTPUT_CSC_C11_B);
249 :
250 0 : set_reg_field_value(
251 : value,
252 : tbl_entry->regval[1],
253 : OUTPUT_CSC_C11_C12_B,
254 : OUTPUT_CSC_C12_B);
255 :
256 0 : dm_write_reg(ctx, addr, value);
257 : }
258 : {
259 0 : uint32_t value = 0;
260 0 : uint32_t addr = mmOUTPUT_CSC_C13_C14_B;
261 : /* fixed S2.13 format */
262 0 : set_reg_field_value(
263 : value,
264 : tbl_entry->regval[2],
265 : OUTPUT_CSC_C13_C14_B,
266 : OUTPUT_CSC_C13_B);
267 : /* fixed S0.13 format */
268 0 : set_reg_field_value(
269 : value,
270 : tbl_entry->regval[3],
271 : OUTPUT_CSC_C13_C14_B,
272 : OUTPUT_CSC_C14_B);
273 :
274 0 : dm_write_reg(ctx, addr, value);
275 : }
276 : {
277 0 : uint32_t value = 0;
278 0 : uint32_t addr = mmOUTPUT_CSC_C21_C22_B;
279 : /* fixed S2.13 format */
280 0 : set_reg_field_value(
281 : value,
282 : tbl_entry->regval[4],
283 : OUTPUT_CSC_C21_C22_B,
284 : OUTPUT_CSC_C21_B);
285 : /* fixed S2.13 format */
286 0 : set_reg_field_value(
287 : value,
288 : tbl_entry->regval[5],
289 : OUTPUT_CSC_C21_C22_B,
290 : OUTPUT_CSC_C22_B);
291 :
292 0 : dm_write_reg(ctx, addr, value);
293 : }
294 : {
295 0 : uint32_t value = 0;
296 0 : uint32_t addr = mmOUTPUT_CSC_C23_C24_B;
297 : /* fixed S2.13 format */
298 0 : set_reg_field_value(
299 : value,
300 : tbl_entry->regval[6],
301 : OUTPUT_CSC_C23_C24_B,
302 : OUTPUT_CSC_C23_B);
303 : /* fixed S0.13 format */
304 0 : set_reg_field_value(
305 : value,
306 : tbl_entry->regval[7],
307 : OUTPUT_CSC_C23_C24_B,
308 : OUTPUT_CSC_C24_B);
309 :
310 0 : dm_write_reg(ctx, addr, value);
311 : }
312 : {
313 0 : uint32_t value = 0;
314 0 : uint32_t addr = mmOUTPUT_CSC_C31_C32_B;
315 : /* fixed S2.13 format */
316 0 : set_reg_field_value(
317 : value,
318 : tbl_entry->regval[8],
319 : OUTPUT_CSC_C31_C32_B,
320 : OUTPUT_CSC_C31_B);
321 : /* fixed S0.13 format */
322 0 : set_reg_field_value(
323 : value,
324 : tbl_entry->regval[9],
325 : OUTPUT_CSC_C31_C32_B,
326 : OUTPUT_CSC_C32_B);
327 :
328 0 : dm_write_reg(ctx, addr, value);
329 : }
330 : {
331 0 : uint32_t value = 0;
332 0 : uint32_t addr = mmOUTPUT_CSC_C33_C34_B;
333 : /* fixed S2.13 format */
334 0 : set_reg_field_value(
335 : value,
336 : tbl_entry->regval[10],
337 : OUTPUT_CSC_C33_C34_B,
338 : OUTPUT_CSC_C33_B);
339 : /* fixed S0.13 format */
340 0 : set_reg_field_value(
341 : value,
342 : tbl_entry->regval[11],
343 : OUTPUT_CSC_C33_C34_B,
344 : OUTPUT_CSC_C34_B);
345 :
346 0 : dm_write_reg(ctx, addr, value);
347 : }
348 0 : set_reg_field_value(
349 : cntl_value,
350 : 5,
351 : COL_MAN_OUTPUT_CSC_CONTROL,
352 : OUTPUT_CSC_MODE);
353 : }
354 :
355 0 : dm_write_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL, cntl_value);
356 0 : }
357 :
358 0 : static bool configure_graphics_mode_v(
359 : struct dce_transform *xfm_dce,
360 : enum csc_color_mode config,
361 : enum graphics_csc_adjust_type csc_adjust_type,
362 : enum dc_color_space color_space)
363 : {
364 0 : struct dc_context *ctx = xfm_dce->base.ctx;
365 0 : uint32_t addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
366 0 : uint32_t value = dm_read_reg(ctx, addr);
367 :
368 0 : set_reg_field_value(
369 : value,
370 : 0,
371 : COL_MAN_OUTPUT_CSC_CONTROL,
372 : OUTPUT_CSC_MODE);
373 :
374 0 : if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
375 0 : if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC)
376 : return true;
377 :
378 0 : switch (color_space) {
379 : case COLOR_SPACE_SRGB:
380 : /* by pass */
381 : set_reg_field_value(
382 : value,
383 : 0,
384 : COL_MAN_OUTPUT_CSC_CONTROL,
385 : OUTPUT_CSC_MODE);
386 : break;
387 : case COLOR_SPACE_SRGB_LIMITED:
388 : /* not supported for underlay on CZ */
389 : return false;
390 :
391 : case COLOR_SPACE_YCBCR601_LIMITED:
392 : /* YCbCr601 */
393 0 : set_reg_field_value(
394 : value,
395 : 2,
396 : COL_MAN_OUTPUT_CSC_CONTROL,
397 : OUTPUT_CSC_MODE);
398 : break;
399 : case COLOR_SPACE_YCBCR709:
400 : case COLOR_SPACE_YCBCR709_LIMITED:
401 : /* YCbCr709 */
402 0 : set_reg_field_value(
403 : value,
404 : 3,
405 : COL_MAN_OUTPUT_CSC_CONTROL,
406 : OUTPUT_CSC_MODE);
407 : break;
408 : default:
409 : return false;
410 : }
411 :
412 0 : } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
413 0 : switch (color_space) {
414 : case COLOR_SPACE_SRGB:
415 : /* by pass */
416 : set_reg_field_value(
417 : value,
418 : 0,
419 : COL_MAN_OUTPUT_CSC_CONTROL,
420 : OUTPUT_CSC_MODE);
421 : break;
422 : case COLOR_SPACE_SRGB_LIMITED:
423 : /* not supported for underlay on CZ */
424 : return false;
425 : case COLOR_SPACE_YCBCR601:
426 : case COLOR_SPACE_YCBCR601_LIMITED:
427 : /* YCbCr601 */
428 0 : set_reg_field_value(
429 : value,
430 : 2,
431 : COL_MAN_OUTPUT_CSC_CONTROL,
432 : OUTPUT_CSC_MODE);
433 : break;
434 : case COLOR_SPACE_YCBCR709:
435 : case COLOR_SPACE_YCBCR709_LIMITED:
436 : /* YCbCr709 */
437 0 : set_reg_field_value(
438 : value,
439 : 3,
440 : COL_MAN_OUTPUT_CSC_CONTROL,
441 : OUTPUT_CSC_MODE);
442 : break;
443 : default:
444 : return false;
445 : }
446 :
447 : } else
448 : /* by pass */
449 : set_reg_field_value(
450 : value,
451 : 0,
452 : COL_MAN_OUTPUT_CSC_CONTROL,
453 : OUTPUT_CSC_MODE);
454 :
455 0 : addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
456 0 : dm_write_reg(ctx, addr, value);
457 :
458 : return true;
459 : }
460 :
461 : /*TODO: color depth is not correct when this is called*/
462 0 : static void set_Denormalization(struct transform *xfm,
463 : enum dc_color_depth color_depth)
464 : {
465 0 : uint32_t value = dm_read_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL);
466 :
467 0 : switch (color_depth) {
468 : case COLOR_DEPTH_888:
469 : /* 255/256 for 8 bit output color depth */
470 0 : set_reg_field_value(
471 : value,
472 : 1,
473 : DENORM_CLAMP_CONTROL,
474 : DENORM_MODE);
475 : break;
476 : case COLOR_DEPTH_101010:
477 : /* 1023/1024 for 10 bit output color depth */
478 0 : set_reg_field_value(
479 : value,
480 : 2,
481 : DENORM_CLAMP_CONTROL,
482 : DENORM_MODE);
483 : break;
484 : case COLOR_DEPTH_121212:
485 : /* 4095/4096 for 12 bit output color depth */
486 0 : set_reg_field_value(
487 : value,
488 : 3,
489 : DENORM_CLAMP_CONTROL,
490 : DENORM_MODE);
491 : break;
492 : default:
493 : /* not valid case */
494 : break;
495 : }
496 :
497 0 : set_reg_field_value(
498 : value,
499 : 1,
500 : DENORM_CLAMP_CONTROL,
501 : DENORM_10BIT_OUT);
502 :
503 0 : dm_write_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL, value);
504 0 : }
505 :
506 : struct input_csc_matrix {
507 : enum dc_color_space color_space;
508 : uint32_t regval[12];
509 : };
510 :
511 : static const struct input_csc_matrix input_csc_matrix[] = {
512 : {COLOR_SPACE_SRGB,
513 : /*1_1 1_2 1_3 1_4 2_1 2_2 2_3 2_4 3_1 3_2 3_3 3_4 */
514 : {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
515 : {COLOR_SPACE_SRGB_LIMITED,
516 : {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
517 : {COLOR_SPACE_YCBCR601,
518 : {0x2cdd, 0x2000, 0x0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef,
519 : 0x0, 0x2000, 0x38b4, 0xe3a6} },
520 : {COLOR_SPACE_YCBCR601_LIMITED,
521 : {0x3353, 0x2568, 0x0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108,
522 : 0x0, 0x2568, 0x40de, 0xdd3a} },
523 : {COLOR_SPACE_YCBCR709,
524 : {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0,
525 : 0x2000, 0x3b61, 0xe24f} },
526 : {COLOR_SPACE_YCBCR709_LIMITED,
527 : {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0,
528 : 0x2568, 0x43ee, 0xdbb2} }
529 : };
530 :
531 0 : static void program_input_csc(
532 : struct transform *xfm, enum dc_color_space color_space)
533 : {
534 0 : int arr_size = sizeof(input_csc_matrix)/sizeof(struct input_csc_matrix);
535 0 : struct dc_context *ctx = xfm->ctx;
536 0 : const uint32_t *regval = NULL;
537 : bool use_set_a;
538 : uint32_t value;
539 : int i;
540 :
541 0 : for (i = 0; i < arr_size; i++)
542 0 : if (input_csc_matrix[i].color_space == color_space) {
543 0 : regval = input_csc_matrix[i].regval;
544 : break;
545 : }
546 0 : if (regval == NULL) {
547 0 : BREAK_TO_DEBUGGER();
548 : return;
549 : }
550 :
551 : /*
552 : * 1 == set A, the logic is 'if currently we're not using set A,
553 : * then use set A, otherwise use set B'
554 : */
555 0 : value = dm_read_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL);
556 0 : use_set_a = get_reg_field_value(
557 : value, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_MODE) != 1;
558 :
559 0 : if (use_set_a) {
560 : /* fixed S2.13 format */
561 0 : value = 0;
562 0 : set_reg_field_value(
563 : value, regval[0], INPUT_CSC_C11_C12_A, INPUT_CSC_C11_A);
564 0 : set_reg_field_value(
565 : value, regval[1], INPUT_CSC_C11_C12_A, INPUT_CSC_C12_A);
566 0 : dm_write_reg(ctx, mmINPUT_CSC_C11_C12_A, value);
567 :
568 0 : value = 0;
569 0 : set_reg_field_value(
570 : value, regval[2], INPUT_CSC_C13_C14_A, INPUT_CSC_C13_A);
571 0 : set_reg_field_value(
572 : value, regval[3], INPUT_CSC_C13_C14_A, INPUT_CSC_C14_A);
573 0 : dm_write_reg(ctx, mmINPUT_CSC_C13_C14_A, value);
574 :
575 0 : value = 0;
576 0 : set_reg_field_value(
577 : value, regval[4], INPUT_CSC_C21_C22_A, INPUT_CSC_C21_A);
578 0 : set_reg_field_value(
579 : value, regval[5], INPUT_CSC_C21_C22_A, INPUT_CSC_C22_A);
580 0 : dm_write_reg(ctx, mmINPUT_CSC_C21_C22_A, value);
581 :
582 0 : value = 0;
583 0 : set_reg_field_value(
584 : value, regval[6], INPUT_CSC_C23_C24_A, INPUT_CSC_C23_A);
585 0 : set_reg_field_value(
586 : value, regval[7], INPUT_CSC_C23_C24_A, INPUT_CSC_C24_A);
587 0 : dm_write_reg(ctx, mmINPUT_CSC_C23_C24_A, value);
588 :
589 0 : value = 0;
590 0 : set_reg_field_value(
591 : value, regval[8], INPUT_CSC_C31_C32_A, INPUT_CSC_C31_A);
592 0 : set_reg_field_value(
593 : value, regval[9], INPUT_CSC_C31_C32_A, INPUT_CSC_C32_A);
594 0 : dm_write_reg(ctx, mmINPUT_CSC_C31_C32_A, value);
595 :
596 0 : value = 0;
597 0 : set_reg_field_value(
598 : value, regval[10], INPUT_CSC_C33_C34_A, INPUT_CSC_C33_A);
599 0 : set_reg_field_value(
600 : value, regval[11], INPUT_CSC_C33_C34_A, INPUT_CSC_C34_A);
601 0 : dm_write_reg(ctx, mmINPUT_CSC_C33_C34_A, value);
602 : } else {
603 : /* fixed S2.13 format */
604 0 : value = 0;
605 0 : set_reg_field_value(
606 : value, regval[0], INPUT_CSC_C11_C12_B, INPUT_CSC_C11_B);
607 0 : set_reg_field_value(
608 : value, regval[1], INPUT_CSC_C11_C12_B, INPUT_CSC_C12_B);
609 0 : dm_write_reg(ctx, mmINPUT_CSC_C11_C12_B, value);
610 :
611 0 : value = 0;
612 0 : set_reg_field_value(
613 : value, regval[2], INPUT_CSC_C13_C14_B, INPUT_CSC_C13_B);
614 0 : set_reg_field_value(
615 : value, regval[3], INPUT_CSC_C13_C14_B, INPUT_CSC_C14_B);
616 0 : dm_write_reg(ctx, mmINPUT_CSC_C13_C14_B, value);
617 :
618 0 : value = 0;
619 0 : set_reg_field_value(
620 : value, regval[4], INPUT_CSC_C21_C22_B, INPUT_CSC_C21_B);
621 0 : set_reg_field_value(
622 : value, regval[5], INPUT_CSC_C21_C22_B, INPUT_CSC_C22_B);
623 0 : dm_write_reg(ctx, mmINPUT_CSC_C21_C22_B, value);
624 :
625 0 : value = 0;
626 0 : set_reg_field_value(
627 : value, regval[6], INPUT_CSC_C23_C24_B, INPUT_CSC_C23_B);
628 0 : set_reg_field_value(
629 : value, regval[7], INPUT_CSC_C23_C24_B, INPUT_CSC_C24_B);
630 0 : dm_write_reg(ctx, mmINPUT_CSC_C23_C24_B, value);
631 :
632 0 : value = 0;
633 0 : set_reg_field_value(
634 : value, regval[8], INPUT_CSC_C31_C32_B, INPUT_CSC_C31_B);
635 0 : set_reg_field_value(
636 : value, regval[9], INPUT_CSC_C31_C32_B, INPUT_CSC_C32_B);
637 0 : dm_write_reg(ctx, mmINPUT_CSC_C31_C32_B, value);
638 :
639 0 : value = 0;
640 0 : set_reg_field_value(
641 : value, regval[10], INPUT_CSC_C33_C34_B, INPUT_CSC_C33_B);
642 0 : set_reg_field_value(
643 : value, regval[11], INPUT_CSC_C33_C34_B, INPUT_CSC_C34_B);
644 0 : dm_write_reg(ctx, mmINPUT_CSC_C33_C34_B, value);
645 : }
646 :
647 : /* KK: leave INPUT_CSC_CONVERSION_MODE at default */
648 0 : value = 0;
649 : /*
650 : * select 8.4 input type instead of default 12.0. From the discussion
651 : * with HW team, this format depends on the UNP surface format, so for
652 : * 8-bit we should select 8.4 (4 bits truncated). For 10 it should be
653 : * 10.2. For Carrizo we only support 8-bit surfaces on underlay pipe
654 : * so we can always keep this at 8.4 (input_type=2). If the later asics
655 : * start supporting 10+ bits, we will have a problem: surface
656 : * programming including UNP_GRPH* is being done in DalISR after this,
657 : * so either we pass surface format to here, or move this logic to ISR
658 : */
659 :
660 0 : set_reg_field_value(
661 : value, 2, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_INPUT_TYPE);
662 0 : set_reg_field_value(
663 : value,
664 : use_set_a ? 1 : 2,
665 : COL_MAN_INPUT_CSC_CONTROL,
666 : INPUT_CSC_MODE);
667 :
668 0 : dm_write_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL, value);
669 : }
670 :
671 0 : void dce110_opp_v_set_csc_default(
672 : struct transform *xfm,
673 : const struct default_adjustment *default_adjust)
674 : {
675 0 : struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
676 0 : enum csc_color_mode config =
677 : CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
678 :
679 0 : if (default_adjust->force_hw_default == false) {
680 : const struct out_csc_color_matrix *elm;
681 : /* currently parameter not in use */
682 : enum grph_color_adjust_option option;
683 : uint32_t i;
684 : /*
685 : * HW default false we program locally defined matrix
686 : * HW default true we use predefined hw matrix and we
687 : * do not need to program matrix
688 : * OEM wants the HW default via runtime parameter.
689 : */
690 : option = GRPH_COLOR_MATRIX_SW;
691 :
692 0 : for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
693 0 : elm = &global_color_matrix[i];
694 0 : if (elm->color_space != default_adjust->out_color_space)
695 0 : continue;
696 : /* program the matrix with default values from this
697 : * file
698 : */
699 0 : program_color_matrix_v(xfm_dce, elm, option);
700 0 : config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
701 0 : break;
702 : }
703 : }
704 :
705 0 : program_input_csc(xfm, default_adjust->in_color_space);
706 :
707 : /* configure the what we programmed :
708 : * 1. Default values from this file
709 : * 2. Use hardware default from ROM_A and we do not need to program
710 : * matrix
711 : */
712 :
713 0 : configure_graphics_mode_v(xfm_dce, config,
714 : default_adjust->csc_adjust_type,
715 : default_adjust->out_color_space);
716 :
717 0 : set_Denormalization(xfm, default_adjust->color_depth);
718 0 : }
719 :
720 0 : void dce110_opp_v_set_csc_adjustment(
721 : struct transform *xfm,
722 : const struct out_csc_color_matrix *tbl_entry)
723 : {
724 0 : struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
725 0 : enum csc_color_mode config =
726 : CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
727 :
728 0 : program_color_matrix_v(
729 : xfm_dce, tbl_entry, GRPH_COLOR_MATRIX_SW);
730 :
731 : /* We did everything ,now program DxOUTPUT_CSC_CONTROL */
732 0 : configure_graphics_mode_v(xfm_dce, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
733 : tbl_entry->color_space);
734 :
735 : /*TODO: Check if denormalization is needed*/
736 : /*set_Denormalization(opp, adjust->color_depth);*/
737 0 : }
|