Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: move bpp range decision in decide dsc bw range function

[why]
Before get dsc bw range is used to compute DSC bw range
based on the given fixed bpp min/max input.
The new change will merge any specs, signal, timing specific
bpp range decision into this function. So the function needs to make
a decision with all aspects considered.

Acked-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Reviewed-by: George Shen <george.shen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Wenjing Liu and committed by
Alex Deucher
e0d09634 952ab0b3

+67 -61
+5 -1
drivers/gpu/drm/amd/display/dc/dc_dsc.h
··· 51 51 int min_slice_height; // Must not be less than 8 52 52 uint32_t max_target_bpp; 53 53 uint32_t min_target_bpp; 54 - uint32_t preferred_bpp_x16; 55 54 bool enable_dsc_when_not_needed; 56 55 }; 57 56 ··· 85 86 const int num_slices_h, 86 87 const bool is_dp); 87 88 89 + /* TODO - Hardware/specs limitation should be owned by dc dsc and returned to DM, 90 + * and DM can choose to OVERRIDE the limitation on CASE BY CASE basis. 91 + * Hardware/specs limitation should not be writable by DM. 92 + * It should be decoupled from DM specific policy and named differently. 93 + */ 88 94 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, 89 95 uint32_t max_target_bpp_limit_override_x16, 90 96 struct dc_dsc_policy *policy);
+62 -60
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
··· 40 40 41 41 static bool dsc_policy_disable_dsc_stream_overhead; 42 42 43 + #ifndef MAX 44 + #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 45 + #endif 46 + #ifndef MIN 47 + #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 48 + #endif 49 + 43 50 /* Forward Declerations */ 44 - static void get_dsc_bandwidth_range( 51 + static bool decide_dsc_bandwidth_range( 45 52 const uint32_t min_bpp_x16, 46 53 const uint32_t max_bpp_x16, 47 54 const uint32_t num_slices_h, ··· 363 356 dsc_min_slice_height_override, max_bpp_x16, &config); 364 357 365 358 if (is_dsc_possible) 366 - get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, 359 + is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, 367 360 config.num_slices_h, &dsc_common_caps, timing, range); 368 361 369 362 return is_dsc_possible; ··· 488 481 return dc_fixpt_floor(bpp_x16); 489 482 } 490 483 491 - /* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock 492 - * and uncompressed bandwidth. 484 + /* Decide DSC bandwidth range based on signal, timing, specs specific and input min and max 485 + * requirements. 486 + * The range output includes decided min/max target bpp, the respective bandwidth requirements 487 + * and native timing bandwidth requirement when DSC is not used. 493 488 */ 494 - static void get_dsc_bandwidth_range( 489 + static bool decide_dsc_bandwidth_range( 495 490 const uint32_t min_bpp_x16, 496 491 const uint32_t max_bpp_x16, 497 492 const uint32_t num_slices_h, ··· 501 492 const struct dc_crtc_timing *timing, 502 493 struct dc_dsc_bw_range *range) 503 494 { 504 - /* native stream bandwidth */ 505 - range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); 495 + uint32_t preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; 506 496 507 - /* max dsc target bpp */ 508 - range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 509 - max_bpp_x16, num_slices_h, dsc_caps->is_dp); 510 - range->max_target_bpp_x16 = max_bpp_x16; 511 - if (range->max_kbps > range->stream_kbps) { 512 - /* max dsc target bpp is capped to native bandwidth */ 513 - range->max_kbps = range->stream_kbps; 514 - range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( 515 - range->max_kbps, timing, num_slices_h, 516 - dsc_caps->bpp_increment_div, 517 - dsc_caps->is_dp); 497 + memset(range, 0, sizeof(*range)); 498 + 499 + /* apply signal, timing, specs and explicitly specified DSC range requirements */ 500 + if (preferred_bpp_x16) { 501 + if (preferred_bpp_x16 <= max_bpp_x16 && 502 + preferred_bpp_x16 >= min_bpp_x16) { 503 + range->max_target_bpp_x16 = preferred_bpp_x16; 504 + range->min_target_bpp_x16 = preferred_bpp_x16; 505 + } 506 + } 507 + else { 508 + range->max_target_bpp_x16 = max_bpp_x16; 509 + range->min_target_bpp_x16 = min_bpp_x16; 518 510 } 519 511 520 - /* min dsc target bpp */ 521 - range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 522 - min_bpp_x16, num_slices_h, dsc_caps->is_dp); 523 - range->min_target_bpp_x16 = min_bpp_x16; 524 - if (range->min_kbps > range->max_kbps) { 525 - /* min dsc target bpp is capped to max dsc bandwidth*/ 526 - range->min_kbps = range->max_kbps; 527 - range->min_target_bpp_x16 = range->max_target_bpp_x16; 512 + /* populate output structure */ 513 + if (range->max_target_bpp_x16 >= range->min_target_bpp_x16 && range->min_target_bpp_x16 > 0) { 514 + /* native stream bandwidth */ 515 + range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); 516 + 517 + /* max dsc target bpp */ 518 + range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 519 + range->max_target_bpp_x16, num_slices_h, dsc_caps->is_dp); 520 + 521 + /* min dsc target bpp */ 522 + range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, 523 + range->min_target_bpp_x16, num_slices_h, dsc_caps->is_dp); 528 524 } 525 + 526 + return range->max_kbps >= range->min_kbps && range->min_kbps > 0; 529 527 } 530 528 531 529 /* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy. 532 530 * 533 531 * Returns: 534 - * - 'true' if DSC was required by policy and was successfully applied 535 - * - 'false' if DSC was not necessary (e.g. if uncompressed stream fits 'target_bandwidth_kbps'), 536 - * or if it couldn't be applied based on DSC policy. 532 + * - 'true' if target bpp is decided 533 + * - 'false' if target bpp cannot be decided (e.g. cannot fit even with min DSC bpp), 537 534 */ 538 535 static bool decide_dsc_target_bpp_x16( 539 536 const struct dc_dsc_policy *policy, ··· 549 534 const int num_slices_h, 550 535 int *target_bpp_x16) 551 536 { 552 - bool should_use_dsc = false; 553 537 struct dc_dsc_bw_range range; 554 538 555 - memset(&range, 0, sizeof(range)); 539 + *target_bpp_x16 = 0; 556 540 557 - get_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, 558 - num_slices_h, dsc_common_caps, timing, &range); 559 - if (!policy->enable_dsc_when_not_needed && target_bandwidth_kbps >= range.stream_kbps) { 560 - /* enough bandwidth without dsc */ 561 - *target_bpp_x16 = 0; 562 - should_use_dsc = false; 563 - } else if (policy->preferred_bpp_x16 > 0 && 564 - policy->preferred_bpp_x16 <= range.max_target_bpp_x16 && 565 - policy->preferred_bpp_x16 >= range.min_target_bpp_x16) { 566 - *target_bpp_x16 = policy->preferred_bpp_x16; 567 - should_use_dsc = true; 568 - } else if (target_bandwidth_kbps >= range.max_kbps) { 569 - /* use max target bpp allowed */ 570 - *target_bpp_x16 = range.max_target_bpp_x16; 571 - should_use_dsc = true; 572 - } else if (target_bandwidth_kbps >= range.min_kbps) { 573 - /* use target bpp that can take entire target bandwidth */ 574 - *target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( 575 - target_bandwidth_kbps, timing, num_slices_h, 576 - dsc_common_caps->bpp_increment_div, 577 - dsc_common_caps->is_dp); 578 - should_use_dsc = true; 579 - } else { 580 - /* not enough bandwidth to fulfill minimum requirement */ 581 - *target_bpp_x16 = 0; 582 - should_use_dsc = false; 541 + if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, 542 + num_slices_h, dsc_common_caps, timing, &range)) { 543 + if (target_bandwidth_kbps >= range.stream_kbps) { 544 + if (policy->enable_dsc_when_not_needed) 545 + /* enable max bpp even dsc is not needed */ 546 + *target_bpp_x16 = range.max_target_bpp_x16; 547 + } else if (target_bandwidth_kbps >= range.max_kbps) { 548 + /* use max target bpp allowed */ 549 + *target_bpp_x16 = range.max_target_bpp_x16; 550 + } else if (target_bandwidth_kbps >= range.min_kbps) { 551 + /* use target bpp that can take entire target bandwidth */ 552 + *target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( 553 + target_bandwidth_kbps, timing, num_slices_h, 554 + dsc_common_caps->bpp_increment_div, 555 + dsc_common_caps->is_dp); 556 + } 583 557 } 584 558 585 - return should_use_dsc; 559 + return *target_bpp_x16 != 0; 586 560 } 587 561 588 562 #define MIN_AVAILABLE_SLICES_SIZE 4 ··· 1062 1058 default: 1063 1059 return; 1064 1060 } 1065 - 1066 - policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; 1067 1061 1068 1062 /* internal upper limit, default 16 bpp */ 1069 1063 if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit)