769 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "dm_services.h"27#include "basics/conversion.h"28 29#include "dce_opp.h"30 31#include "reg_helper.h"32 33#define REG(reg)\34 (opp110->regs->reg)35 36#undef FN37#define FN(reg_name, field_name) \38 opp110->opp_shift->field_name, opp110->opp_mask->field_name39 40#define CTX \41 opp110->base.ctx42 43enum {44 MAX_PWL_ENTRY = 128,45 MAX_REGIONS_NUMBER = 1646};47 48enum {49 MAX_LUT_ENTRY = 256,50 MAX_NUMBER_OF_ENTRIES = 25651};52 53 54enum {55 OUTPUT_CSC_MATRIX_SIZE = 1256};57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79/*80 *****************************************************************************81 * Function: regamma_config_regions_and_segments82 *83 * build regamma curve by using predefined hw points84 * uses interface parameters ,like EDID coeff.85 *86 * @param : parameters interface parameters87 * @return void88 *89 * @note90 *91 * @see92 *93 *****************************************************************************94 */95 96 97 98/*99 * set_truncation100 * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp101 * 2) enable truncation102 * 3) HW remove 12bit FMT support for DCE11 power saving reason.103 */104static void set_truncation(105 struct dce110_opp *opp110,106 const struct bit_depth_reduction_params *params)107{108 /*Disable truncation*/109 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,110 FMT_TRUNCATE_EN, 0,111 FMT_TRUNCATE_DEPTH, 0,112 FMT_TRUNCATE_MODE, 0);113 114 115 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {116 /* 8bpc trunc on YCbCr422*/117 if (params->flags.TRUNCATE_DEPTH == 1)118 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,119 FMT_TRUNCATE_EN, 1,120 FMT_TRUNCATE_DEPTH, 1,121 FMT_TRUNCATE_MODE, 0);122 else if (params->flags.TRUNCATE_DEPTH == 2)123 /* 10bpc trunc on YCbCr422*/124 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,125 FMT_TRUNCATE_EN, 1,126 FMT_TRUNCATE_DEPTH, 2,127 FMT_TRUNCATE_MODE, 0);128 return;129 }130 /* on other format-to do */131 if (params->flags.TRUNCATE_ENABLED == 0)132 return;133 /*Set truncation depth and Enable truncation*/134 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,135 FMT_TRUNCATE_EN, 1,136 FMT_TRUNCATE_DEPTH,137 params->flags.TRUNCATE_DEPTH,138 FMT_TRUNCATE_MODE,139 params->flags.TRUNCATE_MODE);140}141 142#if defined(CONFIG_DRM_AMD_DC_SI)143/*144 * dce60_set_truncation145 * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp146 * 2) enable truncation147 * 3) HW remove 12bit FMT support for DCE11 power saving reason.148 */149static void dce60_set_truncation(150 struct dce110_opp *opp110,151 const struct bit_depth_reduction_params *params)152{153 /* DCE6 has no FMT_TRUNCATE_MODE bit in FMT_BIT_DEPTH_CONTROL reg */154 155 /*Disable truncation*/156 REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,157 FMT_TRUNCATE_EN, 0,158 FMT_TRUNCATE_DEPTH, 0);159 160 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {161 /* 8bpc trunc on YCbCr422*/162 if (params->flags.TRUNCATE_DEPTH == 1)163 REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,164 FMT_TRUNCATE_EN, 1,165 FMT_TRUNCATE_DEPTH, 1);166 else if (params->flags.TRUNCATE_DEPTH == 2)167 /* 10bpc trunc on YCbCr422*/168 REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,169 FMT_TRUNCATE_EN, 1,170 FMT_TRUNCATE_DEPTH, 2);171 return;172 }173 /* on other format-to do */174 if (params->flags.TRUNCATE_ENABLED == 0)175 return;176 /*Set truncation depth and Enable truncation*/177 REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,178 FMT_TRUNCATE_EN, 1,179 FMT_TRUNCATE_DEPTH,180 params->flags.TRUNCATE_DEPTH);181}182#endif183 184/*185 * set_spatial_dither186 * 1) set spatial dithering mode: pattern of seed187 * 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp188 * 3) set random seed189 * 4) set random mode190 * lfsr is reset every frame or not reset191 * RGB dithering method192 * 0: RGB data are all dithered with x^28+x^3+1193 * 1: R data is dithered with x^28+x^3+1194 * G data is dithered with x^28+X^9+1195 * B data is dithered with x^28+x^13+1196 * enable high pass filter or not197 * 5) enable spatical dithering198 */199static void set_spatial_dither(200 struct dce110_opp *opp110,201 const struct bit_depth_reduction_params *params)202{203 /*Disable spatial (random) dithering*/204 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,205 FMT_SPATIAL_DITHER_EN, 0,206 FMT_SPATIAL_DITHER_DEPTH, 0,207 FMT_SPATIAL_DITHER_MODE, 0);208 209 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,210 FMT_HIGHPASS_RANDOM_ENABLE, 0,211 FMT_FRAME_RANDOM_ENABLE, 0,212 FMT_RGB_RANDOM_ENABLE, 0);213 214 REG_UPDATE(FMT_BIT_DEPTH_CONTROL,215 FMT_TEMPORAL_DITHER_EN, 0);216 217 if (params->flags.SPATIAL_DITHER_ENABLED == 0)218 return;219 220 /* only use FRAME_COUNTER_MAX if frameRandom == 1*/221 222 if (opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX &&223 opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP) {224 if (params->flags.FRAME_RANDOM == 1) {225 if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||226 params->flags.SPATIAL_DITHER_DEPTH == 1) {227 REG_UPDATE_2(FMT_CONTROL,228 FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,229 FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);230 } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {231 REG_UPDATE_2(FMT_CONTROL,232 FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,233 FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);234 } else235 return;236 } else {237 REG_UPDATE_2(FMT_CONTROL,238 FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,239 FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);240 }241 }242 /* Set seed for random values for243 * spatial dithering for R,G,B channels244 */245 REG_UPDATE(FMT_DITHER_RAND_R_SEED,246 FMT_RAND_R_SEED, params->r_seed_value);247 248 REG_UPDATE(FMT_DITHER_RAND_G_SEED,249 FMT_RAND_G_SEED, params->g_seed_value);250 251 REG_UPDATE(FMT_DITHER_RAND_B_SEED,252 FMT_RAND_B_SEED, params->b_seed_value);253 254 /* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero255 * offset for the R/Cr channel, lower 4LSB256 * is forced to zeros. Typically set to 0257 * RGB and 0x80000 YCbCr.258 */259 /* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero260 * offset for the G/Y channel, lower 4LSB is261 * forced to zeros. Typically set to 0 RGB262 * and 0x80000 YCbCr.263 */264 /* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero265 * offset for the B/Cb channel, lower 4LSB is266 * forced to zeros. Typically set to 0 RGB and267 * 0x80000 YCbCr.268 */269 270 /* Disable High pass filter271 * Reset only at startup272 * Set RGB data dithered with x^28+x^3+1273 */274 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,275 FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,276 FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,277 FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);278 279 /* Set spatial dithering bit depth280 * Set spatial dithering mode281 * (default is Seed patterrn AAAA...)282 * Enable spatial dithering283 */284 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,285 FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,286 FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,287 FMT_SPATIAL_DITHER_EN, 1);288}289 290/*291 * SetTemporalDither (Frame Modulation)292 * 1) set temporal dither depth293 * 2) select pattern: from hard-coded pattern or programmable pattern294 * 3) select optimized strips for BGR or RGB LCD sub-pixel295 * 4) set s matrix296 * 5) set t matrix297 * 6) set grey level for 0.25, 0.5, 0.75298 * 7) enable temporal dithering299 */300 301static void set_temporal_dither(302 struct dce110_opp *opp110,303 const struct bit_depth_reduction_params *params)304{305 /*Disable temporal (frame modulation) dithering first*/306 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,307 FMT_TEMPORAL_DITHER_EN, 0,308 FMT_TEMPORAL_DITHER_RESET, 0,309 FMT_TEMPORAL_DITHER_OFFSET, 0);310 311 REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,312 FMT_TEMPORAL_DITHER_DEPTH, 0,313 FMT_TEMPORAL_LEVEL, 0);314 315 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,316 FMT_25FRC_SEL, 0,317 FMT_50FRC_SEL, 0,318 FMT_75FRC_SEL, 0);319 320 /* no 10bpc dither on DCE11*/321 if (params->flags.FRAME_MODULATION_ENABLED == 0 ||322 params->flags.FRAME_MODULATION_DEPTH == 2)323 return;324 325 /* Set temporal dithering depth*/326 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,327 FMT_TEMPORAL_DITHER_DEPTH, params->flags.FRAME_MODULATION_DEPTH,328 FMT_TEMPORAL_DITHER_RESET, 0,329 FMT_TEMPORAL_DITHER_OFFSET, 0);330 331 /*Select legacy pattern based on FRC and Temporal level*/332 if (REG(FMT_TEMPORAL_DITHER_PATTERN_CONTROL)) {333 REG_WRITE(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, 0);334 /*Set s matrix*/335 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, 0);336 /*Set t matrix*/337 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, 0);338 }339 340 /*Select patterns for 0.25, 0.5 and 0.75 grey level*/341 REG_UPDATE(FMT_BIT_DEPTH_CONTROL,342 FMT_TEMPORAL_LEVEL, params->flags.TEMPORAL_LEVEL);343 344 REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,345 FMT_25FRC_SEL, params->flags.FRC25,346 FMT_50FRC_SEL, params->flags.FRC50,347 FMT_75FRC_SEL, params->flags.FRC75);348 349 /*Enable bit reduction by temporal (frame modulation) dithering*/350 REG_UPDATE(FMT_BIT_DEPTH_CONTROL,351 FMT_TEMPORAL_DITHER_EN, 1);352}353 354/*355 * Set Clamping356 * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)357 * 1 for 8 bpc358 * 2 for 10 bpc359 * 3 for 12 bpc360 * 7 for programable361 * 2) Enable clamp if Limited range requested362 */363void dce110_opp_set_clamping(364 struct dce110_opp *opp110,365 const struct clamping_and_pixel_encoding_params *params)366{367 REG_SET_2(FMT_CLAMP_CNTL, 0,368 FMT_CLAMP_DATA_EN, 0,369 FMT_CLAMP_COLOR_FORMAT, 0);370 371 switch (params->clamping_level) {372 case CLAMPING_FULL_RANGE:373 break;374 case CLAMPING_LIMITED_RANGE_8BPC:375 REG_SET_2(FMT_CLAMP_CNTL, 0,376 FMT_CLAMP_DATA_EN, 1,377 FMT_CLAMP_COLOR_FORMAT, 1);378 break;379 case CLAMPING_LIMITED_RANGE_10BPC:380 REG_SET_2(FMT_CLAMP_CNTL, 0,381 FMT_CLAMP_DATA_EN, 1,382 FMT_CLAMP_COLOR_FORMAT, 2);383 break;384 case CLAMPING_LIMITED_RANGE_12BPC:385 REG_SET_2(FMT_CLAMP_CNTL, 0,386 FMT_CLAMP_DATA_EN, 1,387 FMT_CLAMP_COLOR_FORMAT, 3);388 break;389 case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:390 /*Set clamp control*/391 REG_SET_2(FMT_CLAMP_CNTL, 0,392 FMT_CLAMP_DATA_EN, 1,393 FMT_CLAMP_COLOR_FORMAT, 7);394 395 /*set the defaults*/396 REG_SET_2(FMT_CLAMP_COMPONENT_R, 0,397 FMT_CLAMP_LOWER_R, 0x10,398 FMT_CLAMP_UPPER_R, 0xFEF);399 400 REG_SET_2(FMT_CLAMP_COMPONENT_G, 0,401 FMT_CLAMP_LOWER_G, 0x10,402 FMT_CLAMP_UPPER_G, 0xFEF);403 404 REG_SET_2(FMT_CLAMP_COMPONENT_B, 0,405 FMT_CLAMP_LOWER_B, 0x10,406 FMT_CLAMP_UPPER_B, 0xFEF);407 break;408 default:409 break;410 }411}412 413#if defined(CONFIG_DRM_AMD_DC_SI)414/*415 * Set Clamping for DCE6 parts416 * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)417 * 1 for 8 bpc418 * 2 for 10 bpc419 * 3 for 12 bpc420 * 7 for programable421 * 2) Enable clamp if Limited range requested422 */423static void dce60_opp_set_clamping(424 struct dce110_opp *opp110,425 const struct clamping_and_pixel_encoding_params *params)426{427 REG_SET_2(FMT_CLAMP_CNTL, 0,428 FMT_CLAMP_DATA_EN, 0,429 FMT_CLAMP_COLOR_FORMAT, 0);430 431 switch (params->clamping_level) {432 case CLAMPING_FULL_RANGE:433 break;434 case CLAMPING_LIMITED_RANGE_8BPC:435 REG_SET_2(FMT_CLAMP_CNTL, 0,436 FMT_CLAMP_DATA_EN, 1,437 FMT_CLAMP_COLOR_FORMAT, 1);438 break;439 case CLAMPING_LIMITED_RANGE_10BPC:440 REG_SET_2(FMT_CLAMP_CNTL, 0,441 FMT_CLAMP_DATA_EN, 1,442 FMT_CLAMP_COLOR_FORMAT, 2);443 break;444 case CLAMPING_LIMITED_RANGE_12BPC:445 REG_SET_2(FMT_CLAMP_CNTL, 0,446 FMT_CLAMP_DATA_EN, 1,447 FMT_CLAMP_COLOR_FORMAT, 3);448 break;449 case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:450 /*Set clamp control*/451 REG_SET_2(FMT_CLAMP_CNTL, 0,452 FMT_CLAMP_DATA_EN, 1,453 FMT_CLAMP_COLOR_FORMAT, 7);454 455 /* DCE6 does have FMT_CLAMP_COMPONENT_{R,G,B} registers */456 457 break;458 default:459 break;460 }461}462#endif463 464/*465 * set_pixel_encoding466 *467 * Set Pixel Encoding468 * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly469 * 1: YCbCr 4:2:2470 */471static void set_pixel_encoding(472 struct dce110_opp *opp110,473 const struct clamping_and_pixel_encoding_params *params)474{475 if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)476 REG_UPDATE_3(FMT_CONTROL,477 FMT_PIXEL_ENCODING, 0,478 FMT_SUBSAMPLING_MODE, 0,479 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);480 else481 REG_UPDATE_2(FMT_CONTROL,482 FMT_PIXEL_ENCODING, 0,483 FMT_SUBSAMPLING_MODE, 0);484 485 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {486 REG_UPDATE_2(FMT_CONTROL,487 FMT_PIXEL_ENCODING, 1,488 FMT_SUBSAMPLING_ORDER, 0);489 }490 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {491 REG_UPDATE_3(FMT_CONTROL,492 FMT_PIXEL_ENCODING, 2,493 FMT_SUBSAMPLING_MODE, 2,494 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);495 }496 497}498 499#if defined(CONFIG_DRM_AMD_DC_SI)500/*501 * dce60_set_pixel_encoding502 * DCE6 has no FMT_SUBSAMPLING_{MODE,ORDER} bits in FMT_CONTROL reg503 * Set Pixel Encoding504 * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly505 * 1: YCbCr 4:2:2506 */507static void dce60_set_pixel_encoding(508 struct dce110_opp *opp110,509 const struct clamping_and_pixel_encoding_params *params)510{511 if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)512 REG_UPDATE_2(FMT_CONTROL,513 FMT_PIXEL_ENCODING, 0,514 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);515 else516 REG_UPDATE(FMT_CONTROL,517 FMT_PIXEL_ENCODING, 0);518 519 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {520 REG_UPDATE(FMT_CONTROL,521 FMT_PIXEL_ENCODING, 1);522 }523 if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {524 REG_UPDATE_2(FMT_CONTROL,525 FMT_PIXEL_ENCODING, 2,526 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);527 }528 529}530#endif531 532void dce110_opp_program_bit_depth_reduction(533 struct output_pixel_processor *opp,534 const struct bit_depth_reduction_params *params)535{536 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);537 538 set_truncation(opp110, params);539 set_spatial_dither(opp110, params);540 set_temporal_dither(opp110, params);541}542 543#if defined(CONFIG_DRM_AMD_DC_SI)544static void dce60_opp_program_bit_depth_reduction(545 struct output_pixel_processor *opp,546 const struct bit_depth_reduction_params *params)547{548 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);549 550 dce60_set_truncation(opp110, params);551 set_spatial_dither(opp110, params);552 set_temporal_dither(opp110, params);553}554#endif555 556void dce110_opp_program_clamping_and_pixel_encoding(557 struct output_pixel_processor *opp,558 const struct clamping_and_pixel_encoding_params *params)559{560 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);561 562 dce110_opp_set_clamping(opp110, params);563 set_pixel_encoding(opp110, params);564}565 566#if defined(CONFIG_DRM_AMD_DC_SI)567static void dce60_opp_program_clamping_and_pixel_encoding(568 struct output_pixel_processor *opp,569 const struct clamping_and_pixel_encoding_params *params)570{571 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);572 573 dce60_opp_set_clamping(opp110, params);574 dce60_set_pixel_encoding(opp110, params);575}576#endif577 578static void program_formatter_420_memory(struct output_pixel_processor *opp)579{580 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);581 uint32_t fmt_mem_cntl_value;582 583 /* Program source select*/584 /* Use HW default source select for FMT_MEMORYx_CONTROL */585 /* Use that value for FMT_SRC_SELECT as well*/586 REG_GET(CONTROL,587 FMT420_MEM0_SOURCE_SEL, &fmt_mem_cntl_value);588 589 REG_UPDATE(FMT_CONTROL,590 FMT_SRC_SELECT, fmt_mem_cntl_value);591 592 /* Turn on the memory */593 REG_UPDATE(CONTROL,594 FMT420_MEM0_PWR_FORCE, 0);595}596 597void dce110_opp_set_dyn_expansion(598 struct output_pixel_processor *opp,599 enum dc_color_space color_sp,600 enum dc_color_depth color_dpth,601 enum signal_type signal)602{603 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);604 605 REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,606 FMT_DYNAMIC_EXP_EN, 0,607 FMT_DYNAMIC_EXP_MODE, 0);608 609 /*00 - 10-bit -> 12-bit dynamic expansion*/610 /*01 - 8-bit -> 12-bit dynamic expansion*/611 if (signal == SIGNAL_TYPE_HDMI_TYPE_A ||612 signal == SIGNAL_TYPE_DISPLAY_PORT ||613 signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {614 switch (color_dpth) {615 case COLOR_DEPTH_888:616 REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,617 FMT_DYNAMIC_EXP_EN, 1,618 FMT_DYNAMIC_EXP_MODE, 1);619 break;620 case COLOR_DEPTH_101010:621 REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,622 FMT_DYNAMIC_EXP_EN, 1,623 FMT_DYNAMIC_EXP_MODE, 0);624 break;625 case COLOR_DEPTH_121212:626 REG_UPDATE_2(627 FMT_DYNAMIC_EXP_CNTL,628 FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/629 FMT_DYNAMIC_EXP_MODE, 0);630 break;631 default:632 break;633 }634 }635}636 637static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)638{639 struct dce110_opp *opp110 = TO_DCE110_OPP(opp);640 641 /* clear previous phase lock status*/642 REG_UPDATE(FMT_CONTROL,643 FMT_420_PIXEL_PHASE_LOCKED_CLEAR, 1);644 645 /* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/646 REG_WAIT(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED, 1, 10, 10);647 648}649 650void dce110_opp_program_fmt(651 struct output_pixel_processor *opp,652 struct bit_depth_reduction_params *fmt_bit_depth,653 struct clamping_and_pixel_encoding_params *clamping)654{655 /* dithering is affected by <CrtcSourceSelect>, hence should be656 * programmed afterwards */657 658 if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)659 program_formatter_420_memory(opp);660 661 dce110_opp_program_bit_depth_reduction(662 opp,663 fmt_bit_depth);664 665 dce110_opp_program_clamping_and_pixel_encoding(666 opp,667 clamping);668 669 if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)670 program_formatter_reset_dig_resync_fifo(opp);671 672 return;673}674 675#if defined(CONFIG_DRM_AMD_DC_SI)676static void dce60_opp_program_fmt(677 struct output_pixel_processor *opp,678 struct bit_depth_reduction_params *fmt_bit_depth,679 struct clamping_and_pixel_encoding_params *clamping)680{681 /* dithering is affected by <CrtcSourceSelect>, hence should be682 * programmed afterwards */683 684 if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)685 program_formatter_420_memory(opp);686 687 dce60_opp_program_bit_depth_reduction(688 opp,689 fmt_bit_depth);690 691 dce60_opp_program_clamping_and_pixel_encoding(692 opp,693 clamping);694 695 if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)696 program_formatter_reset_dig_resync_fifo(opp);697 698 return;699}700#endif701 702 703 704/*****************************************/705/* Constructor, Destructor */706/*****************************************/707 708static const struct opp_funcs funcs = {709 .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,710 .opp_destroy = dce110_opp_destroy,711 .opp_program_fmt = dce110_opp_program_fmt,712 .opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction713};714 715#if defined(CONFIG_DRM_AMD_DC_SI)716static const struct opp_funcs dce60_opp_funcs = {717 .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,718 .opp_destroy = dce110_opp_destroy,719 .opp_program_fmt = dce60_opp_program_fmt,720 .opp_program_bit_depth_reduction = dce60_opp_program_bit_depth_reduction721};722#endif723 724void dce110_opp_construct(struct dce110_opp *opp110,725 struct dc_context *ctx,726 uint32_t inst,727 const struct dce_opp_registers *regs,728 const struct dce_opp_shift *opp_shift,729 const struct dce_opp_mask *opp_mask)730{731 opp110->base.funcs = &funcs;732 733 opp110->base.ctx = ctx;734 735 opp110->base.inst = inst;736 737 opp110->regs = regs;738 opp110->opp_shift = opp_shift;739 opp110->opp_mask = opp_mask;740}741 742#if defined(CONFIG_DRM_AMD_DC_SI)743void dce60_opp_construct(struct dce110_opp *opp110,744 struct dc_context *ctx,745 uint32_t inst,746 const struct dce_opp_registers *regs,747 const struct dce_opp_shift *opp_shift,748 const struct dce_opp_mask *opp_mask)749{750 opp110->base.funcs = &dce60_opp_funcs;751 752 opp110->base.ctx = ctx;753 754 opp110->base.inst = inst;755 756 opp110->regs = regs;757 opp110->opp_shift = opp_shift;758 opp110->opp_mask = opp_mask;759}760#endif761 762void dce110_opp_destroy(struct output_pixel_processor **opp)763{764 if (*opp)765 kfree(FROM_DCE11_OPP(*opp));766 *opp = NULL;767}768 769