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