This source file includes following definitions.
- dsc_buff_block_size_from_dpcd
- dsc_line_buff_depth_from_dpcd
- dsc_throughput_from_dpcd
- dsc_bpp_increment_div_from_dpcd
- get_dsc_enc_caps
- intersect_dsc_caps
- dsc_div_by_10_round_up
- calc_dsc_bpp_x16
- get_dsc_bandwidth_range
- decide_dsc_target_bpp_x16
- get_available_dsc_slices
- get_max_dsc_slices
- inc_num_slices
- dec_num_slices
- fit_num_slices_up
- setup_dsc_config
- dc_dsc_parse_dsc_dpcd
- dc_dsc_compute_bandwidth_range
- dc_dsc_compute_config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
26 #include "dc.h"
27 #include "core_types.h"
28 #include "dsc.h"
29 #include <drm/drm_dp_helper.h>
30
31 struct dc_dsc_policy {
32 bool use_min_slices_h;
33 int max_slices_h;
34 int min_sice_height;
35 int max_target_bpp;
36 int min_target_bpp;
37 };
38
39 const struct dc_dsc_policy dsc_policy = {
40 .use_min_slices_h = true,
41 .max_slices_h = 0,
42 .min_sice_height = 108,
43 .max_target_bpp = 16,
44 .min_target_bpp = 8,
45 };
46
47
48
49
50 static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size)
51 {
52
53 switch (dpcd_buff_block_size) {
54 case DP_DSC_RC_BUF_BLK_SIZE_1:
55 *buff_block_size = 1024;
56 break;
57 case DP_DSC_RC_BUF_BLK_SIZE_4:
58 *buff_block_size = 4 * 1024;
59 break;
60 case DP_DSC_RC_BUF_BLK_SIZE_16:
61 *buff_block_size = 16 * 1024;
62 break;
63 case DP_DSC_RC_BUF_BLK_SIZE_64:
64 *buff_block_size = 64 * 1024;
65 break;
66 default: {
67 dm_error("%s: DPCD DSC buffer size not recognized.\n", __func__);
68 return false;
69 }
70 }
71
72 return true;
73 }
74
75
76 static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *line_buff_bit_depth)
77 {
78 if (0 <= dpcd_line_buff_bit_depth && dpcd_line_buff_bit_depth <= 7)
79 *line_buff_bit_depth = dpcd_line_buff_bit_depth + 9;
80 else if (dpcd_line_buff_bit_depth == 8)
81 *line_buff_bit_depth = 8;
82 else {
83 dm_error("%s: DPCD DSC buffer depth not recognized.\n", __func__);
84 return false;
85 }
86
87 return true;
88 }
89
90
91 static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput)
92 {
93 switch (dpcd_throughput) {
94 case DP_DSC_THROUGHPUT_MODE_0_UPSUPPORTED:
95 *throughput = 0;
96 break;
97 case DP_DSC_THROUGHPUT_MODE_0_170:
98 *throughput = 170;
99 break;
100 case DP_DSC_THROUGHPUT_MODE_0_340:
101 *throughput = 340;
102 break;
103 case DP_DSC_THROUGHPUT_MODE_0_400:
104 *throughput = 400;
105 break;
106 case DP_DSC_THROUGHPUT_MODE_0_450:
107 *throughput = 450;
108 break;
109 case DP_DSC_THROUGHPUT_MODE_0_500:
110 *throughput = 500;
111 break;
112 case DP_DSC_THROUGHPUT_MODE_0_550:
113 *throughput = 550;
114 break;
115 case DP_DSC_THROUGHPUT_MODE_0_600:
116 *throughput = 600;
117 break;
118 case DP_DSC_THROUGHPUT_MODE_0_650:
119 *throughput = 650;
120 break;
121 case DP_DSC_THROUGHPUT_MODE_0_700:
122 *throughput = 700;
123 break;
124 case DP_DSC_THROUGHPUT_MODE_0_750:
125 *throughput = 750;
126 break;
127 case DP_DSC_THROUGHPUT_MODE_0_800:
128 *throughput = 800;
129 break;
130 case DP_DSC_THROUGHPUT_MODE_0_850:
131 *throughput = 850;
132 break;
133 case DP_DSC_THROUGHPUT_MODE_0_900:
134 *throughput = 900;
135 break;
136 case DP_DSC_THROUGHPUT_MODE_0_950:
137 *throughput = 950;
138 break;
139 case DP_DSC_THROUGHPUT_MODE_0_1000:
140 *throughput = 1000;
141 break;
142 default: {
143 dm_error("%s: DPCD DSC throughput mode not recognized.\n", __func__);
144 return false;
145 }
146 }
147
148 return true;
149 }
150
151
152 static bool dsc_bpp_increment_div_from_dpcd(int bpp_increment_dpcd, uint32_t *bpp_increment_div)
153 {
154
155 switch (bpp_increment_dpcd) {
156 case 0:
157 *bpp_increment_div = 16;
158 break;
159 case 1:
160 *bpp_increment_div = 8;
161 break;
162 case 2:
163 *bpp_increment_div = 4;
164 break;
165 case 3:
166 *bpp_increment_div = 2;
167 break;
168 case 4:
169 *bpp_increment_div = 1;
170 break;
171 default: {
172 dm_error("%s: DPCD DSC bits-per-pixel increment not recognized.\n", __func__);
173 return false;
174 }
175 }
176
177 return true;
178 }
179
180 static void get_dsc_enc_caps(
181 const struct dc *dc,
182 struct dsc_enc_caps *dsc_enc_caps,
183 int pixel_clock_100Hz)
184 {
185
186 struct display_stream_compressor *dsc = dc->res_pool->dscs[0];
187
188 memset(dsc_enc_caps, 0, sizeof(struct dsc_enc_caps));
189 if (dsc)
190 dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz);
191 }
192
193
194
195
196 static bool intersect_dsc_caps(
197 const struct dsc_dec_dpcd_caps *dsc_sink_caps,
198 const struct dsc_enc_caps *dsc_enc_caps,
199 enum dc_pixel_encoding pixel_encoding,
200 struct dsc_enc_caps *dsc_common_caps)
201 {
202 int32_t max_slices;
203 int32_t total_sink_throughput;
204
205 memset(dsc_common_caps, 0, sizeof(struct dsc_enc_caps));
206
207 dsc_common_caps->dsc_version = min(dsc_sink_caps->dsc_version, dsc_enc_caps->dsc_version);
208 if (!dsc_common_caps->dsc_version)
209 return false;
210
211 dsc_common_caps->slice_caps.bits.NUM_SLICES_1 = dsc_sink_caps->slice_caps1.bits.NUM_SLICES_1 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_1;
212 dsc_common_caps->slice_caps.bits.NUM_SLICES_2 = dsc_sink_caps->slice_caps1.bits.NUM_SLICES_2 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_2;
213 dsc_common_caps->slice_caps.bits.NUM_SLICES_4 = dsc_sink_caps->slice_caps1.bits.NUM_SLICES_4 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_4;
214 dsc_common_caps->slice_caps.bits.NUM_SLICES_8 = dsc_sink_caps->slice_caps1.bits.NUM_SLICES_8 && dsc_enc_caps->slice_caps.bits.NUM_SLICES_8;
215 if (!dsc_common_caps->slice_caps.raw)
216 return false;
217
218 dsc_common_caps->lb_bit_depth = min(dsc_sink_caps->lb_bit_depth, dsc_enc_caps->lb_bit_depth);
219 if (!dsc_common_caps->lb_bit_depth)
220 return false;
221
222 dsc_common_caps->is_block_pred_supported = dsc_sink_caps->is_block_pred_supported && dsc_enc_caps->is_block_pred_supported;
223
224 dsc_common_caps->color_formats.raw = dsc_sink_caps->color_formats.raw & dsc_enc_caps->color_formats.raw;
225 if (!dsc_common_caps->color_formats.raw)
226 return false;
227
228 dsc_common_caps->color_depth.raw = dsc_sink_caps->color_depth.raw & dsc_enc_caps->color_depth.raw;
229 if (!dsc_common_caps->color_depth.raw)
230 return false;
231
232 max_slices = 0;
233 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_1)
234 max_slices = 1;
235
236 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_2)
237 max_slices = 2;
238
239 if (dsc_common_caps->slice_caps.bits.NUM_SLICES_4)
240 max_slices = 4;
241
242 total_sink_throughput = max_slices * dsc_sink_caps->throughput_mode_0_mps;
243 if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420)
244 total_sink_throughput = max_slices * dsc_sink_caps->throughput_mode_1_mps;
245
246 dsc_common_caps->max_total_throughput_mps = min(total_sink_throughput, dsc_enc_caps->max_total_throughput_mps);
247
248 dsc_common_caps->max_slice_width = min(dsc_sink_caps->max_slice_width, dsc_enc_caps->max_slice_width);
249 if (!dsc_common_caps->max_slice_width)
250 return false;
251
252 dsc_common_caps->bpp_increment_div = min(dsc_sink_caps->bpp_increment_div, dsc_enc_caps->bpp_increment_div);
253
254
255 if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420)
256 dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8);
257
258 return true;
259 }
260
261 static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
262 {
263 return (value + 9) / 10;
264 }
265
266 static inline uint32_t calc_dsc_bpp_x16(uint32_t stream_bandwidth_kbps, uint32_t pix_clk_100hz, uint32_t bpp_increment_div)
267 {
268 uint32_t dsc_target_bpp_x16;
269 float f_dsc_target_bpp;
270 float f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f;
271 uint32_t precision = bpp_increment_div;
272
273 f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz;
274
275
276 dsc_target_bpp_x16 = (uint32_t)(f_dsc_target_bpp * precision);
277 dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision;
278
279 return dsc_target_bpp_x16;
280 }
281
282
283
284
285 static void get_dsc_bandwidth_range(
286 const uint32_t min_bpp,
287 const uint32_t max_bpp,
288 const struct dsc_enc_caps *dsc_caps,
289 const struct dc_crtc_timing *timing,
290 struct dc_dsc_bw_range *range)
291 {
292
293 range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing);
294
295
296 range->max_kbps = dsc_div_by_10_round_up(max_bpp * timing->pix_clk_100hz);
297 range->max_target_bpp_x16 = max_bpp * 16;
298 if (range->max_kbps > range->stream_kbps) {
299
300 range->max_kbps = range->stream_kbps;
301 range->max_target_bpp_x16 = calc_dsc_bpp_x16(range->stream_kbps, timing->pix_clk_100hz, dsc_caps->bpp_increment_div);
302 }
303
304
305 range->min_kbps = dsc_div_by_10_round_up(min_bpp * timing->pix_clk_100hz);
306 range->min_target_bpp_x16 = min_bpp * 16;
307 if (range->min_kbps > range->max_kbps) {
308
309 range->min_kbps = range->max_kbps;
310 range->min_target_bpp_x16 = range->max_target_bpp_x16;
311 }
312 }
313
314
315
316
317
318
319
320
321
322 static bool decide_dsc_target_bpp_x16(
323 const struct dc_dsc_policy *policy,
324 const struct dsc_enc_caps *dsc_common_caps,
325 const int target_bandwidth_kbps,
326 const struct dc_crtc_timing *timing,
327 int *target_bpp_x16)
328 {
329 bool should_use_dsc = false;
330 struct dc_dsc_bw_range range;
331
332 memset(&range, 0, sizeof(range));
333
334 get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp,
335 dsc_common_caps, timing, &range);
336 if (target_bandwidth_kbps >= range.stream_kbps) {
337
338 *target_bpp_x16 = 0;
339 should_use_dsc = false;
340 } else if (target_bandwidth_kbps >= range.max_kbps) {
341
342 *target_bpp_x16 = range.max_target_bpp_x16;
343 should_use_dsc = true;
344 } else if (target_bandwidth_kbps >= range.min_kbps) {
345
346 *target_bpp_x16 = calc_dsc_bpp_x16(target_bandwidth_kbps, timing->pix_clk_100hz, dsc_common_caps->bpp_increment_div);
347 should_use_dsc = true;
348 } else {
349
350 *target_bpp_x16 = 0;
351 should_use_dsc = false;
352 }
353
354 return should_use_dsc;
355 }
356
357 #define MIN_AVAILABLE_SLICES_SIZE 4
358
359 static int get_available_dsc_slices(union dsc_enc_slice_caps slice_caps, int *available_slices)
360 {
361 int idx = 0;
362
363 memset(available_slices, -1, MIN_AVAILABLE_SLICES_SIZE);
364
365 if (slice_caps.bits.NUM_SLICES_1)
366 available_slices[idx++] = 1;
367
368 if (slice_caps.bits.NUM_SLICES_2)
369 available_slices[idx++] = 2;
370
371 if (slice_caps.bits.NUM_SLICES_4)
372 available_slices[idx++] = 4;
373
374 if (slice_caps.bits.NUM_SLICES_8)
375 available_slices[idx++] = 8;
376
377 return idx;
378 }
379
380
381 static int get_max_dsc_slices(union dsc_enc_slice_caps slice_caps)
382 {
383 int max_slices = 0;
384 int available_slices[MIN_AVAILABLE_SLICES_SIZE];
385 int end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]);
386
387 if (end_idx > 0)
388 max_slices = available_slices[end_idx - 1];
389
390 return max_slices;
391 }
392
393
394
395 static int inc_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices)
396 {
397
398 int available_slices[MIN_AVAILABLE_SLICES_SIZE];
399 int end_idx;
400 int i;
401 int new_num_slices = num_slices;
402
403 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]);
404 if (end_idx == 0) {
405
406 new_num_slices++;
407 return new_num_slices;
408 }
409
410
411 for (i = 0; i < end_idx; i++) {
412 if (new_num_slices < available_slices[i]) {
413 new_num_slices = available_slices[i];
414 break;
415 }
416 }
417
418 if (new_num_slices == num_slices)
419 new_num_slices++;
420
421 return new_num_slices;
422 }
423
424
425
426 static int dec_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices)
427 {
428
429 int available_slices[MIN_AVAILABLE_SLICES_SIZE];
430 int end_idx;
431 int i;
432 int new_num_slices = num_slices;
433
434 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]);
435 if (end_idx == 0 && new_num_slices > 0) {
436
437 new_num_slices++;
438 return new_num_slices;
439 }
440
441
442 for (i = end_idx - 1; i >= 0; i--) {
443 if (new_num_slices > available_slices[i]) {
444 new_num_slices = available_slices[i];
445 break;
446 }
447 }
448
449 if (new_num_slices == num_slices) {
450
451 new_num_slices--;
452 if (new_num_slices < 0)
453 new_num_slices = 0;
454 }
455
456 return new_num_slices;
457 }
458
459
460
461 static int fit_num_slices_up(union dsc_enc_slice_caps slice_caps, int num_slices)
462 {
463
464 int available_slices[MIN_AVAILABLE_SLICES_SIZE];
465 int end_idx;
466 int i;
467 int new_num_slices = num_slices;
468
469 end_idx = get_available_dsc_slices(slice_caps, &available_slices[0]);
470 if (end_idx == 0) {
471
472 new_num_slices++;
473 return new_num_slices;
474 }
475
476
477 for (i = 0; i < end_idx; i++) {
478 if (new_num_slices <= available_slices[i]) {
479 new_num_slices = available_slices[i];
480 break;
481 }
482 }
483
484 return new_num_slices;
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510 static bool setup_dsc_config(
511 const struct dsc_dec_dpcd_caps *dsc_sink_caps,
512 const struct dsc_enc_caps *dsc_enc_caps,
513 int target_bandwidth_kbps,
514 const struct dc_crtc_timing *timing,
515 struct dc_dsc_config *dsc_cfg)
516 {
517 struct dsc_enc_caps dsc_common_caps;
518 int max_slices_h;
519 int min_slices_h;
520 int num_slices_h;
521 int pic_width;
522 int slice_width;
523 int target_bpp;
524 int sink_per_slice_throughput_mps;
525 int branch_max_throughput_mps = 0;
526 bool is_dsc_possible = false;
527 int pic_height;
528 int slice_height;
529
530 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
531
532 pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right;
533 pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
534
535 if (!dsc_sink_caps->is_dsc_supported)
536 goto done;
537
538 if (dsc_sink_caps->branch_max_line_width && dsc_sink_caps->branch_max_line_width < pic_width)
539 goto done;
540
541
542 is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, dsc_enc_caps, timing->pixel_encoding, &dsc_common_caps);
543 if (!is_dsc_possible)
544 goto done;
545
546 if (target_bandwidth_kbps > 0) {
547 is_dsc_possible = decide_dsc_target_bpp_x16(&dsc_policy, &dsc_common_caps, target_bandwidth_kbps, timing, &target_bpp);
548 dsc_cfg->bits_per_pixel = target_bpp;
549 }
550 if (!is_dsc_possible)
551 goto done;
552
553 sink_per_slice_throughput_mps = 0;
554
555
556
557
558 dsc_cfg->ycbcr422_simple = false;
559 switch (timing->pixel_encoding) {
560 case PIXEL_ENCODING_RGB:
561 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.RGB;
562 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps;
563 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps;
564 break;
565 case PIXEL_ENCODING_YCBCR444:
566 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_444;
567 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps;
568 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps;
569 break;
570 case PIXEL_ENCODING_YCBCR422:
571 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422;
572 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps;
573 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps;
574 if (!is_dsc_possible) {
575 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_SIMPLE_422;
576 dsc_cfg->ycbcr422_simple = is_dsc_possible;
577 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps;
578 }
579 break;
580 case PIXEL_ENCODING_YCBCR420:
581 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_420;
582 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps;
583 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps;
584 break;
585 default:
586 is_dsc_possible = false;
587 }
588
589
590 if (branch_max_throughput_mps && dsc_div_by_10_round_up(timing->pix_clk_100hz) > branch_max_throughput_mps * 1000)
591 is_dsc_possible = false;
592
593 if (!is_dsc_possible)
594 goto done;
595
596
597 switch (timing->display_color_depth) {
598 case COLOR_DEPTH_888:
599 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_8_BPC;
600 break;
601 case COLOR_DEPTH_101010:
602 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_10_BPC;
603 break;
604 case COLOR_DEPTH_121212:
605 is_dsc_possible = (bool)dsc_common_caps.color_depth.bits.COLOR_DEPTH_12_BPC;
606 break;
607 default:
608 is_dsc_possible = false;
609 }
610
611 if (!is_dsc_possible)
612 goto done;
613
614
615 max_slices_h = get_max_dsc_slices(dsc_common_caps.slice_caps);
616
617 while (max_slices_h > 0) {
618 if (pic_width % max_slices_h == 0)
619 break;
620
621 max_slices_h = dec_num_slices(dsc_common_caps.slice_caps, max_slices_h);
622 }
623
624 is_dsc_possible = (dsc_common_caps.max_slice_width > 0);
625 if (!is_dsc_possible)
626 goto done;
627
628 min_slices_h = pic_width / dsc_common_caps.max_slice_width;
629 if (pic_width % dsc_common_caps.max_slice_width)
630 min_slices_h++;
631
632 min_slices_h = fit_num_slices_up(dsc_common_caps.slice_caps, min_slices_h);
633
634 while (min_slices_h <= max_slices_h) {
635 int pix_clk_per_slice_khz = dsc_div_by_10_round_up(timing->pix_clk_100hz) / min_slices_h;
636 if (pix_clk_per_slice_khz <= sink_per_slice_throughput_mps * 1000)
637 break;
638
639 min_slices_h = inc_num_slices(dsc_common_caps.slice_caps, min_slices_h);
640 }
641
642 if (pic_width % min_slices_h != 0)
643 min_slices_h = 0;
644
645 is_dsc_possible = (min_slices_h <= max_slices_h);
646 if (!is_dsc_possible)
647 goto done;
648
649 if (dsc_policy.use_min_slices_h) {
650 if (min_slices_h > 0)
651 num_slices_h = min_slices_h;
652 else if (max_slices_h > 0) {
653 if (dsc_policy.max_slices_h)
654 num_slices_h = min(dsc_policy.max_slices_h, max_slices_h);
655 else
656 num_slices_h = max_slices_h;
657 } else
658 is_dsc_possible = false;
659 } else {
660 if (max_slices_h > 0) {
661 if (dsc_policy.max_slices_h)
662 num_slices_h = min(dsc_policy.max_slices_h, max_slices_h);
663 else
664 num_slices_h = max_slices_h;
665 } else if (min_slices_h > 0)
666 num_slices_h = min_slices_h;
667 else
668 is_dsc_possible = false;
669 }
670
671 if (!is_dsc_possible)
672 goto done;
673
674 dsc_cfg->num_slices_h = num_slices_h;
675 slice_width = pic_width / num_slices_h;
676
677 is_dsc_possible = slice_width <= dsc_common_caps.max_slice_width;
678 if (!is_dsc_possible)
679 goto done;
680
681
682
683 slice_height = min(dsc_policy.min_sice_height, pic_height);
684
685 while (slice_height < pic_height && (pic_height % slice_height != 0 ||
686 (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0)))
687 slice_height++;
688
689 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
690 is_dsc_possible = (slice_height % 2 == 0);
691
692 if (!is_dsc_possible)
693 goto done;
694
695 dsc_cfg->num_slices_v = pic_height/slice_height;
696
697
698 if (is_dsc_possible) {
699
700 dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported;
701 dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth;
702 dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4;
703 }
704
705 done:
706 if (!is_dsc_possible)
707 memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
708
709 return is_dsc_possible;
710 }
711
712 bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data, const uint8_t *dpcd_dsc_ext_data, struct dsc_dec_dpcd_caps *dsc_sink_caps)
713 {
714 if (!dpcd_dsc_basic_data)
715 return false;
716
717 dsc_sink_caps->is_dsc_supported = (dpcd_dsc_basic_data[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_DECOMPRESSION_IS_SUPPORTED) != 0;
718 if (!dsc_sink_caps->is_dsc_supported)
719 return false;
720
721 dsc_sink_caps->dsc_version = dpcd_dsc_basic_data[DP_DSC_REV - DP_DSC_SUPPORT];
722
723 {
724 int buff_block_size;
725 int buff_size;
726
727 if (!dsc_buff_block_size_from_dpcd(dpcd_dsc_basic_data[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT], &buff_block_size))
728 return false;
729
730 buff_size = dpcd_dsc_basic_data[DP_DSC_RC_BUF_SIZE - DP_DSC_SUPPORT] + 1;
731 dsc_sink_caps->rc_buffer_size = buff_size * buff_block_size;
732 }
733
734 dsc_sink_caps->slice_caps1.raw = dpcd_dsc_basic_data[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT];
735 if (!dsc_line_buff_depth_from_dpcd(dpcd_dsc_basic_data[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT], &dsc_sink_caps->lb_bit_depth))
736 return false;
737
738 dsc_sink_caps->is_block_pred_supported =
739 (dpcd_dsc_basic_data[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_BLK_PREDICTION_IS_SUPPORTED) != 0;
740
741 dsc_sink_caps->edp_max_bits_per_pixel =
742 dpcd_dsc_basic_data[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] |
743 dpcd_dsc_basic_data[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] << 8;
744
745 dsc_sink_caps->color_formats.raw = dpcd_dsc_basic_data[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT];
746 dsc_sink_caps->color_depth.raw = dpcd_dsc_basic_data[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
747
748 {
749 int dpcd_throughput = dpcd_dsc_basic_data[DP_DSC_PEAK_THROUGHPUT - DP_DSC_SUPPORT];
750
751 if (!dsc_throughput_from_dpcd(dpcd_throughput & DP_DSC_THROUGHPUT_MODE_0_MASK, &dsc_sink_caps->throughput_mode_0_mps))
752 return false;
753
754 dpcd_throughput = (dpcd_throughput & DP_DSC_THROUGHPUT_MODE_1_MASK) >> DP_DSC_THROUGHPUT_MODE_1_SHIFT;
755 if (!dsc_throughput_from_dpcd(dpcd_throughput, &dsc_sink_caps->throughput_mode_1_mps))
756 return false;
757 }
758
759 dsc_sink_caps->max_slice_width = dpcd_dsc_basic_data[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] * 320;
760 dsc_sink_caps->slice_caps2.raw = dpcd_dsc_basic_data[DP_DSC_SLICE_CAP_2 - DP_DSC_SUPPORT];
761
762 if (!dsc_bpp_increment_div_from_dpcd(dpcd_dsc_basic_data[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT], &dsc_sink_caps->bpp_increment_div))
763 return false;
764
765
766 if (dpcd_dsc_ext_data == NULL) {
767 dsc_sink_caps->branch_overall_throughput_0_mps = 0;
768 dsc_sink_caps->branch_overall_throughput_1_mps = 0;
769 dsc_sink_caps->branch_max_line_width = 0;
770 return true;
771 }
772
773 dsc_sink_caps->branch_overall_throughput_0_mps = dpcd_dsc_ext_data[DP_DSC_BRANCH_OVERALL_THROUGHPUT_0 - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0];
774 if (dsc_sink_caps->branch_overall_throughput_0_mps == 0)
775 dsc_sink_caps->branch_overall_throughput_0_mps = 0;
776 else if (dsc_sink_caps->branch_overall_throughput_0_mps == 1)
777 dsc_sink_caps->branch_overall_throughput_0_mps = 680;
778 else {
779 dsc_sink_caps->branch_overall_throughput_0_mps *= 50;
780 dsc_sink_caps->branch_overall_throughput_0_mps += 600;
781 }
782
783 dsc_sink_caps->branch_overall_throughput_1_mps = dpcd_dsc_ext_data[DP_DSC_BRANCH_OVERALL_THROUGHPUT_1 - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0];
784 if (dsc_sink_caps->branch_overall_throughput_1_mps == 0)
785 dsc_sink_caps->branch_overall_throughput_1_mps = 0;
786 else if (dsc_sink_caps->branch_overall_throughput_1_mps == 1)
787 dsc_sink_caps->branch_overall_throughput_1_mps = 680;
788 else {
789 dsc_sink_caps->branch_overall_throughput_1_mps *= 50;
790 dsc_sink_caps->branch_overall_throughput_1_mps += 600;
791 }
792
793 dsc_sink_caps->branch_max_line_width = dpcd_dsc_ext_data[DP_DSC_BRANCH_MAX_LINE_WIDTH - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0] * 320;
794 ASSERT(dsc_sink_caps->branch_max_line_width == 0 || dsc_sink_caps->branch_max_line_width >= 5120);
795
796 return true;
797 }
798
799
800
801
802
803
804 bool dc_dsc_compute_bandwidth_range(
805 const struct dc *dc,
806 const uint32_t min_bpp,
807 const uint32_t max_bpp,
808 const struct dsc_dec_dpcd_caps *dsc_sink_caps,
809 const struct dc_crtc_timing *timing,
810 struct dc_dsc_bw_range *range)
811 {
812 bool is_dsc_possible = false;
813 struct dsc_enc_caps dsc_enc_caps;
814 struct dsc_enc_caps dsc_common_caps;
815 struct dc_dsc_config config;
816
817 get_dsc_enc_caps(dc, &dsc_enc_caps, timing->pix_clk_100hz);
818
819 is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, &dsc_enc_caps,
820 timing->pixel_encoding, &dsc_common_caps);
821
822 if (is_dsc_possible)
823 is_dsc_possible = setup_dsc_config(dsc_sink_caps,
824 &dsc_enc_caps,
825 0,
826 timing, &config);
827
828 if (is_dsc_possible)
829 get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, timing, range);
830
831 return is_dsc_possible;
832 }
833
834 bool dc_dsc_compute_config(
835 const struct dc *dc,
836 const struct dsc_dec_dpcd_caps *dsc_sink_caps,
837 uint32_t target_bandwidth_kbps,
838 const struct dc_crtc_timing *timing,
839 struct dc_dsc_config *dsc_cfg)
840 {
841 bool is_dsc_possible = false;
842 struct dsc_enc_caps dsc_enc_caps;
843
844 get_dsc_enc_caps(dc, &dsc_enc_caps, timing->pix_clk_100hz);
845 is_dsc_possible = setup_dsc_config(dsc_sink_caps,
846 &dsc_enc_caps,
847 target_bandwidth_kbps,
848 timing, dsc_cfg);
849 return is_dsc_possible;
850 }
851 #endif