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