Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  *  and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 #include "dce110_transform_v.h"
0028 #include "basics/conversion.h"
0029 
0030 /* include DCE11 register header files */
0031 #include "dce/dce_11_0_d.h"
0032 #include "dce/dce_11_0_sh_mask.h"
0033 #include "dce/dce_11_0_enum.h"
0034 
0035 enum {
0036     OUTPUT_CSC_MATRIX_SIZE = 12
0037 };
0038 
0039 /* constrast:0 - 2.0, default 1.0 */
0040 #define UNDERLAY_CONTRAST_DEFAULT 100
0041 #define UNDERLAY_CONTRAST_MAX     200
0042 #define UNDERLAY_CONTRAST_MIN       0
0043 #define UNDERLAY_CONTRAST_STEP      1
0044 #define UNDERLAY_CONTRAST_DIVIDER 100
0045 
0046 /* Saturation: 0 - 2.0; default 1.0 */
0047 #define UNDERLAY_SATURATION_DEFAULT   100 /*1.00*/
0048 #define UNDERLAY_SATURATION_MIN         0
0049 #define UNDERLAY_SATURATION_MAX       200 /* 2.00 */
0050 #define UNDERLAY_SATURATION_STEP        1 /* 0.01 */
0051 /*actual max overlay saturation
0052  * value = UNDERLAY_SATURATION_MAX /UNDERLAY_SATURATION_DIVIDER
0053  */
0054 
0055 /* Hue */
0056 #define  UNDERLAY_HUE_DEFAULT      0
0057 #define  UNDERLAY_HUE_MIN       -300
0058 #define  UNDERLAY_HUE_MAX        300
0059 #define  UNDERLAY_HUE_STEP         5
0060 #define  UNDERLAY_HUE_DIVIDER   10 /* HW range: -30 ~ +30 */
0061 #define UNDERLAY_SATURATION_DIVIDER   100
0062 
0063 /* Brightness: in DAL usually -.25 ~ .25.
0064  * In MMD is -100 to +100 in 16-235 range; which when scaled to full range is
0065  *  ~-116 to +116. When normalized this is about 0.4566.
0066  * With 100 divider this becomes 46, but we may use another for better precision
0067  * The ideal one is 100/219 ((100/255)*(255/219)),
0068  * i.e. min/max = +-100, divider = 219
0069  * default 0.0
0070  */
0071 #define  UNDERLAY_BRIGHTNESS_DEFAULT    0
0072 #define  UNDERLAY_BRIGHTNESS_MIN      -46 /* ~116/255 */
0073 #define  UNDERLAY_BRIGHTNESS_MAX       46
0074 #define  UNDERLAY_BRIGHTNESS_STEP       1 /*  .01 */
0075 #define  UNDERLAY_BRIGHTNESS_DIVIDER  100
0076 
0077 static const struct out_csc_color_matrix global_color_matrix[] = {
0078 { COLOR_SPACE_SRGB,
0079     { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
0080 { COLOR_SPACE_SRGB_LIMITED,
0081     { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
0082 { COLOR_SPACE_YCBCR601,
0083     { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
0084         0xF6B9, 0xE00, 0x1000} },
0085 { COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
0086     0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
0087 /* TODO: correct values below */
0088 { COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
0089     0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
0090 { COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
0091     0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
0092 };
0093 
0094 enum csc_color_mode {
0095     /* 00 - BITS2:0 Bypass */
0096     CSC_COLOR_MODE_GRAPHICS_BYPASS,
0097     /* 01 - hard coded coefficient TV RGB */
0098     CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
0099     /* 04 - programmable OUTPUT CSC coefficient */
0100     CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
0101 };
0102 
0103 enum grph_color_adjust_option {
0104     GRPH_COLOR_MATRIX_HW_DEFAULT = 1,
0105     GRPH_COLOR_MATRIX_SW
0106 };
0107 
0108 static void program_color_matrix_v(
0109     struct dce_transform *xfm_dce,
0110     const struct out_csc_color_matrix *tbl_entry,
0111     enum grph_color_adjust_option options)
0112 {
0113     struct dc_context *ctx = xfm_dce->base.ctx;
0114     uint32_t cntl_value = dm_read_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL);
0115     bool use_set_a = (get_reg_field_value(cntl_value,
0116             COL_MAN_OUTPUT_CSC_CONTROL,
0117             OUTPUT_CSC_MODE) != 4);
0118 
0119     set_reg_field_value(
0120             cntl_value,
0121         0,
0122         COL_MAN_OUTPUT_CSC_CONTROL,
0123         OUTPUT_CSC_MODE);
0124 
0125     if (use_set_a) {
0126         {
0127             uint32_t value = 0;
0128             uint32_t addr = mmOUTPUT_CSC_C11_C12_A;
0129             /* fixed S2.13 format */
0130             set_reg_field_value(
0131                 value,
0132                 tbl_entry->regval[0],
0133                 OUTPUT_CSC_C11_C12_A,
0134                 OUTPUT_CSC_C11_A);
0135 
0136             set_reg_field_value(
0137                 value,
0138                 tbl_entry->regval[1],
0139                 OUTPUT_CSC_C11_C12_A,
0140                 OUTPUT_CSC_C12_A);
0141 
0142             dm_write_reg(ctx, addr, value);
0143         }
0144         {
0145             uint32_t value = 0;
0146             uint32_t addr = mmOUTPUT_CSC_C13_C14_A;
0147             /* fixed S2.13 format */
0148             set_reg_field_value(
0149                 value,
0150                 tbl_entry->regval[2],
0151                 OUTPUT_CSC_C13_C14_A,
0152                 OUTPUT_CSC_C13_A);
0153             /* fixed S0.13 format */
0154             set_reg_field_value(
0155                 value,
0156                 tbl_entry->regval[3],
0157                 OUTPUT_CSC_C13_C14_A,
0158                 OUTPUT_CSC_C14_A);
0159 
0160             dm_write_reg(ctx, addr, value);
0161         }
0162         {
0163             uint32_t value = 0;
0164             uint32_t addr = mmOUTPUT_CSC_C21_C22_A;
0165             /* fixed S2.13 format */
0166             set_reg_field_value(
0167                 value,
0168                 tbl_entry->regval[4],
0169                 OUTPUT_CSC_C21_C22_A,
0170                 OUTPUT_CSC_C21_A);
0171             /* fixed S2.13 format */
0172             set_reg_field_value(
0173                 value,
0174                 tbl_entry->regval[5],
0175                 OUTPUT_CSC_C21_C22_A,
0176                 OUTPUT_CSC_C22_A);
0177 
0178             dm_write_reg(ctx, addr, value);
0179         }
0180         {
0181             uint32_t value = 0;
0182             uint32_t addr = mmOUTPUT_CSC_C23_C24_A;
0183             /* fixed S2.13 format */
0184             set_reg_field_value(
0185                 value,
0186                 tbl_entry->regval[6],
0187                 OUTPUT_CSC_C23_C24_A,
0188                 OUTPUT_CSC_C23_A);
0189             /* fixed S0.13 format */
0190             set_reg_field_value(
0191                 value,
0192                 tbl_entry->regval[7],
0193                 OUTPUT_CSC_C23_C24_A,
0194                 OUTPUT_CSC_C24_A);
0195 
0196             dm_write_reg(ctx, addr, value);
0197         }
0198         {
0199             uint32_t value = 0;
0200             uint32_t addr = mmOUTPUT_CSC_C31_C32_A;
0201             /* fixed S2.13 format */
0202             set_reg_field_value(
0203                 value,
0204                 tbl_entry->regval[8],
0205                 OUTPUT_CSC_C31_C32_A,
0206                 OUTPUT_CSC_C31_A);
0207             /* fixed S0.13 format */
0208             set_reg_field_value(
0209                 value,
0210                 tbl_entry->regval[9],
0211                 OUTPUT_CSC_C31_C32_A,
0212                 OUTPUT_CSC_C32_A);
0213 
0214             dm_write_reg(ctx, addr, value);
0215         }
0216         {
0217             uint32_t value = 0;
0218             uint32_t addr = mmOUTPUT_CSC_C33_C34_A;
0219             /* fixed S2.13 format */
0220             set_reg_field_value(
0221                 value,
0222                 tbl_entry->regval[10],
0223                 OUTPUT_CSC_C33_C34_A,
0224                 OUTPUT_CSC_C33_A);
0225             /* fixed S0.13 format */
0226             set_reg_field_value(
0227                 value,
0228                 tbl_entry->regval[11],
0229                 OUTPUT_CSC_C33_C34_A,
0230                 OUTPUT_CSC_C34_A);
0231 
0232             dm_write_reg(ctx, addr, value);
0233         }
0234         set_reg_field_value(
0235             cntl_value,
0236             4,
0237             COL_MAN_OUTPUT_CSC_CONTROL,
0238             OUTPUT_CSC_MODE);
0239     } else {
0240         {
0241             uint32_t value = 0;
0242             uint32_t addr = mmOUTPUT_CSC_C11_C12_B;
0243             /* fixed S2.13 format */
0244             set_reg_field_value(
0245                 value,
0246                 tbl_entry->regval[0],
0247                 OUTPUT_CSC_C11_C12_B,
0248                 OUTPUT_CSC_C11_B);
0249 
0250             set_reg_field_value(
0251                 value,
0252                 tbl_entry->regval[1],
0253                 OUTPUT_CSC_C11_C12_B,
0254                 OUTPUT_CSC_C12_B);
0255 
0256             dm_write_reg(ctx, addr, value);
0257         }
0258         {
0259             uint32_t value = 0;
0260             uint32_t addr = mmOUTPUT_CSC_C13_C14_B;
0261             /* fixed S2.13 format */
0262             set_reg_field_value(
0263                 value,
0264                 tbl_entry->regval[2],
0265                 OUTPUT_CSC_C13_C14_B,
0266                 OUTPUT_CSC_C13_B);
0267             /* fixed S0.13 format */
0268             set_reg_field_value(
0269                 value,
0270                 tbl_entry->regval[3],
0271                 OUTPUT_CSC_C13_C14_B,
0272                 OUTPUT_CSC_C14_B);
0273 
0274             dm_write_reg(ctx, addr, value);
0275         }
0276         {
0277             uint32_t value = 0;
0278             uint32_t addr = mmOUTPUT_CSC_C21_C22_B;
0279             /* fixed S2.13 format */
0280             set_reg_field_value(
0281                 value,
0282                 tbl_entry->regval[4],
0283                 OUTPUT_CSC_C21_C22_B,
0284                 OUTPUT_CSC_C21_B);
0285             /* fixed S2.13 format */
0286             set_reg_field_value(
0287                 value,
0288                 tbl_entry->regval[5],
0289                 OUTPUT_CSC_C21_C22_B,
0290                 OUTPUT_CSC_C22_B);
0291 
0292             dm_write_reg(ctx, addr, value);
0293         }
0294         {
0295             uint32_t value = 0;
0296             uint32_t addr = mmOUTPUT_CSC_C23_C24_B;
0297             /* fixed S2.13 format */
0298             set_reg_field_value(
0299                 value,
0300                 tbl_entry->regval[6],
0301                 OUTPUT_CSC_C23_C24_B,
0302                 OUTPUT_CSC_C23_B);
0303             /* fixed S0.13 format */
0304             set_reg_field_value(
0305                 value,
0306                 tbl_entry->regval[7],
0307                 OUTPUT_CSC_C23_C24_B,
0308                 OUTPUT_CSC_C24_B);
0309 
0310             dm_write_reg(ctx, addr, value);
0311         }
0312         {
0313             uint32_t value = 0;
0314             uint32_t addr = mmOUTPUT_CSC_C31_C32_B;
0315             /* fixed S2.13 format */
0316             set_reg_field_value(
0317                 value,
0318                 tbl_entry->regval[8],
0319                 OUTPUT_CSC_C31_C32_B,
0320                 OUTPUT_CSC_C31_B);
0321             /* fixed S0.13 format */
0322             set_reg_field_value(
0323                 value,
0324                 tbl_entry->regval[9],
0325                 OUTPUT_CSC_C31_C32_B,
0326                 OUTPUT_CSC_C32_B);
0327 
0328             dm_write_reg(ctx, addr, value);
0329         }
0330         {
0331             uint32_t value = 0;
0332             uint32_t addr = mmOUTPUT_CSC_C33_C34_B;
0333             /* fixed S2.13 format */
0334             set_reg_field_value(
0335                 value,
0336                 tbl_entry->regval[10],
0337                 OUTPUT_CSC_C33_C34_B,
0338                 OUTPUT_CSC_C33_B);
0339             /* fixed S0.13 format */
0340             set_reg_field_value(
0341                 value,
0342                 tbl_entry->regval[11],
0343                 OUTPUT_CSC_C33_C34_B,
0344                 OUTPUT_CSC_C34_B);
0345 
0346             dm_write_reg(ctx, addr, value);
0347         }
0348         set_reg_field_value(
0349             cntl_value,
0350             5,
0351             COL_MAN_OUTPUT_CSC_CONTROL,
0352             OUTPUT_CSC_MODE);
0353     }
0354 
0355     dm_write_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL, cntl_value);
0356 }
0357 
0358 static bool configure_graphics_mode_v(
0359     struct dce_transform *xfm_dce,
0360     enum csc_color_mode config,
0361     enum graphics_csc_adjust_type csc_adjust_type,
0362     enum dc_color_space color_space)
0363 {
0364     struct dc_context *ctx = xfm_dce->base.ctx;
0365     uint32_t addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
0366     uint32_t value = dm_read_reg(ctx, addr);
0367 
0368     set_reg_field_value(
0369         value,
0370         0,
0371         COL_MAN_OUTPUT_CSC_CONTROL,
0372         OUTPUT_CSC_MODE);
0373 
0374     if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
0375         if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC)
0376             return true;
0377 
0378         switch (color_space) {
0379         case COLOR_SPACE_SRGB:
0380             /* by pass */
0381             set_reg_field_value(
0382                 value,
0383                 0,
0384                 COL_MAN_OUTPUT_CSC_CONTROL,
0385                 OUTPUT_CSC_MODE);
0386             break;
0387         case COLOR_SPACE_SRGB_LIMITED:
0388             /* not supported for underlay on CZ */
0389             return false;
0390 
0391         case COLOR_SPACE_YCBCR601_LIMITED:
0392             /* YCbCr601 */
0393             set_reg_field_value(
0394                 value,
0395                 2,
0396                 COL_MAN_OUTPUT_CSC_CONTROL,
0397                 OUTPUT_CSC_MODE);
0398             break;
0399         case COLOR_SPACE_YCBCR709:
0400         case COLOR_SPACE_YCBCR709_LIMITED:
0401             /* YCbCr709 */
0402             set_reg_field_value(
0403                 value,
0404                 3,
0405                 COL_MAN_OUTPUT_CSC_CONTROL,
0406                 OUTPUT_CSC_MODE);
0407             break;
0408         default:
0409             return false;
0410         }
0411 
0412     } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
0413         switch (color_space) {
0414         case COLOR_SPACE_SRGB:
0415             /* by pass */
0416             set_reg_field_value(
0417                 value,
0418                 0,
0419                 COL_MAN_OUTPUT_CSC_CONTROL,
0420                 OUTPUT_CSC_MODE);
0421             break;
0422         case COLOR_SPACE_SRGB_LIMITED:
0423             /* not supported for underlay on CZ */
0424             return false;
0425         case COLOR_SPACE_YCBCR601:
0426         case COLOR_SPACE_YCBCR601_LIMITED:
0427             /* YCbCr601 */
0428             set_reg_field_value(
0429                 value,
0430                 2,
0431                 COL_MAN_OUTPUT_CSC_CONTROL,
0432                 OUTPUT_CSC_MODE);
0433             break;
0434         case COLOR_SPACE_YCBCR709:
0435         case COLOR_SPACE_YCBCR709_LIMITED:
0436              /* YCbCr709 */
0437             set_reg_field_value(
0438                 value,
0439                 3,
0440                 COL_MAN_OUTPUT_CSC_CONTROL,
0441                 OUTPUT_CSC_MODE);
0442             break;
0443         default:
0444             return false;
0445         }
0446 
0447     } else
0448         /* by pass */
0449         set_reg_field_value(
0450             value,
0451             0,
0452             COL_MAN_OUTPUT_CSC_CONTROL,
0453             OUTPUT_CSC_MODE);
0454 
0455     addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
0456     dm_write_reg(ctx, addr, value);
0457 
0458     return true;
0459 }
0460 
0461 /*TODO: color depth is not correct when this is called*/
0462 static void set_Denormalization(struct transform *xfm,
0463         enum dc_color_depth color_depth)
0464 {
0465     uint32_t value = dm_read_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL);
0466 
0467     switch (color_depth) {
0468     case COLOR_DEPTH_888:
0469         /* 255/256 for 8 bit output color depth */
0470         set_reg_field_value(
0471             value,
0472             1,
0473             DENORM_CLAMP_CONTROL,
0474             DENORM_MODE);
0475         break;
0476     case COLOR_DEPTH_101010:
0477         /* 1023/1024 for 10 bit output color depth */
0478         set_reg_field_value(
0479             value,
0480             2,
0481             DENORM_CLAMP_CONTROL,
0482             DENORM_MODE);
0483         break;
0484     case COLOR_DEPTH_121212:
0485         /* 4095/4096 for 12 bit output color depth */
0486         set_reg_field_value(
0487             value,
0488             3,
0489             DENORM_CLAMP_CONTROL,
0490             DENORM_MODE);
0491         break;
0492     default:
0493         /* not valid case */
0494         break;
0495     }
0496 
0497     set_reg_field_value(
0498         value,
0499         1,
0500         DENORM_CLAMP_CONTROL,
0501         DENORM_10BIT_OUT);
0502 
0503     dm_write_reg(xfm->ctx, mmDENORM_CLAMP_CONTROL, value);
0504 }
0505 
0506 struct input_csc_matrix {
0507     enum dc_color_space color_space;
0508     uint32_t regval[12];
0509 };
0510 
0511 static const struct input_csc_matrix input_csc_matrix[] = {
0512     {COLOR_SPACE_SRGB,
0513 /*1_1   1_2   1_3   1_4   2_1   2_2   2_3   2_4   3_1   3_2   3_3   3_4 */
0514         {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
0515     {COLOR_SPACE_SRGB_LIMITED,
0516         {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
0517     {COLOR_SPACE_YCBCR601,
0518         {0x2cdd, 0x2000, 0x0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef,
0519                         0x0, 0x2000, 0x38b4, 0xe3a6} },
0520     {COLOR_SPACE_YCBCR601_LIMITED,
0521         {0x3353, 0x2568, 0x0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108,
0522                         0x0, 0x2568, 0x40de, 0xdd3a} },
0523     {COLOR_SPACE_YCBCR709,
0524         {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0,
0525                         0x2000, 0x3b61, 0xe24f} },
0526     {COLOR_SPACE_YCBCR709_LIMITED,
0527         {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0,
0528                         0x2568, 0x43ee, 0xdbb2} }
0529 };
0530 
0531 static void program_input_csc(
0532         struct transform *xfm, enum dc_color_space color_space)
0533 {
0534     int arr_size = sizeof(input_csc_matrix)/sizeof(struct input_csc_matrix);
0535     struct dc_context *ctx = xfm->ctx;
0536     const uint32_t *regval = NULL;
0537     bool use_set_a;
0538     uint32_t value;
0539     int i;
0540 
0541     for (i = 0; i < arr_size; i++)
0542         if (input_csc_matrix[i].color_space == color_space) {
0543             regval = input_csc_matrix[i].regval;
0544             break;
0545         }
0546     if (regval == NULL) {
0547         BREAK_TO_DEBUGGER();
0548         return;
0549     }
0550 
0551     /*
0552      * 1 == set A, the logic is 'if currently we're not using set A,
0553      * then use set A, otherwise use set B'
0554      */
0555     value = dm_read_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL);
0556     use_set_a = get_reg_field_value(
0557         value, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_MODE) != 1;
0558 
0559     if (use_set_a) {
0560         /* fixed S2.13 format */
0561         value = 0;
0562         set_reg_field_value(
0563             value, regval[0], INPUT_CSC_C11_C12_A, INPUT_CSC_C11_A);
0564         set_reg_field_value(
0565             value, regval[1], INPUT_CSC_C11_C12_A, INPUT_CSC_C12_A);
0566         dm_write_reg(ctx, mmINPUT_CSC_C11_C12_A, value);
0567 
0568         value = 0;
0569         set_reg_field_value(
0570             value, regval[2], INPUT_CSC_C13_C14_A, INPUT_CSC_C13_A);
0571         set_reg_field_value(
0572             value, regval[3], INPUT_CSC_C13_C14_A, INPUT_CSC_C14_A);
0573         dm_write_reg(ctx, mmINPUT_CSC_C13_C14_A, value);
0574 
0575         value = 0;
0576         set_reg_field_value(
0577             value, regval[4], INPUT_CSC_C21_C22_A, INPUT_CSC_C21_A);
0578         set_reg_field_value(
0579             value, regval[5], INPUT_CSC_C21_C22_A, INPUT_CSC_C22_A);
0580         dm_write_reg(ctx, mmINPUT_CSC_C21_C22_A, value);
0581 
0582         value = 0;
0583         set_reg_field_value(
0584             value, regval[6], INPUT_CSC_C23_C24_A, INPUT_CSC_C23_A);
0585         set_reg_field_value(
0586             value, regval[7], INPUT_CSC_C23_C24_A, INPUT_CSC_C24_A);
0587         dm_write_reg(ctx, mmINPUT_CSC_C23_C24_A, value);
0588 
0589         value = 0;
0590         set_reg_field_value(
0591             value, regval[8], INPUT_CSC_C31_C32_A, INPUT_CSC_C31_A);
0592         set_reg_field_value(
0593             value, regval[9], INPUT_CSC_C31_C32_A, INPUT_CSC_C32_A);
0594         dm_write_reg(ctx, mmINPUT_CSC_C31_C32_A, value);
0595 
0596         value = 0;
0597         set_reg_field_value(
0598             value, regval[10], INPUT_CSC_C33_C34_A, INPUT_CSC_C33_A);
0599         set_reg_field_value(
0600             value, regval[11], INPUT_CSC_C33_C34_A, INPUT_CSC_C34_A);
0601         dm_write_reg(ctx, mmINPUT_CSC_C33_C34_A, value);
0602     } else {
0603         /* fixed S2.13 format */
0604         value = 0;
0605         set_reg_field_value(
0606             value, regval[0], INPUT_CSC_C11_C12_B, INPUT_CSC_C11_B);
0607         set_reg_field_value(
0608             value, regval[1], INPUT_CSC_C11_C12_B, INPUT_CSC_C12_B);
0609         dm_write_reg(ctx, mmINPUT_CSC_C11_C12_B, value);
0610 
0611         value = 0;
0612         set_reg_field_value(
0613             value, regval[2], INPUT_CSC_C13_C14_B, INPUT_CSC_C13_B);
0614         set_reg_field_value(
0615             value, regval[3], INPUT_CSC_C13_C14_B, INPUT_CSC_C14_B);
0616         dm_write_reg(ctx, mmINPUT_CSC_C13_C14_B, value);
0617 
0618         value = 0;
0619         set_reg_field_value(
0620             value, regval[4], INPUT_CSC_C21_C22_B, INPUT_CSC_C21_B);
0621         set_reg_field_value(
0622             value, regval[5], INPUT_CSC_C21_C22_B, INPUT_CSC_C22_B);
0623         dm_write_reg(ctx, mmINPUT_CSC_C21_C22_B, value);
0624 
0625         value = 0;
0626         set_reg_field_value(
0627             value, regval[6], INPUT_CSC_C23_C24_B, INPUT_CSC_C23_B);
0628         set_reg_field_value(
0629             value, regval[7], INPUT_CSC_C23_C24_B, INPUT_CSC_C24_B);
0630         dm_write_reg(ctx, mmINPUT_CSC_C23_C24_B, value);
0631 
0632         value = 0;
0633         set_reg_field_value(
0634             value, regval[8], INPUT_CSC_C31_C32_B, INPUT_CSC_C31_B);
0635         set_reg_field_value(
0636             value, regval[9], INPUT_CSC_C31_C32_B, INPUT_CSC_C32_B);
0637         dm_write_reg(ctx, mmINPUT_CSC_C31_C32_B, value);
0638 
0639         value = 0;
0640         set_reg_field_value(
0641             value, regval[10], INPUT_CSC_C33_C34_B, INPUT_CSC_C33_B);
0642         set_reg_field_value(
0643             value, regval[11], INPUT_CSC_C33_C34_B, INPUT_CSC_C34_B);
0644         dm_write_reg(ctx, mmINPUT_CSC_C33_C34_B, value);
0645     }
0646 
0647     /* KK: leave INPUT_CSC_CONVERSION_MODE at default */
0648     value = 0;
0649     /*
0650      * select 8.4 input type instead of default 12.0. From the discussion
0651      * with HW team, this format depends on the UNP surface format, so for
0652      * 8-bit we should select 8.4 (4 bits truncated). For 10 it should be
0653      * 10.2. For Carrizo we only support 8-bit surfaces on underlay pipe
0654      * so we can always keep this at 8.4 (input_type=2). If the later asics
0655      * start supporting 10+ bits, we will have a problem: surface
0656      * programming including UNP_GRPH* is being done in DalISR after this,
0657      * so either we pass surface format to here, or move this logic to ISR
0658      */
0659 
0660     set_reg_field_value(
0661         value, 2, COL_MAN_INPUT_CSC_CONTROL, INPUT_CSC_INPUT_TYPE);
0662     set_reg_field_value(
0663         value,
0664         use_set_a ? 1 : 2,
0665         COL_MAN_INPUT_CSC_CONTROL,
0666         INPUT_CSC_MODE);
0667 
0668     dm_write_reg(ctx, mmCOL_MAN_INPUT_CSC_CONTROL, value);
0669 }
0670 
0671 void dce110_opp_v_set_csc_default(
0672     struct transform *xfm,
0673     const struct default_adjustment *default_adjust)
0674 {
0675     struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
0676     enum csc_color_mode config =
0677             CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
0678 
0679     if (default_adjust->force_hw_default == false) {
0680         const struct out_csc_color_matrix *elm;
0681         /* currently parameter not in use */
0682         enum grph_color_adjust_option option;
0683         uint32_t i;
0684         /*
0685          * HW default false we program locally defined matrix
0686          * HW default true  we use predefined hw matrix and we
0687          * do not need to program matrix
0688          * OEM wants the HW default via runtime parameter.
0689          */
0690         option = GRPH_COLOR_MATRIX_SW;
0691 
0692         for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
0693             elm = &global_color_matrix[i];
0694             if (elm->color_space != default_adjust->out_color_space)
0695                 continue;
0696             /* program the matrix with default values from this
0697              * file
0698              */
0699             program_color_matrix_v(xfm_dce, elm, option);
0700             config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
0701             break;
0702         }
0703     }
0704 
0705     program_input_csc(xfm, default_adjust->in_color_space);
0706 
0707     /* configure the what we programmed :
0708      * 1. Default values from this file
0709      * 2. Use hardware default from ROM_A and we do not need to program
0710      * matrix
0711      */
0712 
0713     configure_graphics_mode_v(xfm_dce, config,
0714         default_adjust->csc_adjust_type,
0715         default_adjust->out_color_space);
0716 
0717     set_Denormalization(xfm, default_adjust->color_depth);
0718 }
0719 
0720 void dce110_opp_v_set_csc_adjustment(
0721     struct transform *xfm,
0722     const struct out_csc_color_matrix *tbl_entry)
0723 {
0724     struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
0725     enum csc_color_mode config =
0726             CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
0727 
0728     program_color_matrix_v(
0729             xfm_dce, tbl_entry, GRPH_COLOR_MATRIX_SW);
0730 
0731     /*  We did everything ,now program DxOUTPUT_CSC_CONTROL */
0732     configure_graphics_mode_v(xfm_dce, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
0733             tbl_entry->color_space);
0734 
0735     /*TODO: Check if denormalization is needed*/
0736     /*set_Denormalization(opp, adjust->color_depth);*/
0737 }