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