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