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(arg: kbps);
68 bpp = dc_fixpt_div_int(arg1: bpp, arg2: 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(arg: timing->h_addressable);
74 overhead_factor = dc_fixpt_mul(arg1: overhead_factor, arg2: bpp);
75 overhead_factor = dc_fixpt_div_int(arg1: overhead_factor, arg2: 128);
76 overhead_factor = dc_fixpt_div(
77 arg1: dc_fixpt_from_int(arg: dc_fixpt_ceil(arg: overhead_factor)),
78 arg2: overhead_factor);
79
80 total_kbps = dc_fixpt_ceil(
81 arg: dc_fixpt_mul_int(arg1: overhead_factor, arg2: 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 bpp_x16: timing->dsc_cfg.bits_per_pixel,
97 num_slices_h: timing->dsc_cfg.num_slices_h,
98 is_dp: 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_buff_block_size: dpcd_dsc_basic_data[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT] & 0x03,
341 buff_block_size: &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_line_buff_bit_depth: dpcd_dsc_basic_data[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT],
350 line_buff_bit_depth: &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: dpcd_throughput & DP_DSC_THROUGHPUT_MODE_0_MASK,
372 throughput: &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, 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(bpp_increment_dpcd: dpcd_dsc_basic_data[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT],
385 bpp_increment_div: &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: &dsc_enc_caps, pixel_clock_100Hz: timing->pix_clk_100hz);
469
470 is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, dsc_enc_caps: &dsc_enc_caps,
471 pixel_encoding: timing->pixel_encoding, dsc_common_caps: &dsc_common_caps);
472
473 if (is_dsc_possible)
474 is_dsc_possible = setup_dsc_config(dsc_sink_caps, dsc_enc_caps: &dsc_enc_caps, target_bandwidth_kbps: 0, timing,
475 options: &options, link_encoding, dsc_cfg: &config);
476
477 if (is_dsc_possible)
478 is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
479 num_slices_h: config.num_slices_h, dsc_caps: &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(arg: bandwidth_in_kbps);
599 effective_bandwidth_in_kbps = dc_fixpt_sub_int(arg1: effective_bandwidth_in_kbps,
600 arg2: overhead_in_kbps);
601 bpp_x16 = dc_fixpt_mul_int(arg1: effective_bandwidth_in_kbps, arg2: 10);
602 bpp_x16 = dc_fixpt_div_int(arg1: bpp_x16, arg2: timing->pix_clk_100hz);
603 bpp_x16 = dc_fixpt_from_int(arg: dc_fixpt_floor(arg: dc_fixpt_mul_int(arg1: bpp_x16, arg2: bpp_increment_div)));
604 bpp_x16 = dc_fixpt_div_int(arg1: bpp_x16, arg2: bpp_increment_div);
605 bpp_x16 = dc_fixpt_mul_int(arg1: bpp_x16, arg2: 16);
606 return dc_fixpt_floor(arg: 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 bpp_x16: range->max_target_bpp_x16, num_slices_h, is_dp: dsc_caps->is_dp);
655
656 /* min dsc target bpp */
657 range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
658 bpp_x16: range->min_target_bpp_x16, num_slices_h, is_dp: 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(min_bpp_x16: policy->min_target_bpp * 16, max_bpp_x16: policy->max_target_bpp * 16,
684 num_slices_h, dsc_caps: dsc_common_caps, timing, link_encoding, range: &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 bandwidth_in_kbps: target_bandwidth_kbps, timing, num_slices_h,
696 bpp_increment_div: dsc_common_caps->bpp_increment_div,
697 is_dp: 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: &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: &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: &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: &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, max_target_bpp_limit_override_x16: options->max_target_bpp_limit_override_x16, policy: &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, pixel_encoding: timing->pixel_encoding, dsc_common_caps: &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(value: 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(slice_caps: 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(slice_caps: dsc_common_caps.slice_caps, num_slices: 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(slice_caps: dsc_common_caps.slice_caps, num_slices: 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(value: 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(slice_caps: dsc_common_caps.slice_caps, num_slices: 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(slice_caps: dsc_common_caps.slice_caps, num_slices: 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 dsc_cfg->num_slices_v = pic_height/slice_height;
1059
1060 if (target_bandwidth_kbps > 0) {
1061 is_dsc_possible = decide_dsc_target_bpp_x16(
1062 policy: &policy,
1063 dsc_common_caps: &dsc_common_caps,
1064 target_bandwidth_kbps,
1065 timing,
1066 num_slices_h,
1067 link_encoding,
1068 target_bpp_x16: &target_bpp);
1069 dsc_cfg->bits_per_pixel = target_bpp;
1070 }
1071 if (!is_dsc_possible)
1072 goto done;
1073
1074 // Final decission: can we do DSC or not?
1075 if (is_dsc_possible) {
1076 // Fill out the rest of DSC settings
1077 dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported;
1078 dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth;
1079 dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4;
1080 dsc_cfg->is_dp = dsc_sink_caps->is_dp;
1081 }
1082
1083done:
1084 if (!is_dsc_possible)
1085 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
1086
1087 return is_dsc_possible;
1088}
1089
1090bool dc_dsc_compute_config(
1091 const struct display_stream_compressor *dsc,
1092 const struct dsc_dec_dpcd_caps *dsc_sink_caps,
1093 const struct dc_dsc_config_options *options,
1094 uint32_t target_bandwidth_kbps,
1095 const struct dc_crtc_timing *timing,
1096 const enum dc_link_encoding_format link_encoding,
1097 struct dc_dsc_config *dsc_cfg)
1098{
1099 bool is_dsc_possible = false;
1100 struct dsc_enc_caps dsc_enc_caps;
1101
1102 get_dsc_enc_caps(dsc, dsc_enc_caps: &dsc_enc_caps, pixel_clock_100Hz: timing->pix_clk_100hz);
1103 is_dsc_possible = setup_dsc_config(dsc_sink_caps,
1104 dsc_enc_caps: &dsc_enc_caps,
1105 target_bandwidth_kbps,
1106 timing, options, link_encoding, dsc_cfg);
1107 return is_dsc_possible;
1108}
1109
1110uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
1111 uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp)
1112{
1113 uint32_t overhead_in_kbps;
1114 struct fixed31_32 bpp;
1115 struct fixed31_32 actual_bandwidth_in_kbps;
1116
1117 overhead_in_kbps = dc_dsc_stream_bandwidth_overhead_in_kbps(
1118 timing, num_slices_h, is_dp);
1119 bpp = dc_fixpt_from_fraction(numerator: bpp_x16, denominator: 16);
1120 actual_bandwidth_in_kbps = dc_fixpt_from_fraction(numerator: timing->pix_clk_100hz, denominator: 10);
1121 actual_bandwidth_in_kbps = dc_fixpt_mul(arg1: actual_bandwidth_in_kbps, arg2: bpp);
1122 actual_bandwidth_in_kbps = dc_fixpt_add_int(arg1: actual_bandwidth_in_kbps, arg2: overhead_in_kbps);
1123 return dc_fixpt_ceil(arg: actual_bandwidth_in_kbps);
1124}
1125
1126uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps(
1127 const struct dc_crtc_timing *timing,
1128 const int num_slices_h,
1129 const bool is_dp)
1130{
1131 struct fixed31_32 max_dsc_overhead;
1132 struct fixed31_32 refresh_rate;
1133
1134 if (dsc_policy_disable_dsc_stream_overhead || !is_dp)
1135 return 0;
1136
1137 /* use target bpp that can take entire target bandwidth */
1138 refresh_rate = dc_fixpt_from_int(arg: timing->pix_clk_100hz);
1139 refresh_rate = dc_fixpt_div_int(arg1: refresh_rate, arg2: timing->h_total);
1140 refresh_rate = dc_fixpt_div_int(arg1: refresh_rate, arg2: timing->v_total);
1141 refresh_rate = dc_fixpt_mul_int(arg1: refresh_rate, arg2: 100);
1142
1143 max_dsc_overhead = dc_fixpt_from_int(arg: num_slices_h);
1144 max_dsc_overhead = dc_fixpt_mul_int(arg1: max_dsc_overhead, arg2: timing->v_total);
1145 max_dsc_overhead = dc_fixpt_mul_int(arg1: max_dsc_overhead, arg2: 256);
1146 max_dsc_overhead = dc_fixpt_div_int(arg1: max_dsc_overhead, arg2: 1000);
1147 max_dsc_overhead = dc_fixpt_mul(arg1: max_dsc_overhead, arg2: refresh_rate);
1148
1149 return dc_fixpt_ceil(arg: max_dsc_overhead);
1150}
1151
1152void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
1153 uint32_t max_target_bpp_limit_override_x16,
1154 struct dc_dsc_policy *policy)
1155{
1156 uint32_t bpc = 0;
1157
1158 policy->min_target_bpp = 0;
1159 policy->max_target_bpp = 0;
1160
1161 /* DSC Policy: Use minimum number of slices that fits the pixel clock */
1162 policy->use_min_slices_h = true;
1163
1164 /* DSC Policy: Use max available slices
1165 * (in our case 4 for or 8, depending on the mode)
1166 */
1167 policy->max_slices_h = 0;
1168
1169 /* DSC Policy: Use slice height recommended
1170 * by VESA DSC Spreadsheet user guide
1171 */
1172 policy->min_slice_height = 108;
1173
1174 /* DSC Policy: follow DP specs with an internal upper limit to 16 bpp
1175 * for better interoperability
1176 */
1177 switch (timing->display_color_depth) {
1178 case COLOR_DEPTH_888:
1179 bpc = 8;
1180 break;
1181 case COLOR_DEPTH_101010:
1182 bpc = 10;
1183 break;
1184 case COLOR_DEPTH_121212:
1185 bpc = 12;
1186 break;
1187 default:
1188 return;
1189 }
1190 switch (timing->pixel_encoding) {
1191 case PIXEL_ENCODING_RGB:
1192 case PIXEL_ENCODING_YCBCR444:
1193 case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */
1194 /* DP specs limits to 8 */
1195 policy->min_target_bpp = 8;
1196 /* DP specs limits to 3 x bpc */
1197 policy->max_target_bpp = 3 * bpc;
1198 break;
1199 case PIXEL_ENCODING_YCBCR420:
1200 /* DP specs limits to 6 */
1201 policy->min_target_bpp = 6;
1202 /* DP specs limits to 1.5 x bpc assume bpc is an even number */
1203 policy->max_target_bpp = bpc * 3 / 2;
1204 break;
1205 default:
1206 return;
1207 }
1208
1209 /* internal upper limit, default 16 bpp */
1210 if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit)
1211 policy->max_target_bpp = dsc_policy_max_target_bpp_limit;
1212
1213 /* apply override */
1214 if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > max_target_bpp_limit_override_x16 / 16)
1215 policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16;
1216
1217 /* enable DSC when not needed, default false */
1218 if (dsc_policy_enable_dsc_when_not_needed)
1219 policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed;
1220 else
1221 policy->enable_dsc_when_not_needed = false;
1222}
1223
1224void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit)
1225{
1226 dsc_policy_max_target_bpp_limit = limit;
1227}
1228
1229void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable)
1230{
1231 dsc_policy_enable_dsc_when_not_needed = enable;
1232}
1233
1234void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
1235{
1236 dsc_policy_disable_dsc_stream_overhead = disable;
1237}
1238
1239void dc_set_disable_128b_132b_stream_overhead(bool disable)
1240{
1241 disable_128b_132b_stream_overhead = disable;
1242}
1243
1244void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options)
1245{
1246 options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override;
1247 options->dsc_force_odm_hslice_override = dc->debug.force_odm_combine;
1248 options->max_target_bpp_limit_override_x16 = 0;
1249 options->slice_height_granularity = 1;
1250}
1251

source code of linux/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c