1 /* 2 * Copyright 2016 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 28 #include "core_types.h" 29 30 #include "include/grph_object_id.h" 31 #include "include/fixed31_32.h" 32 #include "include/logger_interface.h" 33 34 #include "reg_helper.h" 35 #include "dcn10_dpp.h" 36 #include "basics/conversion.h" 37 38 #define NUM_PHASES 64 39 #define HORZ_MAX_TAPS 8 40 #define VERT_MAX_TAPS 8 41 42 #define BLACK_OFFSET_RGB_Y 0x0 43 #define BLACK_OFFSET_CBCR 0x8000 44 45 #define REG(reg)\ 46 xfm->tf_regs->reg 47 48 #define CTX \ 49 xfm->base.ctx 50 51 #undef FN 52 #define FN(reg_name, field_name) \ 53 xfm->tf_shift->field_name, xfm->tf_mask->field_name 54 55 56 enum dcn10_coef_filter_type_sel { 57 SCL_COEF_LUMA_VERT_FILTER = 0, 58 SCL_COEF_LUMA_HORZ_FILTER = 1, 59 SCL_COEF_CHROMA_VERT_FILTER = 2, 60 SCL_COEF_CHROMA_HORZ_FILTER = 3, 61 SCL_COEF_ALPHA_VERT_FILTER = 4, 62 SCL_COEF_ALPHA_HORZ_FILTER = 5 63 }; 64 65 enum lb_memory_config { 66 /* Enable all 3 pieces of memory */ 67 LB_MEMORY_CONFIG_0 = 0, 68 69 /* Enable only the first piece of memory */ 70 LB_MEMORY_CONFIG_1 = 1, 71 72 /* Enable only the second piece of memory */ 73 LB_MEMORY_CONFIG_2 = 2, 74 75 /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the 76 * last piece of chroma memory used for the luma storage 77 */ 78 LB_MEMORY_CONFIG_3 = 3 79 }; 80 81 enum dscl_autocal_mode { 82 AUTOCAL_MODE_OFF = 0, 83 84 /* Autocal calculate the scaling ratio and initial phase and the 85 * DSCL_MODE_SEL must be set to 1 86 */ 87 AUTOCAL_MODE_AUTOSCALE = 1, 88 /* Autocal perform auto centering without replication and the 89 * DSCL_MODE_SEL must be set to 0 90 */ 91 AUTOCAL_MODE_AUTOCENTER = 2, 92 /* Autocal perform auto centering and auto replication and the 93 * DSCL_MODE_SEL must be set to 0 94 */ 95 AUTOCAL_MODE_AUTOREPLICATE = 3 96 }; 97 98 enum dscl_mode_sel { 99 DSCL_MODE_SCALING_444_BYPASS = 0, 100 DSCL_MODE_SCALING_444_RGB_ENABLE = 1, 101 DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2, 102 DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3, 103 DSCL_MODE_SCALING_420_LUMA_BYPASS = 4, 104 DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5, 105 DSCL_MODE_DSCL_BYPASS = 6 106 }; 107 108 enum gamut_remap_select { 109 GAMUT_REMAP_BYPASS = 0, 110 GAMUT_REMAP_COEFF, 111 GAMUT_REMAP_COMA_COEFF, 112 GAMUT_REMAP_COMB_COEFF 113 }; 114 115 static void dpp_set_overscan( 116 struct dcn10_dpp *xfm, 117 const struct scaler_data *data) 118 { 119 uint32_t left = data->recout.x; 120 uint32_t top = data->recout.y; 121 122 int right = data->h_active - data->recout.x - data->recout.width; 123 int bottom = data->v_active - data->recout.y - data->recout.height; 124 125 if (right < 0) { 126 BREAK_TO_DEBUGGER(); 127 right = 0; 128 } 129 if (bottom < 0) { 130 BREAK_TO_DEBUGGER(); 131 bottom = 0; 132 } 133 134 REG_SET_2(DSCL_EXT_OVERSCAN_LEFT_RIGHT, 0, 135 EXT_OVERSCAN_LEFT, left, 136 EXT_OVERSCAN_RIGHT, right); 137 138 REG_SET_2(DSCL_EXT_OVERSCAN_TOP_BOTTOM, 0, 139 EXT_OVERSCAN_BOTTOM, bottom, 140 EXT_OVERSCAN_TOP, top); 141 } 142 143 static void dpp_set_otg_blank( 144 struct dcn10_dpp *xfm, const struct scaler_data *data) 145 { 146 uint32_t h_blank_start = data->h_active; 147 uint32_t h_blank_end = 0; 148 uint32_t v_blank_start = data->v_active; 149 uint32_t v_blank_end = 0; 150 151 REG_SET_2(OTG_H_BLANK, 0, 152 OTG_H_BLANK_START, h_blank_start, 153 OTG_H_BLANK_END, h_blank_end); 154 155 REG_SET_2(OTG_V_BLANK, 0, 156 OTG_V_BLANK_START, v_blank_start, 157 OTG_V_BLANK_END, v_blank_end); 158 } 159 160 static enum dscl_mode_sel get_dscl_mode( 161 const struct scaler_data *data, bool dbg_always_scale) 162 { 163 const long long one = dal_fixed31_32_one.value; 164 bool ycbcr = false; 165 bool format420 = false; 166 167 if (data->format == PIXEL_FORMAT_FP16) 168 return DSCL_MODE_DSCL_BYPASS; 169 170 if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN 171 && data->format <= PIXEL_FORMAT_VIDEO_END) 172 ycbcr = true; 173 174 if (data->format == PIXEL_FORMAT_420BPP8 || 175 data->format == PIXEL_FORMAT_420BPP10) 176 format420 = true; 177 178 if (data->ratios.horz.value == one 179 && data->ratios.vert.value == one 180 && data->ratios.horz_c.value == one 181 && data->ratios.vert_c.value == one 182 && !dbg_always_scale) 183 return DSCL_MODE_SCALING_444_BYPASS; 184 185 if (!format420) { 186 if (ycbcr) 187 return DSCL_MODE_SCALING_444_YCBCR_ENABLE; 188 else 189 return DSCL_MODE_SCALING_444_RGB_ENABLE; 190 } 191 if (data->ratios.horz.value == one && data->ratios.vert.value == one) 192 return DSCL_MODE_SCALING_420_LUMA_BYPASS; 193 if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) 194 return DSCL_MODE_SCALING_420_CHROMA_BYPASS; 195 196 return DSCL_MODE_SCALING_420_YCBCR_ENABLE; 197 } 198 199 static int get_pixel_depth_val(enum lb_pixel_depth depth) 200 { 201 if (depth == LB_PIXEL_DEPTH_30BPP) 202 return 0; /* 10 bpc */ 203 else if (depth == LB_PIXEL_DEPTH_24BPP) 204 return 1; /* 8 bpc */ 205 else if (depth == LB_PIXEL_DEPTH_18BPP) 206 return 2; /* 6 bpc */ 207 else if (depth == LB_PIXEL_DEPTH_36BPP) 208 return 3; /* 12 bpc */ 209 else { 210 ASSERT(0); 211 return -1; /* Unsupported */ 212 } 213 } 214 215 static void dpp_set_lb( 216 struct dcn10_dpp *xfm, 217 const struct line_buffer_params *lb_params, 218 enum lb_memory_config mem_size_config) 219 { 220 uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); 221 uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; 222 REG_SET_7(LB_DATA_FORMAT, 0, 223 PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ 224 PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ 225 PIXEL_REDUCE_MODE, 1, /* Pixel reduction mode: Rounding */ 226 DYNAMIC_PIXEL_DEPTH, dyn_pix_depth, /* Dynamic expansion pixel depth */ 227 DITHER_EN, 0, /* Dithering enable: Disabled */ 228 INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */ 229 ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ 230 231 REG_SET_2(LB_MEMORY_CTRL, 0, 232 MEMORY_CONFIG, mem_size_config, 233 LB_MAX_PARTITIONS, 63); 234 } 235 236 static void dpp_set_scaler_filter( 237 struct dcn10_dpp *xfm, 238 uint32_t taps, 239 enum dcn10_coef_filter_type_sel filter_type, 240 const uint16_t *filter) 241 { 242 const int tap_pairs = (taps + 1) / 2; 243 int phase; 244 int pair; 245 uint16_t odd_coef, even_coef; 246 247 REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0, 248 SCL_COEF_RAM_TAP_PAIR_IDX, 0, 249 SCL_COEF_RAM_PHASE, 0, 250 SCL_COEF_RAM_FILTER_TYPE, filter_type); 251 252 for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { 253 for (pair = 0; pair < tap_pairs; pair++) { 254 even_coef = filter[phase * taps + 2 * pair]; 255 if ((pair * 2 + 1) < taps) 256 odd_coef = filter[phase * taps + 2 * pair + 1]; 257 else 258 odd_coef = 0; 259 260 REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0, 261 /* Even tap coefficient (bits 1:0 fixed to 0) */ 262 SCL_COEF_RAM_EVEN_TAP_COEF, even_coef, 263 /* Write/read control for even coefficient */ 264 SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1, 265 /* Odd tap coefficient (bits 1:0 fixed to 0) */ 266 SCL_COEF_RAM_ODD_TAP_COEF, odd_coef, 267 /* Write/read control for odd coefficient */ 268 SCL_COEF_RAM_ODD_TAP_COEF_EN, 1); 269 } 270 } 271 272 } 273 274 #if 0 275 bool dpp_set_pixel_storage_depth( 276 struct dpp *xfm, 277 enum lb_pixel_depth depth, 278 const struct bit_depth_reduction_params *bit_depth_params) 279 { 280 struct dcn10_dpp *xfm110 = TO_DCN10_DPP(xfm); 281 bool ret = true; 282 uint32_t value; 283 enum dc_color_depth color_depth; 284 285 value = dm_read_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT)); 286 switch (depth) { 287 case LB_PIXEL_DEPTH_18BPP: 288 color_depth = COLOR_DEPTH_666; 289 set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH); 290 set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 291 break; 292 case LB_PIXEL_DEPTH_24BPP: 293 color_depth = COLOR_DEPTH_888; 294 set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH); 295 set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 296 break; 297 case LB_PIXEL_DEPTH_30BPP: 298 color_depth = COLOR_DEPTH_101010; 299 set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH); 300 set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 301 break; 302 case LB_PIXEL_DEPTH_36BPP: 303 color_depth = COLOR_DEPTH_121212; 304 set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH); 305 set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 306 break; 307 default: 308 ret = false; 309 break; 310 } 311 312 if (ret == true) { 313 set_denormalization(xfm110, color_depth); 314 ret = program_bit_depth_reduction(xfm110, color_depth, 315 bit_depth_params); 316 317 set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN); 318 dm_write_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value); 319 if (!(xfm110->lb_pixel_depth_supported & depth)) { 320 /* We should use unsupported capabilities 321 * unless it is required by w/a 322 */ 323 dm_logger_write(xfm->ctx->logger, LOG_WARNING, 324 "%s: Capability not supported", 325 __func__); 326 } 327 } 328 329 return ret; 330 } 331 #endif 332 333 static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) 334 { 335 if (taps == 8) 336 return get_filter_8tap_64p(ratio); 337 else if (taps == 7) 338 return get_filter_7tap_64p(ratio); 339 else if (taps == 6) 340 return get_filter_6tap_64p(ratio); 341 else if (taps == 5) 342 return get_filter_5tap_64p(ratio); 343 else if (taps == 4) 344 return get_filter_4tap_64p(ratio); 345 else if (taps == 3) 346 return get_filter_3tap_64p(ratio); 347 else if (taps == 2) 348 return filter_2tap_64p; 349 else if (taps == 1) 350 return NULL; 351 else { 352 /* should never happen, bug */ 353 BREAK_TO_DEBUGGER(); 354 return NULL; 355 } 356 } 357 358 static void dpp_set_scl_filter( 359 struct dcn10_dpp *xfm, 360 const struct scaler_data *scl_data, 361 bool chroma_coef_mode) 362 { 363 bool h_2tap_hardcode_coef_en = false; 364 bool v_2tap_hardcode_coef_en = false; 365 bool h_2tap_sharp_en = false; 366 bool v_2tap_sharp_en = false; 367 uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz; 368 uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert; 369 bool coef_ram_current; 370 const uint16_t *filter_h = NULL; 371 const uint16_t *filter_v = NULL; 372 const uint16_t *filter_h_c = NULL; 373 const uint16_t *filter_v_c = NULL; 374 375 h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 376 && scl_data->taps.h_taps_c < 3 377 && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); 378 v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 379 && scl_data->taps.v_taps_c < 3 380 && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); 381 382 h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; 383 v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; 384 385 REG_UPDATE_6(DSCL_2TAP_CONTROL, 386 SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en, 387 SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en, 388 SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor, 389 SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en, 390 SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en, 391 SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor); 392 393 if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { 394 bool filter_updated = false; 395 396 filter_h = get_filter_coeffs_64p( 397 scl_data->taps.h_taps, scl_data->ratios.horz); 398 filter_v = get_filter_coeffs_64p( 399 scl_data->taps.v_taps, scl_data->ratios.vert); 400 401 filter_updated = (filter_h && (filter_h != xfm->filter_h)) 402 || (filter_v && (filter_v != xfm->filter_v)); 403 404 if (chroma_coef_mode) { 405 filter_h_c = get_filter_coeffs_64p( 406 scl_data->taps.h_taps_c, scl_data->ratios.horz_c); 407 filter_v_c = get_filter_coeffs_64p( 408 scl_data->taps.v_taps_c, scl_data->ratios.vert_c); 409 filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) 410 || (filter_v_c && (filter_v_c != xfm->filter_v_c)); 411 } 412 413 if (filter_updated) { 414 uint32_t scl_mode = REG_READ(SCL_MODE); 415 416 if (!h_2tap_hardcode_coef_en && filter_h) { 417 dpp_set_scaler_filter( 418 xfm, scl_data->taps.h_taps, 419 SCL_COEF_LUMA_HORZ_FILTER, filter_h); 420 } 421 xfm->filter_h = filter_h; 422 if (!v_2tap_hardcode_coef_en && filter_v) { 423 dpp_set_scaler_filter( 424 xfm, scl_data->taps.v_taps, 425 SCL_COEF_LUMA_VERT_FILTER, filter_v); 426 } 427 xfm->filter_v = filter_v; 428 if (chroma_coef_mode) { 429 if (!h_2tap_hardcode_coef_en && filter_h_c) { 430 dpp_set_scaler_filter( 431 xfm, scl_data->taps.h_taps_c, 432 SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); 433 } 434 if (!v_2tap_hardcode_coef_en && filter_v_c) { 435 dpp_set_scaler_filter( 436 xfm, scl_data->taps.v_taps_c, 437 SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); 438 } 439 } 440 xfm->filter_h_c = filter_h_c; 441 xfm->filter_v_c = filter_v_c; 442 443 coef_ram_current = get_reg_field_value_ex( 444 scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, 445 xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); 446 447 /* Swap coefficient RAM and set chroma coefficient mode */ 448 REG_SET_2(SCL_MODE, scl_mode, 449 SCL_COEF_RAM_SELECT, !coef_ram_current, 450 SCL_CHROMA_COEF_MODE, chroma_coef_mode); 451 } 452 } 453 } 454 455 456 static int get_lb_depth_bpc(enum lb_pixel_depth depth) 457 { 458 if (depth == LB_PIXEL_DEPTH_30BPP) 459 return 10; 460 else if (depth == LB_PIXEL_DEPTH_24BPP) 461 return 8; 462 else if (depth == LB_PIXEL_DEPTH_18BPP) 463 return 6; 464 else if (depth == LB_PIXEL_DEPTH_36BPP) 465 return 12; 466 else { 467 BREAK_TO_DEBUGGER(); 468 return -1; /* Unsupported */ 469 } 470 } 471 472 static void calc_lb_num_partitions( 473 const struct scaler_data *scl_data, 474 enum lb_memory_config lb_config, 475 int *num_part_y, 476 int *num_part_c) 477 { 478 int line_size = scl_data->viewport.width < scl_data->recout.width ? 479 scl_data->viewport.width : scl_data->recout.width; 480 int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? 481 scl_data->viewport_c.width : scl_data->recout.width; 482 int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); 483 int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ 484 int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ 485 int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ 486 int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a; 487 488 if (lb_config == LB_MEMORY_CONFIG_1) { 489 lb_memory_size = 816; 490 lb_memory_size_c = 816; 491 lb_memory_size_a = 984; 492 } else if (lb_config == LB_MEMORY_CONFIG_2) { 493 lb_memory_size = 1088; 494 lb_memory_size_c = 1088; 495 lb_memory_size_a = 1312; 496 } else if (lb_config == LB_MEMORY_CONFIG_3) { 497 lb_memory_size = 816 + 1088 + 848 + 848 + 848; 498 lb_memory_size_c = 816 + 1088; 499 lb_memory_size_a = 984 + 1312 + 456; 500 } else { 501 lb_memory_size = 816 + 1088 + 848; 502 lb_memory_size_c = 816 + 1088 + 848; 503 lb_memory_size_a = 984 + 1312 + 456; 504 } 505 *num_part_y = lb_memory_size / memory_line_size_y; 506 *num_part_c = lb_memory_size_c / memory_line_size_c; 507 num_partitions_a = lb_memory_size_a / memory_line_size_a; 508 509 if (scl_data->lb_params.alpha_en 510 && (num_partitions_a < *num_part_y)) 511 *num_part_y = num_partitions_a; 512 513 if (*num_part_y > 64) 514 *num_part_y = 64; 515 if (*num_part_c > 64) 516 *num_part_c = 64; 517 518 } 519 520 static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) 521 { 522 if (ceil_vratio > 2) 523 return vtaps <= (num_partitions - ceil_vratio + 2); 524 else 525 return vtaps <= num_partitions; 526 } 527 528 /*find first match configuration which meets the min required lb size*/ 529 static enum lb_memory_config find_lb_memory_config(const struct scaler_data *scl_data) 530 { 531 int num_part_y, num_part_c; 532 int vtaps = scl_data->taps.v_taps; 533 int vtaps_c = scl_data->taps.v_taps_c; 534 int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); 535 int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); 536 537 calc_lb_num_partitions( 538 scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); 539 540 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 541 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 542 return LB_MEMORY_CONFIG_1; 543 544 calc_lb_num_partitions( 545 scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); 546 547 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 548 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 549 return LB_MEMORY_CONFIG_2; 550 551 if (scl_data->format == PIXEL_FORMAT_420BPP8 552 || scl_data->format == PIXEL_FORMAT_420BPP10) { 553 calc_lb_num_partitions( 554 scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); 555 556 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 557 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 558 return LB_MEMORY_CONFIG_3; 559 } 560 561 calc_lb_num_partitions( 562 scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); 563 564 /*Ensure we can support the requested number of vtaps*/ 565 ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 566 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); 567 568 return LB_MEMORY_CONFIG_0; 569 } 570 571 void dpp_set_scaler_auto_scale( 572 struct transform *xfm_base, 573 const struct scaler_data *scl_data) 574 { 575 enum lb_memory_config lb_config; 576 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 577 enum dscl_mode_sel dscl_mode = get_dscl_mode( 578 scl_data, xfm_base->ctx->dc->debug.always_scale); 579 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 580 && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 581 582 dpp_set_overscan(xfm, scl_data); 583 584 dpp_set_otg_blank(xfm, scl_data); 585 586 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); 587 588 if (dscl_mode == DSCL_MODE_DSCL_BYPASS) 589 return; 590 591 lb_config = find_lb_memory_config(scl_data); 592 dpp_set_lb(xfm, &scl_data->lb_params, lb_config); 593 594 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 595 return; 596 597 /* TODO: v_min */ 598 REG_SET_3(DSCL_AUTOCAL, 0, 599 AUTOCAL_MODE, AUTOCAL_MODE_AUTOSCALE, 600 AUTOCAL_NUM_PIPE, 0, 601 AUTOCAL_PIPE_ID, 0); 602 603 /* Black offsets */ 604 if (ycbcr) 605 REG_SET_2(SCL_BLACK_OFFSET, 0, 606 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 607 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); 608 else 609 610 REG_SET_2(SCL_BLACK_OFFSET, 0, 611 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 612 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); 613 614 REG_SET_4(SCL_TAP_CONTROL, 0, 615 SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, 616 SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, 617 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 618 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 619 620 dpp_set_scl_filter(xfm, scl_data, ycbcr); 621 } 622 623 /* Program gamut remap in bypass mode */ 624 void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) 625 { 626 REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 627 CM_GAMUT_REMAP_MODE, 0); 628 /* Gamut remap in bypass */ 629 } 630 631 static void dpp_set_recout( 632 struct dcn10_dpp *xfm, const struct rect *recout) 633 { 634 REG_SET_2(RECOUT_START, 0, 635 /* First pixel of RECOUT */ 636 RECOUT_START_X, recout->x, 637 /* First line of RECOUT */ 638 RECOUT_START_Y, recout->y); 639 640 REG_SET_2(RECOUT_SIZE, 0, 641 /* Number of RECOUT horizontal pixels */ 642 RECOUT_WIDTH, recout->width, 643 /* Number of RECOUT vertical lines */ 644 RECOUT_HEIGHT, recout->height 645 - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 * 646 (xfm->base.inst + 1)); 647 } 648 649 static void dpp_set_manual_ratio_init( 650 struct dcn10_dpp *xfm, const struct scaler_data *data) 651 { 652 uint32_t init_frac = 0; 653 uint32_t init_int = 0; 654 655 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, 656 SCL_H_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.horz) << 5); 657 658 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, 659 SCL_V_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.vert) << 5); 660 661 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, 662 SCL_H_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.horz_c) << 5); 663 664 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, 665 SCL_V_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.vert_c) << 5); 666 667 /* 668 * 0.24 format for fraction, first five bits zeroed 669 */ 670 init_frac = dal_fixed31_32_u0d19(data->inits.h) << 5; 671 init_int = dal_fixed31_32_floor(data->inits.h); 672 REG_SET_2(SCL_HORZ_FILTER_INIT, 0, 673 SCL_H_INIT_FRAC, init_frac, 674 SCL_H_INIT_INT, init_int); 675 676 init_frac = dal_fixed31_32_u0d19(data->inits.h_c) << 5; 677 init_int = dal_fixed31_32_floor(data->inits.h_c); 678 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0, 679 SCL_H_INIT_FRAC_C, init_frac, 680 SCL_H_INIT_INT_C, init_int); 681 682 init_frac = dal_fixed31_32_u0d19(data->inits.v) << 5; 683 init_int = dal_fixed31_32_floor(data->inits.v); 684 REG_SET_2(SCL_VERT_FILTER_INIT, 0, 685 SCL_V_INIT_FRAC, init_frac, 686 SCL_V_INIT_INT, init_int); 687 688 init_frac = dal_fixed31_32_u0d19(data->inits.v_bot) << 5; 689 init_int = dal_fixed31_32_floor(data->inits.v_bot); 690 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0, 691 SCL_V_INIT_FRAC_BOT, init_frac, 692 SCL_V_INIT_INT_BOT, init_int); 693 694 init_frac = dal_fixed31_32_u0d19(data->inits.v_c) << 5; 695 init_int = dal_fixed31_32_floor(data->inits.v_c); 696 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0, 697 SCL_V_INIT_FRAC_C, init_frac, 698 SCL_V_INIT_INT_C, init_int); 699 700 init_frac = dal_fixed31_32_u0d19(data->inits.v_c_bot) << 5; 701 init_int = dal_fixed31_32_floor(data->inits.v_c_bot); 702 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0, 703 SCL_V_INIT_FRAC_BOT_C, init_frac, 704 SCL_V_INIT_INT_BOT_C, init_int); 705 } 706 707 /* Main function to program scaler and line buffer in manual scaling mode */ 708 static void dpp_set_scaler_manual_scale( 709 struct transform *xfm_base, 710 const struct scaler_data *scl_data) 711 { 712 enum lb_memory_config lb_config; 713 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 714 enum dscl_mode_sel dscl_mode = get_dscl_mode( 715 scl_data, xfm_base->ctx->dc->debug.always_scale); 716 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 717 && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 718 719 /* Recout */ 720 dpp_set_recout(xfm, &scl_data->recout); 721 722 /* MPC Size */ 723 REG_SET_2(MPC_SIZE, 0, 724 /* Number of horizontal pixels of MPC */ 725 MPC_WIDTH, scl_data->h_active, 726 /* Number of vertical lines of MPC */ 727 MPC_HEIGHT, scl_data->v_active); 728 729 /* SCL mode */ 730 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); 731 732 if (dscl_mode == DSCL_MODE_DSCL_BYPASS) 733 return; 734 /* LB */ 735 lb_config = find_lb_memory_config(scl_data); 736 dpp_set_lb(xfm, &scl_data->lb_params, lb_config); 737 738 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 739 return; 740 741 /* Autocal off */ 742 REG_SET_3(DSCL_AUTOCAL, 0, 743 AUTOCAL_MODE, AUTOCAL_MODE_OFF, 744 AUTOCAL_NUM_PIPE, 0, 745 AUTOCAL_PIPE_ID, 0); 746 747 /* Black offsets */ 748 if (ycbcr) 749 REG_SET_2(SCL_BLACK_OFFSET, 0, 750 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 751 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); 752 else 753 754 REG_SET_2(SCL_BLACK_OFFSET, 0, 755 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 756 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); 757 758 /* Manually calculate scale ratio and init values */ 759 dpp_set_manual_ratio_init(xfm, scl_data); 760 761 /* HTaps/VTaps */ 762 REG_SET_4(SCL_TAP_CONTROL, 0, 763 SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, 764 SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, 765 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 766 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 767 768 dpp_set_scl_filter(xfm, scl_data, ycbcr); 769 } 770 771 #define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) 772 773 774 static bool dpp_get_optimal_number_of_taps( 775 struct transform *xfm, 776 struct scaler_data *scl_data, 777 const struct scaling_taps *in_taps) 778 { 779 uint32_t pixel_width; 780 781 if (scl_data->viewport.width > scl_data->recout.width) 782 pixel_width = scl_data->recout.width; 783 else 784 pixel_width = scl_data->viewport.width; 785 786 /* TODO: add lb check */ 787 788 /* No support for programming ratio of 4, drop to 3.99999.. */ 789 if (scl_data->ratios.horz.value == (4ll << 32)) 790 scl_data->ratios.horz.value--; 791 if (scl_data->ratios.vert.value == (4ll << 32)) 792 scl_data->ratios.vert.value--; 793 if (scl_data->ratios.horz_c.value == (4ll << 32)) 794 scl_data->ratios.horz_c.value--; 795 if (scl_data->ratios.vert_c.value == (4ll << 32)) 796 scl_data->ratios.vert_c.value--; 797 798 /* Set default taps if none are provided */ 799 if (in_taps->h_taps == 0) 800 scl_data->taps.h_taps = 4; 801 else 802 scl_data->taps.h_taps = in_taps->h_taps; 803 if (in_taps->v_taps == 0) 804 scl_data->taps.v_taps = 4; 805 else 806 scl_data->taps.v_taps = in_taps->v_taps; 807 if (in_taps->v_taps_c == 0) 808 scl_data->taps.v_taps_c = 2; 809 else 810 scl_data->taps.v_taps_c = in_taps->v_taps_c; 811 if (in_taps->h_taps_c == 0) 812 scl_data->taps.h_taps_c = 2; 813 /* Only 1 and even h_taps_c are supported by hw */ 814 else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1) 815 scl_data->taps.h_taps_c = in_taps->h_taps_c - 1; 816 else 817 scl_data->taps.h_taps_c = in_taps->h_taps_c; 818 819 if (!xfm->ctx->dc->debug.always_scale) { 820 if (IDENTITY_RATIO(scl_data->ratios.horz)) 821 scl_data->taps.h_taps = 1; 822 if (IDENTITY_RATIO(scl_data->ratios.vert)) 823 scl_data->taps.v_taps = 1; 824 if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 825 scl_data->taps.h_taps_c = 1; 826 if (IDENTITY_RATIO(scl_data->ratios.vert_c)) 827 scl_data->taps.v_taps_c = 1; 828 } 829 830 return true; 831 } 832 833 static void dpp_reset(struct transform *xfm_base) 834 { 835 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 836 837 xfm->filter_h_c = NULL; 838 xfm->filter_v_c = NULL; 839 xfm->filter_h = NULL; 840 xfm->filter_v = NULL; 841 842 /* set boundary mode to 0 */ 843 REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0); 844 } 845 846 static void program_gamut_remap( 847 struct dcn10_dpp *xfm, 848 const uint16_t *regval, 849 enum gamut_remap_select select) 850 { 851 uint16_t selection = 0; 852 853 if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 854 REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 855 CM_GAMUT_REMAP_MODE, 0); 856 return; 857 } 858 switch (select) { 859 case GAMUT_REMAP_COEFF: 860 selection = 1; 861 break; 862 case GAMUT_REMAP_COMA_COEFF: 863 selection = 2; 864 break; 865 case GAMUT_REMAP_COMB_COEFF: 866 selection = 3; 867 break; 868 default: 869 break; 870 } 871 872 873 if (select == GAMUT_REMAP_COEFF) { 874 875 REG_SET_2(CM_GAMUT_REMAP_C11_C12, 0, 876 CM_GAMUT_REMAP_C11, regval[0], 877 CM_GAMUT_REMAP_C12, regval[1]); 878 regval += 2; 879 REG_SET_2(CM_GAMUT_REMAP_C13_C14, 0, 880 CM_GAMUT_REMAP_C13, regval[0], 881 CM_GAMUT_REMAP_C14, regval[1]); 882 regval += 2; 883 REG_SET_2(CM_GAMUT_REMAP_C21_C22, 0, 884 CM_GAMUT_REMAP_C21, regval[0], 885 CM_GAMUT_REMAP_C22, regval[1]); 886 regval += 2; 887 REG_SET_2(CM_GAMUT_REMAP_C23_C24, 0, 888 CM_GAMUT_REMAP_C23, regval[0], 889 CM_GAMUT_REMAP_C24, regval[1]); 890 regval += 2; 891 REG_SET_2(CM_GAMUT_REMAP_C31_C32, 0, 892 CM_GAMUT_REMAP_C31, regval[0], 893 CM_GAMUT_REMAP_C32, regval[1]); 894 regval += 2; 895 REG_SET_2(CM_GAMUT_REMAP_C33_C34, 0, 896 CM_GAMUT_REMAP_C33, regval[0], 897 CM_GAMUT_REMAP_C34, regval[1]); 898 899 } else if (select == GAMUT_REMAP_COMA_COEFF) { 900 REG_SET_2(CM_COMA_C11_C12, 0, 901 CM_COMA_C11, regval[0], 902 CM_COMA_C12, regval[1]); 903 regval += 2; 904 REG_SET_2(CM_COMA_C13_C14, 0, 905 CM_COMA_C13, regval[0], 906 CM_COMA_C14, regval[1]); 907 regval += 2; 908 REG_SET_2(CM_COMA_C21_C22, 0, 909 CM_COMA_C21, regval[0], 910 CM_COMA_C22, regval[1]); 911 regval += 2; 912 REG_SET_2(CM_COMA_C23_C24, 0, 913 CM_COMA_C23, regval[0], 914 CM_COMA_C24, regval[1]); 915 regval += 2; 916 REG_SET_2(CM_COMA_C31_C32, 0, 917 CM_COMA_C31, regval[0], 918 CM_COMA_C32, regval[1]); 919 regval += 2; 920 REG_SET_2(CM_COMA_C33_C34, 0, 921 CM_COMA_C33, regval[0], 922 CM_COMA_C34, regval[1]); 923 924 } else { 925 REG_SET_2(CM_COMB_C11_C12, 0, 926 CM_COMB_C11, regval[0], 927 CM_COMB_C12, regval[1]); 928 regval += 2; 929 REG_SET_2(CM_COMB_C13_C14, 0, 930 CM_COMB_C13, regval[0], 931 CM_COMB_C14, regval[1]); 932 regval += 2; 933 REG_SET_2(CM_COMB_C21_C22, 0, 934 CM_COMB_C21, regval[0], 935 CM_COMB_C22, regval[1]); 936 regval += 2; 937 REG_SET_2(CM_COMB_C23_C24, 0, 938 CM_COMB_C23, regval[0], 939 CM_COMB_C24, regval[1]); 940 regval += 2; 941 REG_SET_2(CM_COMB_C31_C32, 0, 942 CM_COMB_C31, regval[0], 943 CM_COMB_C32, regval[1]); 944 regval += 2; 945 REG_SET_2(CM_COMB_C33_C34, 0, 946 CM_COMB_C33, regval[0], 947 CM_COMB_C34, regval[1]); 948 } 949 950 REG_SET( 951 CM_GAMUT_REMAP_CONTROL, 0, 952 CM_GAMUT_REMAP_MODE, selection); 953 954 } 955 956 static void dcn_dpp_set_gamut_remap( 957 struct transform *xfm, 958 const struct xfm_grph_csc_adjustment *adjust) 959 { 960 struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm); 961 962 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 963 /* Bypass if type is bypass or hw */ 964 program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS); 965 else { 966 struct fixed31_32 arr_matrix[12]; 967 uint16_t arr_reg_val[12]; 968 969 arr_matrix[0] = adjust->temperature_matrix[0]; 970 arr_matrix[1] = adjust->temperature_matrix[1]; 971 arr_matrix[2] = adjust->temperature_matrix[2]; 972 arr_matrix[3] = dal_fixed31_32_zero; 973 974 arr_matrix[4] = adjust->temperature_matrix[3]; 975 arr_matrix[5] = adjust->temperature_matrix[4]; 976 arr_matrix[6] = adjust->temperature_matrix[5]; 977 arr_matrix[7] = dal_fixed31_32_zero; 978 979 arr_matrix[8] = adjust->temperature_matrix[6]; 980 arr_matrix[9] = adjust->temperature_matrix[7]; 981 arr_matrix[10] = adjust->temperature_matrix[8]; 982 arr_matrix[11] = dal_fixed31_32_zero; 983 984 convert_float_matrix( 985 arr_reg_val, arr_matrix, 12); 986 987 program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF); 988 } 989 } 990 991 static void oppn10_set_output_csc_default( 992 struct transform *xfm_base, 993 const struct default_adjustment *default_adjust) 994 { 995 996 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 997 uint32_t ocsc_mode = 0; 998 999 if (default_adjust != NULL) { 1000 switch (default_adjust->out_color_space) { 1001 case COLOR_SPACE_SRGB: 1002 case COLOR_SPACE_2020_RGB_FULLRANGE: 1003 ocsc_mode = 0; 1004 break; 1005 case COLOR_SPACE_SRGB_LIMITED: 1006 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 1007 ocsc_mode = 1; 1008 break; 1009 case COLOR_SPACE_YCBCR601: 1010 case COLOR_SPACE_YCBCR601_LIMITED: 1011 ocsc_mode = 2; 1012 break; 1013 case COLOR_SPACE_YCBCR709: 1014 case COLOR_SPACE_YCBCR709_LIMITED: 1015 case COLOR_SPACE_2020_YCBCR: 1016 ocsc_mode = 3; 1017 break; 1018 case COLOR_SPACE_UNKNOWN: 1019 default: 1020 break; 1021 } 1022 } 1023 1024 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); 1025 1026 } 1027 1028 static void oppn10_program_color_matrix( 1029 struct dcn10_dpp *xfm, 1030 const struct out_csc_color_matrix *tbl_entry) 1031 { 1032 uint32_t mode; 1033 1034 REG_GET(CM_OCSC_CONTROL, CM_OCSC_MODE, &mode); 1035 1036 if (tbl_entry == NULL) { 1037 BREAK_TO_DEBUGGER(); 1038 return; 1039 } 1040 1041 if (mode == 4) { 1042 /*R*/ 1043 REG_SET_2(CM_OCSC_C11_C12, 0, 1044 CM_OCSC_C11, tbl_entry->regval[0], 1045 CM_OCSC_C12, tbl_entry->regval[1]); 1046 1047 REG_SET_2(CM_OCSC_C13_C14, 0, 1048 CM_OCSC_C13, tbl_entry->regval[2], 1049 CM_OCSC_C14, tbl_entry->regval[3]); 1050 1051 /*G*/ 1052 REG_SET_2(CM_OCSC_C21_C22, 0, 1053 CM_OCSC_C21, tbl_entry->regval[4], 1054 CM_OCSC_C22, tbl_entry->regval[5]); 1055 1056 REG_SET_2(CM_OCSC_C23_C24, 0, 1057 CM_OCSC_C23, tbl_entry->regval[6], 1058 CM_OCSC_C24, tbl_entry->regval[7]); 1059 1060 /*B*/ 1061 REG_SET_2(CM_OCSC_C31_C32, 0, 1062 CM_OCSC_C31, tbl_entry->regval[8], 1063 CM_OCSC_C32, tbl_entry->regval[9]); 1064 1065 REG_SET_2(CM_OCSC_C33_C34, 0, 1066 CM_OCSC_C33, tbl_entry->regval[10], 1067 CM_OCSC_C34, tbl_entry->regval[11]); 1068 } else { 1069 /*R*/ 1070 REG_SET_2(CM_COMB_C11_C12, 0, 1071 CM_COMB_C11, tbl_entry->regval[0], 1072 CM_COMB_C12, tbl_entry->regval[1]); 1073 1074 REG_SET_2(CM_COMB_C13_C14, 0, 1075 CM_COMB_C13, tbl_entry->regval[2], 1076 CM_COMB_C14, tbl_entry->regval[3]); 1077 1078 /*G*/ 1079 REG_SET_2(CM_COMB_C21_C22, 0, 1080 CM_COMB_C21, tbl_entry->regval[4], 1081 CM_COMB_C22, tbl_entry->regval[5]); 1082 1083 REG_SET_2(CM_COMB_C23_C24, 0, 1084 CM_COMB_C23, tbl_entry->regval[6], 1085 CM_COMB_C24, tbl_entry->regval[7]); 1086 1087 /*B*/ 1088 REG_SET_2(CM_COMB_C31_C32, 0, 1089 CM_COMB_C31, tbl_entry->regval[8], 1090 CM_COMB_C32, tbl_entry->regval[9]); 1091 1092 REG_SET_2(CM_COMB_C33_C34, 0, 1093 CM_COMB_C33, tbl_entry->regval[10], 1094 CM_COMB_C34, tbl_entry->regval[11]); 1095 } 1096 } 1097 1098 static void oppn10_set_output_csc_adjustment( 1099 struct transform *xfm_base, 1100 const struct out_csc_color_matrix *tbl_entry) 1101 { 1102 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1103 //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC; 1104 uint32_t ocsc_mode = 4; 1105 1106 /** 1107 *if (tbl_entry != NULL) { 1108 * switch (tbl_entry->color_space) { 1109 * case COLOR_SPACE_SRGB: 1110 * case COLOR_SPACE_2020_RGB_FULLRANGE: 1111 * ocsc_mode = 0; 1112 * break; 1113 * case COLOR_SPACE_SRGB_LIMITED: 1114 * case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 1115 * ocsc_mode = 1; 1116 * break; 1117 * case COLOR_SPACE_YCBCR601: 1118 * case COLOR_SPACE_YCBCR601_LIMITED: 1119 * ocsc_mode = 2; 1120 * break; 1121 * case COLOR_SPACE_YCBCR709: 1122 * case COLOR_SPACE_YCBCR709_LIMITED: 1123 * case COLOR_SPACE_2020_YCBCR: 1124 * ocsc_mode = 3; 1125 * break; 1126 * case COLOR_SPACE_UNKNOWN: 1127 * default: 1128 * break; 1129 * } 1130 *} 1131 */ 1132 1133 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); 1134 oppn10_program_color_matrix(xfm, tbl_entry); 1135 } 1136 1137 static void oppn10_power_on_regamma_lut( 1138 struct transform *xfm_base, 1139 bool power_on) 1140 { 1141 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1142 REG_SET(CM_MEM_PWR_CTRL, 0, 1143 RGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 1144 1145 } 1146 1147 static void opp_program_regamma_lut( 1148 struct transform *xfm_base, 1149 const struct pwl_result_data *rgb, 1150 uint32_t num) 1151 { 1152 uint32_t i; 1153 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1154 for (i = 0 ; i < num; i++) { 1155 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg); 1156 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg); 1157 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].blue_reg); 1158 1159 REG_SET(CM_RGAM_LUT_DATA, 0, 1160 CM_RGAM_LUT_DATA, rgb[i].delta_red_reg); 1161 REG_SET(CM_RGAM_LUT_DATA, 0, 1162 CM_RGAM_LUT_DATA, rgb[i].delta_green_reg); 1163 REG_SET(CM_RGAM_LUT_DATA, 0, 1164 CM_RGAM_LUT_DATA, rgb[i].delta_blue_reg); 1165 1166 } 1167 1168 } 1169 1170 static void opp_configure_regamma_lut( 1171 struct transform *xfm_base, 1172 bool is_ram_a) 1173 { 1174 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1175 1176 REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, 1177 CM_RGAM_LUT_WRITE_EN_MASK, 7); 1178 REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, 1179 CM_RGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 1180 REG_SET(CM_RGAM_LUT_INDEX, 0, CM_RGAM_LUT_INDEX, 0); 1181 } 1182 1183 /*program re gamma RAM A*/ 1184 static void opp_program_regamma_luta_settings( 1185 struct transform *xfm_base, 1186 const struct pwl_params *params) 1187 { 1188 const struct gamma_curve *curve; 1189 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1190 1191 REG_SET_2(CM_RGAM_RAMA_START_CNTL_B, 0, 1192 CM_RGAM_RAMA_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 1193 CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_B, 0); 1194 REG_SET_2(CM_RGAM_RAMA_START_CNTL_G, 0, 1195 CM_RGAM_RAMA_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 1196 CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_G, 0); 1197 REG_SET_2(CM_RGAM_RAMA_START_CNTL_R, 0, 1198 CM_RGAM_RAMA_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 1199 CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_R, 0); 1200 1201 REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_B, 0, 1202 CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 1203 REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_G, 0, 1204 CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 1205 REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_R, 0, 1206 CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 1207 1208 REG_SET(CM_RGAM_RAMA_END_CNTL1_B, 0, 1209 CM_RGAM_RAMA_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 1210 REG_SET_2(CM_RGAM_RAMA_END_CNTL2_B, 0, 1211 CM_RGAM_RAMA_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_slope, 1212 CM_RGAM_RAMA_EXP_REGION_END_BASE_B, params->arr_points[1].custom_float_y); 1213 1214 REG_SET(CM_RGAM_RAMA_END_CNTL1_G, 0, 1215 CM_RGAM_RAMA_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 1216 REG_SET_2(CM_RGAM_RAMA_END_CNTL2_G, 0, 1217 CM_RGAM_RAMA_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_slope, 1218 CM_RGAM_RAMA_EXP_REGION_END_BASE_G, params->arr_points[1].custom_float_y); 1219 1220 REG_SET(CM_RGAM_RAMA_END_CNTL1_R, 0, 1221 CM_RGAM_RAMA_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 1222 REG_SET_2(CM_RGAM_RAMA_END_CNTL2_R, 0, 1223 CM_RGAM_RAMA_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_slope, 1224 CM_RGAM_RAMA_EXP_REGION_END_BASE_R, params->arr_points[1].custom_float_y); 1225 1226 curve = params->arr_curve_points; 1227 REG_SET_4(CM_RGAM_RAMA_REGION_0_1, 0, 1228 CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 1229 CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 1230 CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 1231 CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 1232 1233 curve += 2; 1234 REG_SET_4(CM_RGAM_RAMA_REGION_2_3, 0, 1235 CM_RGAM_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 1236 CM_RGAM_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 1237 CM_RGAM_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 1238 CM_RGAM_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 1239 1240 curve += 2; 1241 REG_SET_4(CM_RGAM_RAMA_REGION_4_5, 0, 1242 CM_RGAM_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 1243 CM_RGAM_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 1244 CM_RGAM_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 1245 CM_RGAM_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 1246 1247 curve += 2; 1248 REG_SET_4(CM_RGAM_RAMA_REGION_6_7, 0, 1249 CM_RGAM_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 1250 CM_RGAM_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 1251 CM_RGAM_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 1252 CM_RGAM_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 1253 1254 curve += 2; 1255 REG_SET_4(CM_RGAM_RAMA_REGION_8_9, 0, 1256 CM_RGAM_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 1257 CM_RGAM_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 1258 CM_RGAM_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 1259 CM_RGAM_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 1260 1261 curve += 2; 1262 REG_SET_4(CM_RGAM_RAMA_REGION_10_11, 0, 1263 CM_RGAM_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 1264 CM_RGAM_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 1265 CM_RGAM_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 1266 CM_RGAM_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 1267 1268 curve += 2; 1269 REG_SET_4(CM_RGAM_RAMA_REGION_12_13, 0, 1270 CM_RGAM_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 1271 CM_RGAM_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 1272 CM_RGAM_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 1273 CM_RGAM_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 1274 1275 curve += 2; 1276 REG_SET_4(CM_RGAM_RAMA_REGION_14_15, 0, 1277 CM_RGAM_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 1278 CM_RGAM_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 1279 CM_RGAM_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 1280 CM_RGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 1281 1282 curve += 2; 1283 REG_SET_4(CM_RGAM_RAMA_REGION_16_17, 0, 1284 CM_RGAM_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset, 1285 CM_RGAM_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 1286 CM_RGAM_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset, 1287 CM_RGAM_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 1288 1289 curve += 2; 1290 REG_SET_4(CM_RGAM_RAMA_REGION_18_19, 0, 1291 CM_RGAM_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset, 1292 CM_RGAM_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 1293 CM_RGAM_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset, 1294 CM_RGAM_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 1295 1296 curve += 2; 1297 REG_SET_4(CM_RGAM_RAMA_REGION_20_21, 0, 1298 CM_RGAM_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset, 1299 CM_RGAM_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 1300 CM_RGAM_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset, 1301 CM_RGAM_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 1302 1303 curve += 2; 1304 REG_SET_4(CM_RGAM_RAMA_REGION_22_23, 0, 1305 CM_RGAM_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset, 1306 CM_RGAM_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 1307 CM_RGAM_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset, 1308 CM_RGAM_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 1309 1310 curve += 2; 1311 REG_SET_4(CM_RGAM_RAMA_REGION_24_25, 0, 1312 CM_RGAM_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset, 1313 CM_RGAM_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 1314 CM_RGAM_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset, 1315 CM_RGAM_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 1316 1317 curve += 2; 1318 REG_SET_4(CM_RGAM_RAMA_REGION_26_27, 0, 1319 CM_RGAM_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset, 1320 CM_RGAM_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 1321 CM_RGAM_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset, 1322 CM_RGAM_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 1323 1324 curve += 2; 1325 REG_SET_4(CM_RGAM_RAMA_REGION_28_29, 0, 1326 CM_RGAM_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset, 1327 CM_RGAM_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 1328 CM_RGAM_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset, 1329 CM_RGAM_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 1330 1331 curve += 2; 1332 REG_SET_4(CM_RGAM_RAMA_REGION_30_31, 0, 1333 CM_RGAM_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset, 1334 CM_RGAM_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 1335 CM_RGAM_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset, 1336 CM_RGAM_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 1337 1338 curve += 2; 1339 REG_SET_4(CM_RGAM_RAMA_REGION_32_33, 0, 1340 CM_RGAM_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset, 1341 CM_RGAM_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 1342 CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset, 1343 CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 1344 } 1345 1346 /*program re gamma RAM B*/ 1347 static void opp_program_regamma_lutb_settings( 1348 struct transform *xfm_base, 1349 const struct pwl_params *params) 1350 { 1351 const struct gamma_curve *curve; 1352 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1353 1354 REG_SET_2(CM_RGAM_RAMB_START_CNTL_B, 0, 1355 CM_RGAM_RAMB_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 1356 CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B, 0); 1357 REG_SET_2(CM_RGAM_RAMB_START_CNTL_G, 0, 1358 CM_RGAM_RAMB_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 1359 CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_G, 0); 1360 REG_SET_2(CM_RGAM_RAMB_START_CNTL_R, 0, 1361 CM_RGAM_RAMB_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 1362 CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_R, 0); 1363 1364 REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_B, 0, 1365 CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 1366 REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_G, 0, 1367 CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 1368 REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_R, 0, 1369 CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 1370 1371 REG_SET(CM_RGAM_RAMB_END_CNTL1_B, 0, 1372 CM_RGAM_RAMB_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 1373 REG_SET_2(CM_RGAM_RAMB_END_CNTL2_B, 0, 1374 CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_slope, 1375 CM_RGAM_RAMB_EXP_REGION_END_BASE_B, params->arr_points[1].custom_float_y); 1376 1377 REG_SET(CM_RGAM_RAMB_END_CNTL1_G, 0, 1378 CM_RGAM_RAMB_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 1379 REG_SET_2(CM_RGAM_RAMB_END_CNTL2_G, 0, 1380 CM_RGAM_RAMB_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_slope, 1381 CM_RGAM_RAMB_EXP_REGION_END_BASE_G, params->arr_points[1].custom_float_y); 1382 1383 REG_SET(CM_RGAM_RAMB_END_CNTL1_R, 0, 1384 CM_RGAM_RAMB_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 1385 REG_SET_2(CM_RGAM_RAMB_END_CNTL2_R, 0, 1386 CM_RGAM_RAMB_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_slope, 1387 CM_RGAM_RAMB_EXP_REGION_END_BASE_R, params->arr_points[1].custom_float_y); 1388 1389 curve = params->arr_curve_points; 1390 REG_SET_4(CM_RGAM_RAMB_REGION_0_1, 0, 1391 CM_RGAM_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 1392 CM_RGAM_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 1393 CM_RGAM_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 1394 CM_RGAM_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 1395 1396 curve += 2; 1397 REG_SET_4(CM_RGAM_RAMB_REGION_2_3, 0, 1398 CM_RGAM_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 1399 CM_RGAM_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 1400 CM_RGAM_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 1401 CM_RGAM_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 1402 1403 curve += 2; 1404 REG_SET_4(CM_RGAM_RAMB_REGION_4_5, 0, 1405 CM_RGAM_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 1406 CM_RGAM_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 1407 CM_RGAM_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 1408 CM_RGAM_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 1409 1410 curve += 2; 1411 REG_SET_4(CM_RGAM_RAMB_REGION_6_7, 0, 1412 CM_RGAM_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 1413 CM_RGAM_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 1414 CM_RGAM_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 1415 CM_RGAM_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 1416 1417 curve += 2; 1418 REG_SET_4(CM_RGAM_RAMB_REGION_8_9, 0, 1419 CM_RGAM_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 1420 CM_RGAM_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 1421 CM_RGAM_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 1422 CM_RGAM_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 1423 1424 curve += 2; 1425 REG_SET_4(CM_RGAM_RAMB_REGION_10_11, 0, 1426 CM_RGAM_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 1427 CM_RGAM_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 1428 CM_RGAM_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 1429 CM_RGAM_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 1430 1431 curve += 2; 1432 REG_SET_4(CM_RGAM_RAMB_REGION_12_13, 0, 1433 CM_RGAM_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 1434 CM_RGAM_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 1435 CM_RGAM_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 1436 CM_RGAM_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 1437 1438 curve += 2; 1439 REG_SET_4(CM_RGAM_RAMB_REGION_14_15, 0, 1440 CM_RGAM_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 1441 CM_RGAM_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 1442 CM_RGAM_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 1443 CM_RGAM_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 1444 1445 curve += 2; 1446 REG_SET_4(CM_RGAM_RAMB_REGION_16_17, 0, 1447 CM_RGAM_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset, 1448 CM_RGAM_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 1449 CM_RGAM_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset, 1450 CM_RGAM_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 1451 1452 curve += 2; 1453 REG_SET_4(CM_RGAM_RAMB_REGION_18_19, 0, 1454 CM_RGAM_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset, 1455 CM_RGAM_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 1456 CM_RGAM_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset, 1457 CM_RGAM_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 1458 1459 curve += 2; 1460 REG_SET_4(CM_RGAM_RAMB_REGION_20_21, 0, 1461 CM_RGAM_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset, 1462 CM_RGAM_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 1463 CM_RGAM_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset, 1464 CM_RGAM_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 1465 1466 curve += 2; 1467 REG_SET_4(CM_RGAM_RAMB_REGION_22_23, 0, 1468 CM_RGAM_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset, 1469 CM_RGAM_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 1470 CM_RGAM_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset, 1471 CM_RGAM_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 1472 1473 curve += 2; 1474 REG_SET_4(CM_RGAM_RAMB_REGION_24_25, 0, 1475 CM_RGAM_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset, 1476 CM_RGAM_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 1477 CM_RGAM_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset, 1478 CM_RGAM_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 1479 1480 curve += 2; 1481 REG_SET_4(CM_RGAM_RAMB_REGION_26_27, 0, 1482 CM_RGAM_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset, 1483 CM_RGAM_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 1484 CM_RGAM_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset, 1485 CM_RGAM_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 1486 1487 curve += 2; 1488 REG_SET_4(CM_RGAM_RAMB_REGION_28_29, 0, 1489 CM_RGAM_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset, 1490 CM_RGAM_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 1491 CM_RGAM_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset, 1492 CM_RGAM_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 1493 1494 curve += 2; 1495 REG_SET_4(CM_RGAM_RAMB_REGION_30_31, 0, 1496 CM_RGAM_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset, 1497 CM_RGAM_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 1498 CM_RGAM_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset, 1499 CM_RGAM_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 1500 1501 curve += 2; 1502 REG_SET_4(CM_RGAM_RAMB_REGION_32_33, 0, 1503 CM_RGAM_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset, 1504 CM_RGAM_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 1505 CM_RGAM_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset, 1506 CM_RGAM_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 1507 1508 } 1509 1510 static bool oppn10_set_regamma_pwl( 1511 struct transform *xfm_base, const struct pwl_params *params) 1512 { 1513 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1514 1515 oppn10_power_on_regamma_lut(xfm_base, true); 1516 opp_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe); 1517 1518 if (xfm->is_write_to_ram_a_safe) 1519 opp_program_regamma_luta_settings(xfm_base, params); 1520 else 1521 opp_program_regamma_lutb_settings(xfm_base, params); 1522 1523 opp_program_regamma_lut( 1524 xfm_base, params->rgb_resulted, params->hw_points_num); 1525 1526 return true; 1527 } 1528 1529 static void oppn10_set_regamma_mode( 1530 struct transform *xfm_base, 1531 enum opp_regamma mode) 1532 { 1533 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 1534 uint32_t re_mode = 0; 1535 uint32_t obuf_bypass = 0; /* need for pipe split */ 1536 uint32_t obuf_hupscale = 0; 1537 1538 switch (mode) { 1539 case OPP_REGAMMA_BYPASS: 1540 re_mode = 0; 1541 break; 1542 case OPP_REGAMMA_SRGB: 1543 re_mode = 1; 1544 break; 1545 case OPP_REGAMMA_3_6: 1546 re_mode = 2; 1547 break; 1548 case OPP_REGAMMA_USER: 1549 re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4; 1550 xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe; 1551 break; 1552 default: 1553 break; 1554 } 1555 1556 REG_SET(CM_RGAM_CONTROL, 0, CM_RGAM_LUT_MODE, re_mode); 1557 REG_UPDATE_2(OBUF_CONTROL, 1558 OBUF_BYPASS, obuf_bypass, 1559 OBUF_H_2X_UPSCALE_EN, obuf_hupscale); 1560 } 1561 1562 static struct transform_funcs dcn10_dpp_funcs = { 1563 .transform_reset = dpp_reset, 1564 .transform_set_scaler = dpp_set_scaler_manual_scale, 1565 .transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, 1566 .transform_set_gamut_remap = dcn_dpp_set_gamut_remap, 1567 .opp_set_csc_adjustment = oppn10_set_output_csc_adjustment, 1568 .opp_set_csc_default = oppn10_set_output_csc_default, 1569 .opp_power_on_regamma_lut = oppn10_power_on_regamma_lut, 1570 .opp_program_regamma_lut = opp_program_regamma_lut, 1571 .opp_configure_regamma_lut = opp_configure_regamma_lut, 1572 .opp_program_regamma_lutb_settings = opp_program_regamma_lutb_settings, 1573 .opp_program_regamma_luta_settings = opp_program_regamma_luta_settings, 1574 .opp_program_regamma_pwl = oppn10_set_regamma_pwl, 1575 .opp_set_regamma_mode = oppn10_set_regamma_mode, 1576 }; 1577 1578 /*****************************************/ 1579 /* Constructor, Destructor */ 1580 /*****************************************/ 1581 1582 bool dcn10_dpp_construct( 1583 struct dcn10_dpp *xfm, 1584 struct dc_context *ctx, 1585 uint32_t inst, 1586 const struct dcn_dpp_registers *tf_regs, 1587 const struct dcn_dpp_shift *tf_shift, 1588 const struct dcn_dpp_mask *tf_mask) 1589 { 1590 xfm->base.ctx = ctx; 1591 1592 xfm->base.inst = inst; 1593 xfm->base.funcs = &dcn10_dpp_funcs; 1594 1595 xfm->tf_regs = tf_regs; 1596 xfm->tf_shift = tf_shift; 1597 xfm->tf_mask = tf_mask; 1598 1599 xfm->lb_pixel_depth_supported = 1600 LB_PIXEL_DEPTH_18BPP | 1601 LB_PIXEL_DEPTH_24BPP | 1602 LB_PIXEL_DEPTH_30BPP; 1603 1604 xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY; 1605 xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ 1606 1607 return true; 1608 } 1609