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

drm/amd/display: Add changes for dsc bpp in 16ths and unify bw calculations

[Why?]
Some code still expected bpp to be used in whole bits, not 16ths. dsc.c uses
redundant function now found in dc to calculate stream bandwidth from timing.

[How?]
Fix code to work with 16ths instead of whole bits for dsc bpp.
Refactor get_dsc_bandwidth to accept inputs in 16ths of a bit.
Use dc function to calculate bandwidth from timing, and make dsc bw calculation
a part of dsc.c.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Solomon Chiu <solomon.chiu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dillon Varone and committed by
Alex Deucher
8c2f14c3 86ca3cbe

+43 -80
+3 -6
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 3498 3498 } 3499 3499 } 3500 3500 3501 + uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16); 3502 + 3501 3503 uint32_t dc_bandwidth_in_kbps_from_timing( 3502 3504 const struct dc_crtc_timing *timing) 3503 3505 { 3504 3506 uint32_t bits_per_channel = 0; 3505 3507 uint32_t kbps; 3506 - struct fixed31_32 link_bw_kbps; 3507 3508 3508 3509 if (timing->flags.DSC) { 3509 - link_bw_kbps = dc_fixpt_from_int(timing->pix_clk_100hz); 3510 - link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160); 3511 - link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, timing->dsc_cfg.bits_per_pixel); 3512 - kbps = dc_fixpt_ceil(link_bw_kbps); 3513 - return kbps; 3510 + return dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, timing->dsc_cfg.bits_per_pixel); 3514 3511 } 3515 3512 3516 3513 switch (timing->display_color_depth) {
+6 -3
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; 54 55 bool enable_dsc_when_not_needed; 55 56 }; 56 57 ··· 63 62 bool dc_dsc_compute_bandwidth_range( 64 63 const struct display_stream_compressor *dsc, 65 64 uint32_t dsc_min_slice_height_override, 66 - uint32_t min_bpp, 67 - uint32_t max_bpp, 65 + uint32_t min_bpp_x16, 66 + uint32_t max_bpp_x16, 68 67 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 69 68 const struct dc_crtc_timing *timing, 70 69 struct dc_dsc_bw_range *range); ··· 78 77 const struct dc_crtc_timing *timing, 79 78 struct dc_dsc_config *dsc_cfg); 80 79 80 + uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16); 81 + 81 82 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, 82 - uint32_t max_target_bpp_limit_override, 83 + uint32_t max_target_bpp_limit_override_x16, 83 84 struct dc_dsc_policy *policy); 84 85 85 86 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
+34 -71
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
··· 37 37 /* default DSC policy enables DSC only when needed */ 38 38 static bool dsc_policy_enable_dsc_when_not_needed; 39 39 40 - static uint32_t dc_dsc_bandwidth_in_kbps_from_timing( 41 - const struct dc_crtc_timing *timing) 42 - { 43 - uint32_t bits_per_channel = 0; 44 - uint32_t kbps; 45 - 46 - if (timing->flags.DSC) { 47 - kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel); 48 - kbps = kbps / 160 + ((kbps % 160) ? 1 : 0); 49 - return kbps; 50 - } 51 - 52 - switch (timing->display_color_depth) { 53 - case COLOR_DEPTH_666: 54 - bits_per_channel = 6; 55 - break; 56 - case COLOR_DEPTH_888: 57 - bits_per_channel = 8; 58 - break; 59 - case COLOR_DEPTH_101010: 60 - bits_per_channel = 10; 61 - break; 62 - case COLOR_DEPTH_121212: 63 - bits_per_channel = 12; 64 - break; 65 - case COLOR_DEPTH_141414: 66 - bits_per_channel = 14; 67 - break; 68 - case COLOR_DEPTH_161616: 69 - bits_per_channel = 16; 70 - break; 71 - default: 72 - break; 73 - } 74 - 75 - ASSERT(bits_per_channel != 0); 76 - 77 - kbps = timing->pix_clk_100hz / 10; 78 - kbps *= bits_per_channel; 79 - 80 - if (timing->flags.Y_ONLY != 1) { 81 - /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ 82 - kbps *= 3; 83 - if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) 84 - kbps /= 2; 85 - else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) 86 - kbps = kbps * 2 / 3; 87 - } 88 - 89 - return kbps; 90 - 91 - } 92 - 93 40 static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) 94 41 { 95 42 ··· 262 315 * and uncompressed bandwidth. 263 316 */ 264 317 static void get_dsc_bandwidth_range( 265 - const uint32_t min_bpp, 266 - const uint32_t max_bpp, 318 + const uint32_t min_bpp_x16, 319 + const uint32_t max_bpp_x16, 267 320 const struct dsc_enc_caps *dsc_caps, 268 321 const struct dc_crtc_timing *timing, 269 322 struct dc_dsc_bw_range *range) 270 323 { 271 324 /* native stream bandwidth */ 272 - range->stream_kbps = dc_dsc_bandwidth_in_kbps_from_timing(timing); 325 + range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); 273 326 274 327 /* max dsc target bpp */ 275 - range->max_kbps = dsc_div_by_10_round_up(max_bpp * timing->pix_clk_100hz); 276 - range->max_target_bpp_x16 = max_bpp * 16; 328 + range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, max_bpp_x16); 329 + range->max_target_bpp_x16 = max_bpp_x16; 277 330 if (range->max_kbps > range->stream_kbps) { 278 331 /* max dsc target bpp is capped to native bandwidth */ 279 332 range->max_kbps = range->stream_kbps; ··· 281 334 } 282 335 283 336 /* min dsc target bpp */ 284 - range->min_kbps = dsc_div_by_10_round_up(min_bpp * timing->pix_clk_100hz); 285 - range->min_target_bpp_x16 = min_bpp * 16; 337 + range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, min_bpp_x16); 338 + range->min_target_bpp_x16 = min_bpp_x16; 286 339 if (range->min_kbps > range->max_kbps) { 287 340 /* min dsc target bpp is capped to max dsc bandwidth*/ 288 341 range->min_kbps = range->max_kbps; ··· 310 363 311 364 memset(&range, 0, sizeof(range)); 312 365 313 - get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp, 366 + get_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, 314 367 dsc_common_caps, timing, &range); 315 368 if (!policy->enable_dsc_when_not_needed && target_bandwidth_kbps >= range.stream_kbps) { 316 369 /* enough bandwidth without dsc */ 317 370 *target_bpp_x16 = 0; 318 371 should_use_dsc = false; 372 + } else if (policy->preferred_bpp_x16 > 0 && 373 + policy->preferred_bpp_x16 <= range.max_target_bpp_x16 && 374 + policy->preferred_bpp_x16 >= range.min_target_bpp_x16) { 375 + *target_bpp_x16 = policy->preferred_bpp_x16; 376 + should_use_dsc = true; 319 377 } else if (target_bandwidth_kbps >= range.max_kbps) { 320 378 /* use max target bpp allowed */ 321 379 *target_bpp_x16 = range.max_target_bpp_x16; ··· 497 545 int target_bandwidth_kbps, 498 546 const struct dc_crtc_timing *timing, 499 547 int min_slice_height_override, 500 - int max_dsc_target_bpp_limit_override, 548 + int max_dsc_target_bpp_limit_override_x16, 501 549 struct dc_dsc_config *dsc_cfg) 502 550 { 503 551 struct dsc_enc_caps dsc_common_caps; ··· 516 564 517 565 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); 518 566 519 - dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override, &policy); 567 + dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override_x16, &policy); 520 568 pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; 521 569 pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; 522 570 ··· 817 865 bool dc_dsc_compute_bandwidth_range( 818 866 const struct display_stream_compressor *dsc, 819 867 uint32_t dsc_min_slice_height_override, 820 - uint32_t min_bpp, 821 - uint32_t max_bpp, 868 + uint32_t min_bpp_x16, 869 + uint32_t max_bpp_x16, 822 870 const struct dsc_dec_dpcd_caps *dsc_sink_caps, 823 871 const struct dc_crtc_timing *timing, 824 872 struct dc_dsc_bw_range *range) ··· 835 883 836 884 if (is_dsc_possible) 837 885 is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, 838 - dsc_min_slice_height_override, max_bpp, &config); 886 + dsc_min_slice_height_override, max_bpp_x16, &config); 839 887 840 888 if (is_dsc_possible) 841 - get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, timing, range); 889 + get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, &dsc_common_caps, timing, range); 842 890 843 891 return is_dsc_possible; 844 892 } ··· 860 908 &dsc_enc_caps, 861 909 target_bandwidth_kbps, 862 910 timing, dsc_min_slice_height_override, 863 - max_target_bpp_limit_override, dsc_cfg); 911 + max_target_bpp_limit_override * 16, dsc_cfg); 864 912 return is_dsc_possible; 865 913 } 866 914 867 - void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override, struct dc_dsc_policy *policy) 915 + uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16) 916 + { 917 + struct fixed31_32 link_bw_kbps; 918 + link_bw_kbps = dc_fixpt_from_int(pix_clk_100hz); 919 + link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160); 920 + link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, bpp_x16); 921 + return dc_fixpt_ceil(link_bw_kbps); 922 + } 923 + 924 + void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy) 868 925 { 869 926 uint32_t bpc = 0; 870 927 ··· 928 967 return; 929 968 } 930 969 970 + policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; 971 + 931 972 /* internal upper limit, default 16 bpp */ 932 973 if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) 933 974 policy->max_target_bpp = dsc_policy_max_target_bpp_limit; 934 975 935 976 /* apply override */ 936 - if (max_target_bpp_limit_override && policy->max_target_bpp > max_target_bpp_limit_override) 937 - policy->max_target_bpp = max_target_bpp_limit_override; 977 + if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > max_target_bpp_limit_override_x16 / 16) 978 + policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16; 938 979 939 980 /* enable DSC when not needed, default false */ 940 981 if (dsc_policy_enable_dsc_when_not_needed)