1 /* 2 * Copyright 2019 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 * Author: AMD 23 */ 24 25 #include <drm/display/drm_dp_helper.h> 26 #include <drm/display/drm_dsc_helper.h> 27 #include "dc_hw_types.h" 28 #include "dsc.h" 29 #include "dc.h" 30 #include "rc_calc.h" 31 #include "fixed31_32.h" 32 33 /* This module's internal functions */ 34 35 /* default DSC policy target bitrate limit is 16bpp */ 36 static uint32_t dsc_policy_max_target_bpp_limit = 16; 37 38 /* default DSC policy enables DSC only when needed */ 39 static bool dsc_policy_enable_dsc_when_not_needed; 40 41 static bool dsc_policy_disable_dsc_stream_overhead; 42 43 static bool disable_128b_132b_stream_overhead; 44 45 #ifndef MAX 46 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 47 #endif 48 #ifndef MIN 49 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 50 #endif 51 52 /* Forward Declerations */ 53 static bool decide_dsc_bandwidth_range( 54 const uint32_t min_bpp_x16, 55 const uint32_t max_bpp_x16, 56 const uint32_t num_slices_h, 57 const struct dsc_enc_caps *dsc_caps, 58 const struct dc_crtc_timing *timing, 59 const enum dc_link_encoding_format link_encoding, 60 struct dc_dsc_bw_range *range); 61 62 static uint32_t compute_bpp_x16_from_target_bandwidth( 63 const uint32_t bandwidth_in_kbps, 64 const struct dc_crtc_timing *timing, 65 const uint32_t num_slices_h, 66 const uint32_t bpp_increment_div, 67 const bool is_dp); 68 69 static void get_dsc_enc_caps( 70 const struct display_stream_compressor *dsc, 71 struct dsc_enc_caps *dsc_enc_caps, 72 int pixel_clock_100Hz); 73 74 static bool intersect_dsc_caps( 75 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 76 const struct dsc_enc_caps *dsc_enc_caps, 77 enum dc_pixel_encoding pixel_encoding, 78 struct dsc_enc_caps *dsc_common_caps); 79 80 static bool setup_dsc_config( 81 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 82 const struct dsc_enc_caps *dsc_enc_caps, 83 int target_bandwidth_kbps, 84 const struct dc_crtc_timing *timing, 85 const struct dc_dsc_config_options *options, 86 const enum dc_link_encoding_format link_encoding, 87 struct dc_dsc_config *dsc_cfg); 88 89 static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) 90 { 91 92 switch (dpcd_buff_block_size) { 93 case DP_DSC_RC_BUF_BLK_SIZE_1: 94 *buff_block_size = 1024; 95 break; 96 case DP_DSC_RC_BUF_BLK_SIZE_4: 97 *buff_block_size = 4 * 1024; 98 break; 99 case DP_DSC_RC_BUF_BLK_SIZE_16: 100 *buff_block_size = 16 * 1024; 101 break; 102 case DP_DSC_RC_BUF_BLK_SIZE_64: 103 *buff_block_size = 64 * 1024; 104 break; 105 default: { 106 dm_error("%s: DPCD DSC buffer size not recognized.\n", __func__); 107 return false; 108 } 109 } 110 111 return true; 112 } 113 114 115 static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *line_buff_bit_depth) 116 { 117 if (0 <= dpcd_line_buff_bit_depth && dpcd_line_buff_bit_depth <= 7) 118 *line_buff_bit_depth = dpcd_line_buff_bit_depth + 9; 119 else if (dpcd_line_buff_bit_depth == 8) 120 *line_buff_bit_depth = 8; 121 else { 122 dm_error("%s: DPCD DSC buffer depth not recognized.\n", __func__); 123 return false; 124 } 125 126 return true; 127 } 128 129 130 static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput) 131 { 132 switch (dpcd_throughput) { 133 case DP_DSC_THROUGHPUT_MODE_0_UNSUPPORTED: 134 *throughput = 0; 135 break; 136 case DP_DSC_THROUGHPUT_MODE_0_170: 137 *throughput = 170; 138 break; 139 case DP_DSC_THROUGHPUT_MODE_0_340: 140 *throughput = 340; 141 break; 142 case DP_DSC_THROUGHPUT_MODE_0_400: 143 *throughput = 400; 144 break; 145 case DP_DSC_THROUGHPUT_MODE_0_450: 146 *throughput = 450; 147 break; 148 case DP_DSC_THROUGHPUT_MODE_0_500: 149 *throughput = 500; 150 break; 151 case DP_DSC_THROUGHPUT_MODE_0_550: 152 *throughput = 550; 153 break; 154 case DP_DSC_THROUGHPUT_MODE_0_600: 155 *throughput = 600; 156 break; 157 case DP_DSC_THROUGHPUT_MODE_0_650: 158 *throughput = 650; 159 break; 160 case DP_DSC_THROUGHPUT_MODE_0_700: 161 *throughput = 700; 162 break; 163 case DP_DSC_THROUGHPUT_MODE_0_750: 164 *throughput = 750; 165 break; 166 case DP_DSC_THROUGHPUT_MODE_0_800: 167 *throughput = 800; 168 break; 169 case DP_DSC_THROUGHPUT_MODE_0_850: 170 *throughput = 850; 171 break; 172 case DP_DSC_THROUGHPUT_MODE_0_900: 173 *throughput = 900; 174 break; 175 case DP_DSC_THROUGHPUT_MODE_0_950: 176 *throughput = 950; 177 break; 178 case DP_DSC_THROUGHPUT_MODE_0_1000: 179 *throughput = 1000; 180 break; 181 default: { 182 dm_error("%s: DPCD DSC throughput mode not recognized.\n", __func__); 183 return false; 184 } 185 } 186 187 return true; 188 } 189 190 191 static bool dsc_bpp_increment_div_from_dpcd(uint8_t bpp_increment_dpcd, uint32_t *bpp_increment_div) 192 { 193 // Mask bpp increment dpcd field to avoid reading other fields 194 bpp_increment_dpcd &= 0x7; 195 196 switch (bpp_increment_dpcd) { 197 case 0: 198 *bpp_increment_div = 16; 199 break; 200 case 1: 201 *bpp_increment_div = 8; 202 break; 203 case 2: 204 *bpp_increment_div = 4; 205 break; 206 case 3: 207 *bpp_increment_div = 2; 208 break; 209 case 4: 210 *bpp_increment_div = 1; 211 break; 212 default: { 213 dm_error("%s: DPCD DSC bits-per-pixel increment not recognized.\n", __func__); 214 return false; 215 } 216 } 217 218 return true; 219 } 220 221 222 223 bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, 224 const uint8_t *dpcd_dsc_basic_data, 225 const uint8_t *dpcd_dsc_branch_decoder_caps, 226 struct dsc_dec_dpcd_caps *dsc_sink_caps) 227 { 228 if (!dpcd_dsc_basic_data) 229 return false; 230 231 dsc_sink_caps->is_dsc_supported = 232 (dpcd_dsc_basic_data[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_DECOMPRESSION_IS_SUPPORTED) != 0; 233 if (!dsc_sink_caps->is_dsc_supported) 234 return false; 235 236 dsc_sink_caps->dsc_version = dpcd_dsc_basic_data[DP_DSC_REV - DP_DSC_SUPPORT]; 237 238 { 239 int buff_block_size; 240 int buff_size; 241 242 if (!dsc_buff_block_size_from_dpcd( 243 dpcd_dsc_basic_data[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT] & 0x03, 244 &buff_block_size)) 245 return false; 246 247 buff_size = dpcd_dsc_basic_data[DP_DSC_RC_BUF_SIZE - DP_DSC_SUPPORT] + 1; 248 dsc_sink_caps->rc_buffer_size = buff_size * buff_block_size; 249 } 250 251 dsc_sink_caps->slice_caps1.raw = dpcd_dsc_basic_data[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT]; 252 if (!dsc_line_buff_depth_from_dpcd(dpcd_dsc_basic_data[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT], 253 &dsc_sink_caps->lb_bit_depth)) 254 return false; 255 256 dsc_sink_caps->is_block_pred_supported = 257 (dpcd_dsc_basic_data[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] & 258 DP_DSC_BLK_PREDICTION_IS_SUPPORTED) != 0; 259 260 dsc_sink_caps->edp_max_bits_per_pixel = 261 dpcd_dsc_basic_data[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | 262 dpcd_dsc_basic_data[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] << 8; 263 264 dsc_sink_caps->color_formats.raw = dpcd_dsc_basic_data[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT]; 265 dsc_sink_caps->color_depth.raw = dpcd_dsc_basic_data[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; 266 267 { 268 int dpcd_throughput = dpcd_dsc_basic_data[DP_DSC_PEAK_THROUGHPUT - DP_DSC_SUPPORT]; 269 int dsc_throughput_granular_delta; 270 271 dsc_throughput_granular_delta = dpcd_dsc_basic_data[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT] >> 3; 272 dsc_throughput_granular_delta *= 2; 273 274 if (!dsc_throughput_from_dpcd(dpcd_throughput & DP_DSC_THROUGHPUT_MODE_0_MASK, 275 &dsc_sink_caps->throughput_mode_0_mps)) 276 return false; 277 dsc_sink_caps->throughput_mode_0_mps += dsc_throughput_granular_delta; 278 279 dpcd_throughput = (dpcd_throughput & DP_DSC_THROUGHPUT_MODE_1_MASK) >> DP_DSC_THROUGHPUT_MODE_1_SHIFT; 280 if (!dsc_throughput_from_dpcd(dpcd_throughput, &dsc_sink_caps->throughput_mode_1_mps)) 281 return false; 282 } 283 284 dsc_sink_caps->max_slice_width = dpcd_dsc_basic_data[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] * 320; 285 dsc_sink_caps->slice_caps2.raw = dpcd_dsc_basic_data[DP_DSC_SLICE_CAP_2 - DP_DSC_SUPPORT]; 286 287 if (!dsc_bpp_increment_div_from_dpcd(dpcd_dsc_basic_data[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT], 288 &dsc_sink_caps->bpp_increment_div)) 289 return false; 290 291 if (dc->debug.dsc_bpp_increment_div) { 292 /* dsc_bpp_increment_div should onl be 1, 2, 4, 8 or 16, but rather than rejecting invalid values, 293 * we'll accept all and get it into range. This also makes the above check against 0 redundant, 294 * but that one stresses out the override will be only used if it's not 0. 295 */ 296 if (dc->debug.dsc_bpp_increment_div >= 1) 297 dsc_sink_caps->bpp_increment_div = 1; 298 if (dc->debug.dsc_bpp_increment_div >= 2) 299 dsc_sink_caps->bpp_increment_div = 2; 300 if (dc->debug.dsc_bpp_increment_div >= 4) 301 dsc_sink_caps->bpp_increment_div = 4; 302 if (dc->debug.dsc_bpp_increment_div >= 8) 303 dsc_sink_caps->bpp_increment_div = 8; 304 if (dc->debug.dsc_bpp_increment_div >= 16) 305 dsc_sink_caps->bpp_increment_div = 16; 306 } 307 308 /* Extended caps */ 309 if (dpcd_dsc_branch_decoder_caps == NULL) { // branch decoder DPCD DSC data can be null for non branch device 310 dsc_sink_caps->branch_overall_throughput_0_mps = 0; 311 dsc_sink_caps->branch_overall_throughput_1_mps = 0; 312 dsc_sink_caps->branch_max_line_width = 0; 313 return true; 314 } 315 316 dsc_sink_caps->branch_overall_throughput_0_mps = 317 dpcd_dsc_branch_decoder_caps[DP_DSC_BRANCH_OVERALL_THROUGHPUT_0 - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0]; 318 if (dsc_sink_caps->branch_overall_throughput_0_mps == 0) 319 dsc_sink_caps->branch_overall_throughput_0_mps = 0; 320 else if (dsc_sink_caps->branch_overall_throughput_0_mps == 1) 321 dsc_sink_caps->branch_overall_throughput_0_mps = 680; 322 else { 323 dsc_sink_caps->branch_overall_throughput_0_mps *= 50; 324 dsc_sink_caps->branch_overall_throughput_0_mps += 600; 325 } 326 327 dsc_sink_caps->branch_overall_throughput_1_mps = 328 dpcd_dsc_branch_decoder_caps[DP_DSC_BRANCH_OVERALL_THROUGHPUT_1 - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0]; 329 if (dsc_sink_caps->branch_overall_throughput_1_mps == 0) 330 dsc_sink_caps->branch_overall_throughput_1_mps = 0; 331 else if (dsc_sink_caps->branch_overall_throughput_1_mps == 1) 332 dsc_sink_caps->branch_overall_throughput_1_mps = 680; 333 else { 334 dsc_sink_caps->branch_overall_throughput_1_mps *= 50; 335 dsc_sink_caps->branch_overall_throughput_1_mps += 600; 336 } 337 338 dsc_sink_caps->branch_max_line_width = 339 dpcd_dsc_branch_decoder_caps[DP_DSC_BRANCH_MAX_LINE_WIDTH - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0] * 320; 340 ASSERT(dsc_sink_caps->branch_max_line_width == 0 || dsc_sink_caps->branch_max_line_width >= 5120); 341 342 dsc_sink_caps->is_dp = true; 343 return true; 344 } 345 346 347 /* If DSC is possbile, get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range and 348 * timing's pixel clock and uncompressed bandwidth. 349 * If DSC is not possible, leave '*range' untouched. 350 */ 351 bool dc_dsc_compute_bandwidth_range( 352 const struct display_stream_compressor *dsc, 353 uint32_t dsc_min_slice_height_override, 354 uint32_t min_bpp_x16, 355 uint32_t max_bpp_x16, 356 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 357 const struct dc_crtc_timing *timing, 358 const enum dc_link_encoding_format link_encoding, 359 struct dc_dsc_bw_range *range) 360 { 361 bool is_dsc_possible = false; 362 struct dsc_enc_caps dsc_enc_caps; 363 struct dsc_enc_caps dsc_common_caps; 364 struct dc_dsc_config config = {0}; 365 struct dc_dsc_config_options options = {0}; 366 367 options.dsc_min_slice_height_override = dsc_min_slice_height_override; 368 options.max_target_bpp_limit_override_x16 = max_bpp_x16; 369 options.slice_height_granularity = 1; 370 371 get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); 372 373 is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, &dsc_enc_caps, 374 timing->pixel_encoding, &dsc_common_caps); 375 376 if (is_dsc_possible) 377 is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, 378 &options, link_encoding, &config); 379 380 if (is_dsc_possible) 381 is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, 382 config.num_slices_h, &dsc_common_caps, timing, link_encoding, range); 383 384 return is_dsc_possible; 385 } 386 387 static void get_dsc_enc_caps( 388 const struct display_stream_compressor *dsc, 389 struct dsc_enc_caps *dsc_enc_caps, 390 int pixel_clock_100Hz) 391 { 392 // This is a static HW query, so we can use any DSC 393 394 memset(dsc_enc_caps, 0, sizeof(struct dsc_enc_caps)); 395 if (dsc) { 396 if (!dsc->ctx->dc->debug.disable_dsc) 397 dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz); 398 if (dsc->ctx->dc->debug.native422_support) 399 dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; 400 } 401 } 402 403 /* Returns 'false' if no intersection was found for at least one capability. 404 * It also implicitly validates some sink caps against invalid value of zero. 405 */ 406 static bool intersect_dsc_caps( 407 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 408 const struct dsc_enc_caps *dsc_enc_caps, 409 enum dc_pixel_encoding pixel_encoding, 410 struct dsc_enc_caps *dsc_common_caps) 411 { 412 int32_t max_slices; 413 int32_t total_sink_throughput; 414 415 memset(dsc_common_caps, 0, sizeof(struct dsc_enc_caps)); 416 417 dsc_common_caps->dsc_version = min(dsc_sink_caps->dsc_version, dsc_enc_caps->dsc_version); 418 if (!dsc_common_caps->dsc_version) 419 return false; 420 421 dsc_common_caps->slice_caps.bits.NUM_SLICES_1 = 422 dsc_sink_caps->slice_caps1.bits.NUM_SLICES_1 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_1; 423 dsc_common_caps->slice_caps.bits.NUM_SLICES_2 = 424 dsc_sink_caps->slice_caps1.bits.NUM_SLICES_2 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_2; 425 dsc_common_caps->slice_caps.bits.NUM_SLICES_4 = 426 dsc_sink_caps->slice_caps1.bits.NUM_SLICES_4 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_4; 427 dsc_common_caps->slice_caps.bits.NUM_SLICES_8 = 428 dsc_sink_caps->slice_caps1.bits.NUM_SLICES_8 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_8; 429 dsc_common_caps->slice_caps.bits.NUM_SLICES_12 = 430 dsc_sink_caps->slice_caps1.bits.NUM_SLICES_12 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_12; 431 dsc_common_caps->slice_caps.bits.NUM_SLICES_16 = 432 dsc_sink_caps->slice_caps2.bits.NUM_SLICES_16 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_16; 433 434 if (!dsc_common_caps->slice_caps.raw) 435 return false; 436 437 dsc_common_caps->lb_bit_depth = min(dsc_sink_caps->lb_bit_depth, dsc_enc_caps->lb_bit_depth); 438 if (!dsc_common_caps->lb_bit_depth) 439 return false; 440 441 dsc_common_caps->is_block_pred_supported = 442 dsc_sink_caps->is_block_pred_supported && dsc_enc_caps->is_block_pred_supported; 443 444 dsc_common_caps->color_formats.raw = dsc_sink_caps->color_formats.raw & dsc_enc_caps->color_formats.raw; 445 if (!dsc_common_caps->color_formats.raw) 446 return false; 447 448 dsc_common_caps->color_depth.raw = dsc_sink_caps->color_depth.raw & dsc_enc_caps->color_depth.raw; 449 if (!dsc_common_caps->color_depth.raw) 450 return false; 451 452 max_slices = 0; 453 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_1) 454 max_slices = 1; 455 456 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_2) 457 max_slices = 2; 458 459 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_4) 460 max_slices = 4; 461 462 total_sink_throughput = max_slices * dsc_sink_caps->throughput_mode_0_mps; 463 if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) 464 total_sink_throughput = max_slices * dsc_sink_caps->throughput_mode_1_mps; 465 466 dsc_common_caps->max_total_throughput_mps = min(total_sink_throughput, dsc_enc_caps->max_total_throughput_mps); 467 468 dsc_common_caps->max_slice_width = min(dsc_sink_caps->max_slice_width, dsc_enc_caps->max_slice_width); 469 if (!dsc_common_caps->max_slice_width) 470 return false; 471 472 dsc_common_caps->bpp_increment_div = min(dsc_sink_caps->bpp_increment_div, dsc_enc_caps->bpp_increment_div); 473 474 // TODO DSC: Remove this workaround for N422 and 420 once it's fixed, or move it to get_dsc_encoder_caps() 475 if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) 476 dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8); 477 478 dsc_common_caps->edp_sink_max_bits_per_pixel = dsc_sink_caps->edp_max_bits_per_pixel; 479 dsc_common_caps->is_dp = dsc_sink_caps->is_dp; 480 return true; 481 } 482 483 static inline uint32_t dsc_div_by_10_round_up(uint32_t value) 484 { 485 return (value + 9) / 10; 486 } 487 488 static uint32_t compute_bpp_x16_from_target_bandwidth( 489 const uint32_t bandwidth_in_kbps, 490 const struct dc_crtc_timing *timing, 491 const uint32_t num_slices_h, 492 const uint32_t bpp_increment_div, 493 const bool is_dp) 494 { 495 uint32_t overhead_in_kbps; 496 struct fixed31_32 effective_bandwidth_in_kbps; 497 struct fixed31_32 bpp_x16; 498 499 overhead_in_kbps = dc_dsc_stream_bandwidth_overhead_in_kbps( 500 timing, num_slices_h, is_dp); 501 effective_bandwidth_in_kbps = dc_fixpt_from_int(bandwidth_in_kbps); 502 effective_bandwidth_in_kbps = dc_fixpt_sub_int(effective_bandwidth_in_kbps, 503 overhead_in_kbps); 504 bpp_x16 = dc_fixpt_mul_int(effective_bandwidth_in_kbps, 10); 505 bpp_x16 = dc_fixpt_div_int(bpp_x16, timing->pix_clk_100hz); 506 bpp_x16 = dc_fixpt_from_int(dc_fixpt_floor(dc_fixpt_mul_int(bpp_x16, bpp_increment_div))); 507 bpp_x16 = dc_fixpt_div_int(bpp_x16, bpp_increment_div); 508 bpp_x16 = dc_fixpt_mul_int(bpp_x16, 16); 509 return dc_fixpt_floor(bpp_x16); 510 } 511 512 /* Decide DSC bandwidth range based on signal, timing, specs specific and input min and max 513 * requirements. 514 * The range output includes decided min/max target bpp, the respective bandwidth requirements 515 * and native timing bandwidth requirement when DSC is not used. 516 */ 517 static bool decide_dsc_bandwidth_range( 518 const uint32_t min_bpp_x16, 519 const uint32_t max_bpp_x16, 520 const uint32_t num_slices_h, 521 const struct dsc_enc_caps *dsc_caps, 522 const struct dc_crtc_timing *timing, 523 const enum dc_link_encoding_format link_encoding, 524 struct dc_dsc_bw_range *range) 525 { 526 uint32_t preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; 527 528 memset(range, 0, sizeof(*range)); 529 530 /* apply signal, timing, specs and explicitly specified DSC range requirements */ 531 if (preferred_bpp_x16) { 532 if (preferred_bpp_x16 <= max_bpp_x16 && 533 preferred_bpp_x16 >= min_bpp_x16) { 534 range->max_target_bpp_x16 = preferred_bpp_x16; 535 range->min_target_bpp_x16 = preferred_bpp_x16; 536 } 537 } 538 /* TODO - make this value generic to all signal types */ 539 else if (dsc_caps->edp_sink_max_bits_per_pixel) { 540 /* apply max bpp limitation from edp sink */ 541 range->max_target_bpp_x16 = MIN(dsc_caps->edp_sink_max_bits_per_pixel, 542 max_bpp_x16); 543 range->min_target_bpp_x16 = min_bpp_x16; 544 } 545 else { 546 range->max_target_bpp_x16 = max_bpp_x16; 547 range->min_target_bpp_x16 = min_bpp_x16; 548 } 549 550 /* populate output structure */ 551 if (range->max_target_bpp_x16 >= range->min_target_bpp_x16 && range->min_target_bpp_x16 > 0) { 552 /* native stream bandwidth */ 553 range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing, link_encoding); 554 555 /* max dsc target bpp */ 556 range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 557 range->max_target_bpp_x16, num_slices_h, dsc_caps->is_dp); 558 559 /* min dsc target bpp */ 560 range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 561 range->min_target_bpp_x16, num_slices_h, dsc_caps->is_dp); 562 } 563 564 return range->max_kbps >= range->min_kbps && range->min_kbps > 0; 565 } 566 567 /* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy. 568 * 569 * Returns: 570 * - 'true' if target bpp is decided 571 * - 'false' if target bpp cannot be decided (e.g. cannot fit even with min DSC bpp), 572 */ 573 static bool decide_dsc_target_bpp_x16( 574 const struct dc_dsc_policy *policy, 575 const struct dsc_enc_caps *dsc_common_caps, 576 const int target_bandwidth_kbps, 577 const struct dc_crtc_timing *timing, 578 const int num_slices_h, 579 const enum dc_link_encoding_format link_encoding, 580 int *target_bpp_x16) 581 { 582 struct dc_dsc_bw_range range; 583 584 *target_bpp_x16 = 0; 585 586 if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, 587 num_slices_h, dsc_common_caps, timing, link_encoding, &range)) { 588 if (target_bandwidth_kbps >= range.stream_kbps) { 589 if (policy->enable_dsc_when_not_needed) 590 /* enable max bpp even dsc is not needed */ 591 *target_bpp_x16 = range.max_target_bpp_x16; 592 } else if (target_bandwidth_kbps >= range.max_kbps) { 593 /* use max target bpp allowed */ 594 *target_bpp_x16 = range.max_target_bpp_x16; 595 } else if (target_bandwidth_kbps >= range.min_kbps) { 596 /* use target bpp that can take entire target bandwidth */ 597 *target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( 598 target_bandwidth_kbps, timing, num_slices_h, 599 dsc_common_caps->bpp_increment_div, 600 dsc_common_caps->is_dp); 601 } 602 } 603 604 return *target_bpp_x16 != 0; 605 } 606 607 #define MIN_AVAILABLE_SLICES_SIZE 6 608 609 static int get_available_dsc_slices(union dsc_enc_slice_caps slice_caps, int *available_slices) 610 { 611 int idx = 0; 612 613 if (slice_caps.bits.NUM_SLICES_1) 614 available_slices[idx++] = 1; 615 616 if (slice_caps.bits.NUM_SLICES_2) 617 available_slices[idx++] = 2; 618 619 if (slice_caps.bits.NUM_SLICES_4) 620 available_slices[idx++] = 4; 621 622 if (slice_caps.bits.NUM_SLICES_8) 623 available_slices[idx++] = 8; 624 625 if (slice_caps.bits.NUM_SLICES_12) 626 available_slices[idx++] = 12; 627 628 if (slice_caps.bits.NUM_SLICES_16) 629 available_slices[idx++] = 16; 630 631 return idx; 632 } 633 634 635 static int get_max_dsc_slices(union dsc_enc_slice_caps slice_caps) 636 { 637 int max_slices = 0; 638 int available_slices[MIN_AVAILABLE_SLICES_SIZE]; 639 int end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]); 640 641 if (end_idx > 0) 642 max_slices = available_slices[end_idx - 1]; 643 644 return max_slices; 645 } 646 647 648 // Increment slice number in available slice numbers stops if possible, or just increment if not 649 static int inc_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices) 650 { 651 // Get next bigger num slices available in common caps 652 int available_slices[MIN_AVAILABLE_SLICES_SIZE]; 653 int end_idx; 654 int i; 655 int new_num_slices = num_slices; 656 657 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]); 658 if (end_idx == 0) { 659 // No available slices found 660 new_num_slices++; 661 return new_num_slices; 662 } 663 664 // Numbers of slices found - get the next bigger number 665 for (i = 0; i < end_idx; i++) { 666 if (new_num_slices < available_slices[i]) { 667 new_num_slices = available_slices[i]; 668 break; 669 } 670 } 671 672 if (new_num_slices == num_slices) // No bigger number of slices found 673 new_num_slices++; 674 675 return new_num_slices; 676 } 677 678 679 // Decrement slice number in available slice numbers stops if possible, or just decrement if not. Stop at zero. 680 static int dec_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices) 681 { 682 // Get next bigger num slices available in common caps 683 int available_slices[MIN_AVAILABLE_SLICES_SIZE]; 684 int end_idx; 685 int i; 686 int new_num_slices = num_slices; 687 688 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]); 689 if (end_idx == 0 && new_num_slices > 0) { 690 // No numbers of slices found 691 new_num_slices++; 692 return new_num_slices; 693 } 694 695 // Numbers of slices found - get the next smaller number 696 for (i = end_idx - 1; i >= 0; i--) { 697 if (new_num_slices > available_slices[i]) { 698 new_num_slices = available_slices[i]; 699 break; 700 } 701 } 702 703 if (new_num_slices == num_slices) { 704 // No smaller number of slices found 705 new_num_slices--; 706 if (new_num_slices < 0) 707 new_num_slices = 0; 708 } 709 710 return new_num_slices; 711 } 712 713 714 // Choose next bigger number of slices if the requested number of slices is not available 715 static int fit_num_slices_up(union dsc_enc_slice_caps slice_caps, int num_slices) 716 { 717 // Get next bigger num slices available in common caps 718 int available_slices[MIN_AVAILABLE_SLICES_SIZE]; 719 int end_idx; 720 int i; 721 int new_num_slices = num_slices; 722 723 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]); 724 if (end_idx == 0) { 725 // No available slices found 726 new_num_slices++; 727 return new_num_slices; 728 } 729 730 // Numbers of slices found - get the equal or next bigger number 731 for (i = 0; i < end_idx; i++) { 732 if (new_num_slices <= available_slices[i]) { 733 new_num_slices = available_slices[i]; 734 break; 735 } 736 } 737 738 return new_num_slices; 739 } 740 741 742 /* Attempts to set DSC configuration for the stream, applying DSC policy. 743 * Returns 'true' if successful or 'false' if not. 744 * 745 * Parameters: 746 * 747 * dsc_sink_caps - DSC sink decoder capabilities (from DPCD) 748 * 749 * dsc_enc_caps - DSC encoder capabilities 750 * 751 * target_bandwidth_kbps - Target bandwidth to fit the stream into. 752 * If 0, do not calculate target bpp. 753 * 754 * timing - The stream timing to fit into 'target_bandwidth_kbps' or apply 755 * maximum compression to, if 'target_badwidth == 0' 756 * 757 * dsc_cfg - DSC configuration to use if it was possible to come up with 758 * one for the given inputs. 759 * The target bitrate after DSC can be calculated by multiplying 760 * dsc_cfg.bits_per_pixel (in U6.4 format) by pixel rate, e.g. 761 * 762 * dsc_stream_bitrate_kbps = (int)ceil(timing->pix_clk_khz * dsc_cfg.bits_per_pixel / 16.0); 763 */ 764 static bool setup_dsc_config( 765 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 766 const struct dsc_enc_caps *dsc_enc_caps, 767 int target_bandwidth_kbps, 768 const struct dc_crtc_timing *timing, 769 const struct dc_dsc_config_options *options, 770 const enum dc_link_encoding_format link_encoding, 771 struct dc_dsc_config *dsc_cfg) 772 { 773 struct dsc_enc_caps dsc_common_caps; 774 int max_slices_h = 0; 775 int min_slices_h = 0; 776 int num_slices_h = 0; 777 int pic_width; 778 int slice_width; 779 int target_bpp; 780 int sink_per_slice_throughput_mps; 781 int branch_max_throughput_mps = 0; 782 bool is_dsc_possible = false; 783 int pic_height; 784 int slice_height; 785 struct dc_dsc_policy policy; 786 787 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); 788 789 dc_dsc_get_policy_for_timing(timing, options->max_target_bpp_limit_override_x16, &policy); 790 pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; 791 pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; 792 793 if (!dsc_sink_caps->is_dsc_supported) 794 goto done; 795 796 if (dsc_sink_caps->branch_max_line_width && dsc_sink_caps->branch_max_line_width < pic_width) 797 goto done; 798 799 // Intersect decoder with encoder DSC caps and validate DSC settings 800 is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, dsc_enc_caps, timing->pixel_encoding, &dsc_common_caps); 801 if (!is_dsc_possible) 802 goto done; 803 804 sink_per_slice_throughput_mps = 0; 805 806 // Validate available DSC settings against the mode timing 807 808 // Validate color format (and pick up the throughput values) 809 dsc_cfg->ycbcr422_simple = false; 810 switch (timing->pixel_encoding) { 811 case PIXEL_ENCODING_RGB: 812 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.RGB; 813 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps; 814 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps; 815 break; 816 case PIXEL_ENCODING_YCBCR444: 817 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_444; 818 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps; 819 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps; 820 break; 821 case PIXEL_ENCODING_YCBCR422: 822 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422; 823 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps; 824 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps; 825 if (!is_dsc_possible) { 826 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_SIMPLE_422; 827 dsc_cfg->ycbcr422_simple = is_dsc_possible; 828 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps; 829 } 830 break; 831 case PIXEL_ENCODING_YCBCR420: 832 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_420; 833 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps; 834 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps; 835 break; 836 default: 837 is_dsc_possible = false; 838 } 839 840 // Validate branch's maximum throughput 841 if (branch_max_throughput_mps && dsc_div_by_10_round_up(timing->pix_clk_100hz) > branch_max_throughput_mps * 1000) 842 is_dsc_possible = false; 843 844 if (!is_dsc_possible) 845 goto done; 846 847 // Color depth 848 switch (timing->display_color_depth) { 849 case COLOR_DEPTH_888: 850 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_8_BPC; 851 break; 852 case COLOR_DEPTH_101010: 853 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_10_BPC; 854 break; 855 case COLOR_DEPTH_121212: 856 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_12_BPC; 857 break; 858 default: 859 is_dsc_possible = false; 860 } 861 862 if (!is_dsc_possible) 863 goto done; 864 865 // Slice width (i.e. number of slices per line) 866 max_slices_h = get_max_dsc_slices(dsc_common_caps.slice_caps); 867 868 while (max_slices_h > 0) { 869 if (pic_width % max_slices_h == 0) 870 break; 871 872 max_slices_h = dec_num_slices(dsc_common_caps.slice_caps, max_slices_h); 873 } 874 875 is_dsc_possible = (dsc_common_caps.max_slice_width > 0); 876 if (!is_dsc_possible) 877 goto done; 878 879 min_slices_h = pic_width / dsc_common_caps.max_slice_width; 880 if (pic_width % dsc_common_caps.max_slice_width) 881 min_slices_h++; 882 883 min_slices_h = fit_num_slices_up(dsc_common_caps.slice_caps, min_slices_h); 884 885 while (min_slices_h <= max_slices_h) { 886 int pix_clk_per_slice_khz = dsc_div_by_10_round_up(timing->pix_clk_100hz) / min_slices_h; 887 if (pix_clk_per_slice_khz <= sink_per_slice_throughput_mps * 1000) 888 break; 889 890 min_slices_h = inc_num_slices(dsc_common_caps.slice_caps, min_slices_h); 891 } 892 893 is_dsc_possible = (min_slices_h <= max_slices_h); 894 895 if (pic_width % min_slices_h != 0) 896 min_slices_h = 0; // DSC TODO: Maybe try increasing the number of slices first? 897 898 if (min_slices_h == 0 && max_slices_h == 0) 899 is_dsc_possible = false; 900 901 if (!is_dsc_possible) 902 goto done; 903 904 if (policy.use_min_slices_h) { 905 if (min_slices_h > 0) 906 num_slices_h = min_slices_h; 907 else if (max_slices_h > 0) { // Fall back to max slices if min slices is not working out 908 if (policy.max_slices_h) 909 num_slices_h = min(policy.max_slices_h, max_slices_h); 910 else 911 num_slices_h = max_slices_h; 912 } else 913 is_dsc_possible = false; 914 } else { 915 if (max_slices_h > 0) { 916 if (policy.max_slices_h) 917 num_slices_h = min(policy.max_slices_h, max_slices_h); 918 else 919 num_slices_h = max_slices_h; 920 } else if (min_slices_h > 0) // Fall back to min slices if max slices is not possible 921 num_slices_h = min_slices_h; 922 else 923 is_dsc_possible = false; 924 } 925 // When we force ODM, num dsc h slices must be divisible by num odm h slices 926 switch (options->dsc_force_odm_hslice_override) { 927 case 0: 928 case 1: 929 break; 930 case 2: 931 if (num_slices_h < 2) 932 num_slices_h = fit_num_slices_up(dsc_common_caps.slice_caps, 2); 933 break; 934 case 3: 935 if (dsc_common_caps.slice_caps.bits.NUM_SLICES_12) 936 num_slices_h = 12; 937 else 938 num_slices_h = 0; 939 break; 940 case 4: 941 if (num_slices_h < 4) 942 num_slices_h = fit_num_slices_up(dsc_common_caps.slice_caps, 4); 943 break; 944 default: 945 break; 946 } 947 if (num_slices_h == 0) 948 is_dsc_possible = false; 949 if (!is_dsc_possible) 950 goto done; 951 952 dsc_cfg->num_slices_h = num_slices_h; 953 slice_width = pic_width / num_slices_h; 954 955 is_dsc_possible = slice_width <= dsc_common_caps.max_slice_width; 956 if (!is_dsc_possible) 957 goto done; 958 959 // Slice height (i.e. number of slices per column): start with policy and pick the first one that height is divisible by. 960 // For 4:2:0 make sure the slice height is divisible by 2 as well. 961 if (options->dsc_min_slice_height_override == 0) 962 slice_height = min(policy.min_slice_height, pic_height); 963 else 964 slice_height = min((int)(options->dsc_min_slice_height_override), pic_height); 965 966 while (slice_height < pic_height && (pic_height % slice_height != 0 || 967 slice_height % options->slice_height_granularity != 0 || 968 (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0))) 969 slice_height++; 970 971 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) // For the case when pic_height < dsc_policy.min_sice_height 972 is_dsc_possible = (slice_height % 2 == 0); 973 974 if (!is_dsc_possible) 975 goto done; 976 977 if (slice_height > 0) { 978 dsc_cfg->num_slices_v = pic_height / slice_height; 979 } else { 980 is_dsc_possible = false; 981 goto done; 982 } 983 984 if (target_bandwidth_kbps > 0) { 985 is_dsc_possible = decide_dsc_target_bpp_x16( 986 &policy, 987 &dsc_common_caps, 988 target_bandwidth_kbps, 989 timing, 990 num_slices_h, 991 link_encoding, 992 &target_bpp); 993 dsc_cfg->bits_per_pixel = target_bpp; 994 } 995 if (!is_dsc_possible) 996 goto done; 997 998 // Final decission: can we do DSC or not? 999 if (is_dsc_possible) { 1000 // Fill out the rest of DSC settings 1001 dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported; 1002 dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth; 1003 dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4; 1004 dsc_cfg->is_dp = dsc_sink_caps->is_dp; 1005 } 1006 1007 done: 1008 if (!is_dsc_possible) 1009 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); 1010 1011 return is_dsc_possible; 1012 } 1013 1014 bool dc_dsc_compute_config( 1015 const struct display_stream_compressor *dsc, 1016 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 1017 const struct dc_dsc_config_options *options, 1018 uint32_t target_bandwidth_kbps, 1019 const struct dc_crtc_timing *timing, 1020 const enum dc_link_encoding_format link_encoding, 1021 struct dc_dsc_config *dsc_cfg) 1022 { 1023 bool is_dsc_possible = false; 1024 struct dsc_enc_caps dsc_enc_caps; 1025 1026 get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); 1027 is_dsc_possible = setup_dsc_config(dsc_sink_caps, 1028 &dsc_enc_caps, 1029 target_bandwidth_kbps, 1030 timing, options, link_encoding, dsc_cfg); 1031 return is_dsc_possible; 1032 } 1033 1034 uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing, 1035 uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp) 1036 { 1037 uint32_t overhead_in_kbps; 1038 struct fixed31_32 bpp; 1039 struct fixed31_32 actual_bandwidth_in_kbps; 1040 1041 overhead_in_kbps = dc_dsc_stream_bandwidth_overhead_in_kbps( 1042 timing, num_slices_h, is_dp); 1043 bpp = dc_fixpt_from_fraction(bpp_x16, 16); 1044 actual_bandwidth_in_kbps = dc_fixpt_from_fraction(timing->pix_clk_100hz, 10); 1045 actual_bandwidth_in_kbps = dc_fixpt_mul(actual_bandwidth_in_kbps, bpp); 1046 actual_bandwidth_in_kbps = dc_fixpt_add_int(actual_bandwidth_in_kbps, overhead_in_kbps); 1047 return dc_fixpt_ceil(actual_bandwidth_in_kbps); 1048 } 1049 1050 uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps( 1051 const struct dc_crtc_timing *timing, 1052 const int num_slices_h, 1053 const bool is_dp) 1054 { 1055 struct fixed31_32 max_dsc_overhead; 1056 struct fixed31_32 refresh_rate; 1057 1058 if (dsc_policy_disable_dsc_stream_overhead || !is_dp) 1059 return 0; 1060 1061 /* use target bpp that can take entire target bandwidth */ 1062 refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz); 1063 refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total); 1064 refresh_rate = dc_fixpt_div_int(refresh_rate, timing->v_total); 1065 refresh_rate = dc_fixpt_mul_int(refresh_rate, 100); 1066 1067 max_dsc_overhead = dc_fixpt_from_int(num_slices_h); 1068 max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_total); 1069 max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256); 1070 max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000); 1071 max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate); 1072 1073 return dc_fixpt_ceil(max_dsc_overhead); 1074 } 1075 1076 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, 1077 uint32_t max_target_bpp_limit_override_x16, 1078 struct dc_dsc_policy *policy) 1079 { 1080 uint32_t bpc = 0; 1081 1082 policy->min_target_bpp = 0; 1083 policy->max_target_bpp = 0; 1084 1085 /* DSC Policy: Use minimum number of slices that fits the pixel clock */ 1086 policy->use_min_slices_h = true; 1087 1088 /* DSC Policy: Use max available slices 1089 * (in our case 4 for or 8, depending on the mode) 1090 */ 1091 policy->max_slices_h = 0; 1092 1093 /* DSC Policy: Use slice height recommended 1094 * by VESA DSC Spreadsheet user guide 1095 */ 1096 policy->min_slice_height = 108; 1097 1098 /* DSC Policy: follow DP specs with an internal upper limit to 16 bpp 1099 * for better interoperability 1100 */ 1101 switch (timing->display_color_depth) { 1102 case COLOR_DEPTH_888: 1103 bpc = 8; 1104 break; 1105 case COLOR_DEPTH_101010: 1106 bpc = 10; 1107 break; 1108 case COLOR_DEPTH_121212: 1109 bpc = 12; 1110 break; 1111 default: 1112 return; 1113 } 1114 switch (timing->pixel_encoding) { 1115 case PIXEL_ENCODING_RGB: 1116 case PIXEL_ENCODING_YCBCR444: 1117 case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */ 1118 /* DP specs limits to 8 */ 1119 policy->min_target_bpp = 8; 1120 /* DP specs limits to 3 x bpc */ 1121 policy->max_target_bpp = 3 * bpc; 1122 break; 1123 case PIXEL_ENCODING_YCBCR420: 1124 /* DP specs limits to 6 */ 1125 policy->min_target_bpp = 6; 1126 /* DP specs limits to 1.5 x bpc assume bpc is an even number */ 1127 policy->max_target_bpp = bpc * 3 / 2; 1128 break; 1129 default: 1130 return; 1131 } 1132 1133 /* internal upper limit, default 16 bpp */ 1134 if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) 1135 policy->max_target_bpp = dsc_policy_max_target_bpp_limit; 1136 1137 /* apply override */ 1138 if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > max_target_bpp_limit_override_x16 / 16) 1139 policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16; 1140 1141 /* enable DSC when not needed, default false */ 1142 if (dsc_policy_enable_dsc_when_not_needed) 1143 policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed; 1144 else 1145 policy->enable_dsc_when_not_needed = false; 1146 } 1147 1148 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit) 1149 { 1150 dsc_policy_max_target_bpp_limit = limit; 1151 } 1152 1153 void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable) 1154 { 1155 dsc_policy_enable_dsc_when_not_needed = enable; 1156 } 1157 1158 void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable) 1159 { 1160 dsc_policy_disable_dsc_stream_overhead = disable; 1161 } 1162 1163 void dc_set_disable_128b_132b_stream_overhead(bool disable) 1164 { 1165 disable_128b_132b_stream_overhead = disable; 1166 } 1167 1168 bool dc_get_disable_128b_132b_stream_overhead(void) 1169 { 1170 return disable_128b_132b_stream_overhead; 1171 } 1172 1173 void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options) 1174 { 1175 options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override; 1176 options->dsc_force_odm_hslice_override = dc->debug.force_odm_combine; 1177 options->max_target_bpp_limit_override_x16 = 0; 1178 options->slice_height_granularity = 1; 1179 } 1180