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