GNU Linux-libre 4.19.295-gnu1
[releases.git] / drivers / gpu / drm / amd / display / dc / dce110 / dce110_opp_csc_v.c
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 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         struct dc_context *ctx = xfm_dce->base.ctx;
114         uint32_t cntl_value = dm_read_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL);
115         bool use_set_a = (get_reg_field_value(cntl_value,
116                         COL_MAN_OUTPUT_CSC_CONTROL,
117                         OUTPUT_CSC_MODE) != 4);
118
119         set_reg_field_value(
120                         cntl_value,
121                 0,
122                 COL_MAN_OUTPUT_CSC_CONTROL,
123                 OUTPUT_CSC_MODE);
124
125         if (use_set_a) {
126                 {
127                         uint32_t value = 0;
128                         uint32_t addr = mmOUTPUT_CSC_C11_C12_A;
129                         /* fixed S2.13 format */
130                         set_reg_field_value(
131                                 value,
132                                 tbl_entry->regval[0],
133                                 OUTPUT_CSC_C11_C12_A,
134                                 OUTPUT_CSC_C11_A);
135
136                         set_reg_field_value(
137                                 value,
138                                 tbl_entry->regval[1],
139                                 OUTPUT_CSC_C11_C12_A,
140                                 OUTPUT_CSC_C12_A);
141
142                         dm_write_reg(ctx, addr, value);
143                 }
144                 {
145                         uint32_t value = 0;
146                         uint32_t addr = mmOUTPUT_CSC_C13_C14_A;
147                         /* fixed S2.13 format */
148                         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                         set_reg_field_value(
155                                 value,
156                                 tbl_entry->regval[3],
157                                 OUTPUT_CSC_C13_C14_A,
158                                 OUTPUT_CSC_C14_A);
159
160                         dm_write_reg(ctx, addr, value);
161                 }
162                 {
163                         uint32_t value = 0;
164                         uint32_t addr = mmOUTPUT_CSC_C21_C22_A;
165                         /* fixed S2.13 format */
166                         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                         set_reg_field_value(
173                                 value,
174                                 tbl_entry->regval[5],
175                                 OUTPUT_CSC_C21_C22_A,
176                                 OUTPUT_CSC_C22_A);
177
178                         dm_write_reg(ctx, addr, value);
179                 }
180                 {
181                         uint32_t value = 0;
182                         uint32_t addr = mmOUTPUT_CSC_C23_C24_A;
183                         /* fixed S2.13 format */
184                         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                         set_reg_field_value(
191                                 value,
192                                 tbl_entry->regval[7],
193                                 OUTPUT_CSC_C23_C24_A,
194                                 OUTPUT_CSC_C24_A);
195
196                         dm_write_reg(ctx, addr, value);
197                 }
198                 {
199                         uint32_t value = 0;
200                         uint32_t addr = mmOUTPUT_CSC_C31_C32_A;
201                         /* fixed S2.13 format */
202                         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                         set_reg_field_value(
209                                 value,
210                                 tbl_entry->regval[9],
211                                 OUTPUT_CSC_C31_C32_A,
212                                 OUTPUT_CSC_C32_A);
213
214                         dm_write_reg(ctx, addr, value);
215                 }
216                 {
217                         uint32_t value = 0;
218                         uint32_t addr = mmOUTPUT_CSC_C33_C34_A;
219                         /* fixed S2.13 format */
220                         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                         set_reg_field_value(
227                                 value,
228                                 tbl_entry->regval[11],
229                                 OUTPUT_CSC_C33_C34_A,
230                                 OUTPUT_CSC_C34_A);
231
232                         dm_write_reg(ctx, addr, value);
233                 }
234                 set_reg_field_value(
235                         cntl_value,
236                         4,
237                         COL_MAN_OUTPUT_CSC_CONTROL,
238                         OUTPUT_CSC_MODE);
239         } else {
240                 {
241                         uint32_t value = 0;
242                         uint32_t addr = mmOUTPUT_CSC_C11_C12_B;
243                         /* fixed S2.13 format */
244                         set_reg_field_value(
245                                 value,
246                                 tbl_entry->regval[0],
247                                 OUTPUT_CSC_C11_C12_B,
248                                 OUTPUT_CSC_C11_B);
249
250                         set_reg_field_value(
251                                 value,
252                                 tbl_entry->regval[1],
253                                 OUTPUT_CSC_C11_C12_B,
254                                 OUTPUT_CSC_C12_B);
255
256                         dm_write_reg(ctx, addr, value);
257                 }
258                 {
259                         uint32_t value = 0;
260                         uint32_t addr = mmOUTPUT_CSC_C13_C14_B;
261                         /* fixed S2.13 format */
262                         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                         set_reg_field_value(
269                                 value,
270                                 tbl_entry->regval[3],
271                                 OUTPUT_CSC_C13_C14_B,
272                                 OUTPUT_CSC_C14_B);
273
274                         dm_write_reg(ctx, addr, value);
275                 }
276                 {
277                         uint32_t value = 0;
278                         uint32_t addr = mmOUTPUT_CSC_C21_C22_B;
279                         /* fixed S2.13 format */
280                         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                         set_reg_field_value(
287                                 value,
288                                 tbl_entry->regval[5],
289                                 OUTPUT_CSC_C21_C22_B,
290                                 OUTPUT_CSC_C22_B);
291
292                         dm_write_reg(ctx, addr, value);
293                 }
294                 {
295                         uint32_t value = 0;
296                         uint32_t addr = mmOUTPUT_CSC_C23_C24_B;
297                         /* fixed S2.13 format */
298                         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                         set_reg_field_value(
305                                 value,
306                                 tbl_entry->regval[7],
307                                 OUTPUT_CSC_C23_C24_B,
308                                 OUTPUT_CSC_C24_B);
309
310                         dm_write_reg(ctx, addr, value);
311                 }
312                 {
313                         uint32_t value = 0;
314                         uint32_t addr = mmOUTPUT_CSC_C31_C32_B;
315                         /* fixed S2.13 format */
316                         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                         set_reg_field_value(
323                                 value,
324                                 tbl_entry->regval[9],
325                                 OUTPUT_CSC_C31_C32_B,
326                                 OUTPUT_CSC_C32_B);
327
328                         dm_write_reg(ctx, addr, value);
329                 }
330                 {
331                         uint32_t value = 0;
332                         uint32_t addr = mmOUTPUT_CSC_C33_C34_B;
333                         /* fixed S2.13 format */
334                         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                         set_reg_field_value(
341                                 value,
342                                 tbl_entry->regval[11],
343                                 OUTPUT_CSC_C33_C34_B,
344                                 OUTPUT_CSC_C34_B);
345
346                         dm_write_reg(ctx, addr, value);
347                 }
348                 set_reg_field_value(
349                         cntl_value,
350                         5,
351                         COL_MAN_OUTPUT_CSC_CONTROL,
352                         OUTPUT_CSC_MODE);
353         }
354
355         dm_write_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL, cntl_value);
356 }
357
358 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         struct dc_context *ctx = xfm_dce->base.ctx;
365         uint32_t addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
366         uint32_t value = dm_read_reg(ctx, addr);
367
368         set_reg_field_value(
369                 value,
370                 0,
371                 COL_MAN_OUTPUT_CSC_CONTROL,
372                 OUTPUT_CSC_MODE);
373
374         if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
375                 if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC)
376                         return true;
377
378                 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                         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                         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         } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
413                 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                         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                         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         addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
456         dm_write_reg(ctx, addr, value);
457
458         return true;
459 }
460
461 /*TODO: color depth is not correct when this is called*/
462 static void set_Denormalization(struct transform *xfm,
463                 enum dc_color_depth color_depth)
464 {
465         uint32_t value = dm_read_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL);
466
467         switch (color_depth) {
468         case COLOR_DEPTH_888:
469                 /* 255/256 for 8 bit output color depth */
470                 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                 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                 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         set_reg_field_value(
498                 value,
499                 1,
500                 DENORM_CLAMP_CONTROL,
501                 DENORM_10BIT_OUT);
502
503         dm_write_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL, value);
504 }
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 static void program_input_csc(
532                 struct transform *xfm, enum dc_color_space color_space)
533 {
534         int arr_size = sizeof(input_csc_matrix)/sizeof(struct input_csc_matrix);
535         struct dc_context *ctx = xfm->ctx;
536         const uint32_t *regval = NULL;
537         bool use_set_a;
538         uint32_t value;
539         int i;
540
541         for (i = 0; i < arr_size; i++)
542                 if (input_csc_matrix[i].color_space == color_space) {
543                         regval = input_csc_matrix[i].regval;
544                         break;
545                 }
546         if (regval == NULL) {
547                 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         value = dm_read_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL);
556         use_set_a = get_reg_field_value(
557                 value, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_MODE) != 1;
558
559         if (use_set_a) {
560                 /* fixed S2.13 format */
561                 value = 0;
562                 set_reg_field_value(
563                         value, regval[0], INPUT_CSC_C11_C12_A, INPUT_CSC_C11_A);
564                 set_reg_field_value(
565                         value, regval[1], INPUT_CSC_C11_C12_A, INPUT_CSC_C12_A);
566                 dm_write_reg(ctx, mmINPUT_CSC_C11_C12_A, value);
567
568                 value = 0;
569                 set_reg_field_value(
570                         value, regval[2], INPUT_CSC_C13_C14_A, INPUT_CSC_C13_A);
571                 set_reg_field_value(
572                         value, regval[3], INPUT_CSC_C13_C14_A, INPUT_CSC_C14_A);
573                 dm_write_reg(ctx, mmINPUT_CSC_C13_C14_A, value);
574
575                 value = 0;
576                 set_reg_field_value(
577                         value, regval[4], INPUT_CSC_C21_C22_A, INPUT_CSC_C21_A);
578                 set_reg_field_value(
579                         value, regval[5], INPUT_CSC_C21_C22_A, INPUT_CSC_C22_A);
580                 dm_write_reg(ctx, mmINPUT_CSC_C21_C22_A, value);
581
582                 value = 0;
583                 set_reg_field_value(
584                         value, regval[6], INPUT_CSC_C23_C24_A, INPUT_CSC_C23_A);
585                 set_reg_field_value(
586                         value, regval[7], INPUT_CSC_C23_C24_A, INPUT_CSC_C24_A);
587                 dm_write_reg(ctx, mmINPUT_CSC_C23_C24_A, value);
588
589                 value = 0;
590                 set_reg_field_value(
591                         value, regval[8], INPUT_CSC_C31_C32_A, INPUT_CSC_C31_A);
592                 set_reg_field_value(
593                         value, regval[9], INPUT_CSC_C31_C32_A, INPUT_CSC_C32_A);
594                 dm_write_reg(ctx, mmINPUT_CSC_C31_C32_A, value);
595
596                 value = 0;
597                 set_reg_field_value(
598                         value, regval[10], INPUT_CSC_C33_C34_A, INPUT_CSC_C33_A);
599                 set_reg_field_value(
600                         value, regval[11], INPUT_CSC_C33_C34_A, INPUT_CSC_C34_A);
601                 dm_write_reg(ctx, mmINPUT_CSC_C33_C34_A, value);
602         } else {
603                 /* fixed S2.13 format */
604                 value = 0;
605                 set_reg_field_value(
606                         value, regval[0], INPUT_CSC_C11_C12_B, INPUT_CSC_C11_B);
607                 set_reg_field_value(
608                         value, regval[1], INPUT_CSC_C11_C12_B, INPUT_CSC_C12_B);
609                 dm_write_reg(ctx, mmINPUT_CSC_C11_C12_B, value);
610
611                 value = 0;
612                 set_reg_field_value(
613                         value, regval[2], INPUT_CSC_C13_C14_B, INPUT_CSC_C13_B);
614                 set_reg_field_value(
615                         value, regval[3], INPUT_CSC_C13_C14_B, INPUT_CSC_C14_B);
616                 dm_write_reg(ctx, mmINPUT_CSC_C13_C14_B, value);
617
618                 value = 0;
619                 set_reg_field_value(
620                         value, regval[4], INPUT_CSC_C21_C22_B, INPUT_CSC_C21_B);
621                 set_reg_field_value(
622                         value, regval[5], INPUT_CSC_C21_C22_B, INPUT_CSC_C22_B);
623                 dm_write_reg(ctx, mmINPUT_CSC_C21_C22_B, value);
624
625                 value = 0;
626                 set_reg_field_value(
627                         value, regval[6], INPUT_CSC_C23_C24_B, INPUT_CSC_C23_B);
628                 set_reg_field_value(
629                         value, regval[7], INPUT_CSC_C23_C24_B, INPUT_CSC_C24_B);
630                 dm_write_reg(ctx, mmINPUT_CSC_C23_C24_B, value);
631
632                 value = 0;
633                 set_reg_field_value(
634                         value, regval[8], INPUT_CSC_C31_C32_B, INPUT_CSC_C31_B);
635                 set_reg_field_value(
636                         value, regval[9], INPUT_CSC_C31_C32_B, INPUT_CSC_C32_B);
637                 dm_write_reg(ctx, mmINPUT_CSC_C31_C32_B, value);
638
639                 value = 0;
640                 set_reg_field_value(
641                         value, regval[10], INPUT_CSC_C33_C34_B, INPUT_CSC_C33_B);
642                 set_reg_field_value(
643                         value, regval[11], INPUT_CSC_C33_C34_B, INPUT_CSC_C34_B);
644                 dm_write_reg(ctx, mmINPUT_CSC_C33_C34_B, value);
645         }
646
647         /* KK: leave INPUT_CSC_CONVERSION_MODE at default */
648         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         set_reg_field_value(
661                 value, 2, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_INPUT_TYPE);
662         set_reg_field_value(
663                 value,
664                 use_set_a ? 1 : 2,
665                 COL_MAN_INPUT_CSC_CONTROL,
666                 INPUT_CSC_MODE);
667
668         dm_write_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL, value);
669 }
670
671 void dce110_opp_v_set_csc_default(
672         struct transform *xfm,
673         const struct default_adjustment *default_adjust)
674 {
675         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
676         enum csc_color_mode config =
677                         CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
678
679         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                         GRPH_COLOR_MATRIX_HW_DEFAULT;
684                 uint32_t i;
685                 /*
686                  * HW default false we program locally defined matrix
687                  * HW default true  we use predefined hw matrix and we
688                  * do not need to program matrix
689                  * OEM wants the HW default via runtime parameter.
690                  */
691                 option = GRPH_COLOR_MATRIX_SW;
692
693                 for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
694                         elm = &global_color_matrix[i];
695                         if (elm->color_space != default_adjust->out_color_space)
696                                 continue;
697                         /* program the matrix with default values from this
698                          * file
699                          */
700                         program_color_matrix_v(xfm_dce, elm, option);
701                         config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
702                         break;
703                 }
704         }
705
706         program_input_csc(xfm, default_adjust->in_color_space);
707
708         /* configure the what we programmed :
709          * 1. Default values from this file
710          * 2. Use hardware default from ROM_A and we do not need to program
711          * matrix
712          */
713
714         configure_graphics_mode_v(xfm_dce, config,
715                 default_adjust->csc_adjust_type,
716                 default_adjust->out_color_space);
717
718         set_Denormalization(xfm, default_adjust->color_depth);
719 }
720
721 void dce110_opp_v_set_csc_adjustment(
722         struct transform *xfm,
723         const struct out_csc_color_matrix *tbl_entry)
724 {
725         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
726         enum csc_color_mode config =
727                         CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
728
729         program_color_matrix_v(
730                         xfm_dce, tbl_entry, GRPH_COLOR_MATRIX_SW);
731
732         /*  We did everything ,now program DxOUTPUT_CSC_CONTROL */
733         configure_graphics_mode_v(xfm_dce, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
734                         tbl_entry->color_space);
735
736         /*TODO: Check if denormalization is needed*/
737         /*set_Denormalization(opp, adjust->color_depth);*/
738 }