linux/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
<<
>>
Prefs
   1/* Copyright 2015 Advanced Micro Devices, Inc. */
   2
   3
   4#include "dm_services.h"
   5#include "dc.h"
   6#include "inc/core_types.h"
   7#include "include/ddc_service_types.h"
   8#include "include/i2caux_interface.h"
   9#include "link_hwss.h"
  10#include "hw_sequencer.h"
  11#include "dc_link_dp.h"
  12#include "dc_link_ddc.h"
  13#include "dm_helpers.h"
  14#include "dpcd_defs.h"
  15#include "dsc.h"
  16#include "resource.h"
  17
  18static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
  19{
  20        switch (lttpr_repeater_count) {
  21        case 0x80: // 1 lttpr repeater
  22                return 1;
  23        case 0x40: // 2 lttpr repeaters
  24                return 2;
  25        case 0x20: // 3 lttpr repeaters
  26                return 3;
  27        case 0x10: // 4 lttpr repeaters
  28                return 4;
  29        case 0x08: // 5 lttpr repeaters
  30                return 5;
  31        case 0x04: // 6 lttpr repeaters
  32                return 6;
  33        case 0x02: // 7 lttpr repeaters
  34                return 7;
  35        case 0x01: // 8 lttpr repeaters
  36                return 8;
  37        default:
  38                break;
  39        }
  40        return 0; // invalid value
  41}
  42
  43static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
  44{
  45        return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
  46}
  47
  48enum dc_status core_link_read_dpcd(
  49        struct dc_link *link,
  50        uint32_t address,
  51        uint8_t *data,
  52        uint32_t size)
  53{
  54        if (!link->aux_access_disabled &&
  55                        !dm_helpers_dp_read_dpcd(link->ctx,
  56                        link, address, data, size)) {
  57                return DC_ERROR_UNEXPECTED;
  58        }
  59
  60        return DC_OK;
  61}
  62
  63enum dc_status core_link_write_dpcd(
  64        struct dc_link *link,
  65        uint32_t address,
  66        const uint8_t *data,
  67        uint32_t size)
  68{
  69        if (!link->aux_access_disabled &&
  70                        !dm_helpers_dp_write_dpcd(link->ctx,
  71                        link, address, data, size)) {
  72                return DC_ERROR_UNEXPECTED;
  73        }
  74
  75        return DC_OK;
  76}
  77
  78void dp_receiver_power_ctrl(struct dc_link *link, bool on)
  79{
  80        uint8_t state;
  81
  82        state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
  83
  84        if (link->sync_lt_in_progress)
  85                return;
  86
  87        core_link_write_dpcd(link, DP_SET_POWER, &state,
  88                        sizeof(state));
  89}
  90
  91void dp_enable_link_phy(
  92        struct dc_link *link,
  93        enum signal_type signal,
  94        enum clock_source_id clock_source,
  95        const struct dc_link_settings *link_settings)
  96{
  97        struct link_encoder *link_enc = link->link_enc;
  98        struct dc  *dc = link->ctx->dc;
  99        struct dmcu *dmcu = dc->res_pool->dmcu;
 100
 101        struct pipe_ctx *pipes =
 102                        link->dc->current_state->res_ctx.pipe_ctx;
 103        struct clock_source *dp_cs =
 104                        link->dc->res_pool->dp_clock_source;
 105        unsigned int i;
 106        /* If the current pixel clock source is not DTO(happens after
 107         * switching from HDMI passive dongle to DP on the same connector),
 108         * switch the pixel clock source to DTO.
 109         */
 110        for (i = 0; i < MAX_PIPES; i++) {
 111                if (pipes[i].stream != NULL &&
 112                        pipes[i].stream->link == link) {
 113                        if (pipes[i].clock_source != NULL &&
 114                                        pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
 115                                pipes[i].clock_source = dp_cs;
 116                                pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
 117                                                pipes[i].stream->timing.pix_clk_100hz;
 118                                pipes[i].clock_source->funcs->program_pix_clk(
 119                                                        pipes[i].clock_source,
 120                                                        &pipes[i].stream_res.pix_clk_params,
 121                                                        &pipes[i].pll_settings);
 122                        }
 123                }
 124        }
 125
 126        if (dmcu != NULL && dmcu->funcs->lock_phy)
 127                dmcu->funcs->lock_phy(dmcu);
 128
 129        if (dc_is_dp_sst_signal(signal)) {
 130                link_enc->funcs->enable_dp_output(
 131                                                link_enc,
 132                                                link_settings,
 133                                                clock_source);
 134        } else {
 135                link_enc->funcs->enable_dp_mst_output(
 136                                                link_enc,
 137                                                link_settings,
 138                                                clock_source);
 139        }
 140
 141        if (dmcu != NULL && dmcu->funcs->unlock_phy)
 142                dmcu->funcs->unlock_phy(dmcu);
 143
 144        link->cur_link_settings = *link_settings;
 145
 146        dp_receiver_power_ctrl(link, true);
 147}
 148
 149bool edp_receiver_ready_T9(struct dc_link *link)
 150{
 151        unsigned int tries = 0;
 152        unsigned char sinkstatus = 0;
 153        unsigned char edpRev = 0;
 154        enum dc_status result = DC_OK;
 155        result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
 156
 157     /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
 158        if (result == DC_OK && edpRev >= DP_EDP_12) {
 159                do {
 160                        sinkstatus = 1;
 161                        result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
 162                        if (sinkstatus == 0)
 163                                break;
 164                        if (result != DC_OK)
 165                                break;
 166                        udelay(100); //MAx T9
 167                } while (++tries < 50);
 168        }
 169
 170        if (link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
 171                udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
 172
 173        return result;
 174}
 175bool edp_receiver_ready_T7(struct dc_link *link)
 176{
 177        unsigned char sinkstatus = 0;
 178        unsigned char edpRev = 0;
 179        enum dc_status result = DC_OK;
 180
 181        /* use absolute time stamp to constrain max T7*/
 182        unsigned long long enter_timestamp = 0;
 183        unsigned long long finish_timestamp = 0;
 184        unsigned long long time_taken_in_ns = 0;
 185
 186        result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
 187
 188        if (result == DC_OK && edpRev >= DP_EDP_12) {
 189                /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
 190                enter_timestamp = dm_get_timestamp(link->ctx);
 191                do {
 192                        sinkstatus = 0;
 193                        result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
 194                        if (sinkstatus == 1)
 195                                break;
 196                        if (result != DC_OK)
 197                                break;
 198                        udelay(25);
 199                        finish_timestamp = dm_get_timestamp(link->ctx);
 200                        time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
 201                } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
 202        }
 203
 204        if (link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
 205                udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
 206
 207        return result;
 208}
 209
 210void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
 211{
 212        struct dc  *dc = link->ctx->dc;
 213        struct dmcu *dmcu = dc->res_pool->dmcu;
 214
 215        if (!link->wa_flags.dp_keep_receiver_powered)
 216                dp_receiver_power_ctrl(link, false);
 217
 218        if (signal == SIGNAL_TYPE_EDP) {
 219                link->link_enc->funcs->disable_output(link->link_enc, signal);
 220                link->dc->hwss.edp_power_control(link, false);
 221        } else {
 222                if (dmcu != NULL && dmcu->funcs->lock_phy)
 223                        dmcu->funcs->lock_phy(dmcu);
 224
 225                link->link_enc->funcs->disable_output(link->link_enc, signal);
 226
 227                if (dmcu != NULL && dmcu->funcs->unlock_phy)
 228                        dmcu->funcs->unlock_phy(dmcu);
 229        }
 230
 231        /* Clear current link setting.*/
 232        memset(&link->cur_link_settings, 0,
 233                        sizeof(link->cur_link_settings));
 234}
 235
 236void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
 237{
 238        /* MST disable link only when no stream use the link */
 239        if (link->mst_stream_alloc_table.stream_count > 0)
 240                return;
 241
 242        dp_disable_link_phy(link, signal);
 243
 244        /* set the sink to SST mode after disabling the link */
 245        dp_enable_mst_on_sink(link, false);
 246}
 247
 248bool dp_set_hw_training_pattern(
 249        struct dc_link *link,
 250        enum dc_dp_training_pattern pattern,
 251        uint32_t offset)
 252{
 253        enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
 254
 255        switch (pattern) {
 256        case DP_TRAINING_PATTERN_SEQUENCE_1:
 257                test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
 258                break;
 259        case DP_TRAINING_PATTERN_SEQUENCE_2:
 260                test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
 261                break;
 262        case DP_TRAINING_PATTERN_SEQUENCE_3:
 263                test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
 264                break;
 265        case DP_TRAINING_PATTERN_SEQUENCE_4:
 266                test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
 267                break;
 268        default:
 269                break;
 270        }
 271
 272        dp_set_hw_test_pattern(link, test_pattern, NULL, 0);
 273
 274        return true;
 275}
 276
 277void dp_set_hw_lane_settings(
 278        struct dc_link *link,
 279        const struct link_training_settings *link_settings,
 280        uint32_t offset)
 281{
 282        struct link_encoder *encoder = link->link_enc;
 283
 284        if (!link->is_lttpr_mode_transparent && !is_immediate_downstream(link, offset))
 285                return;
 286
 287        /* call Encoder to set lane settings */
 288        encoder->funcs->dp_set_lane_settings(encoder, link_settings);
 289}
 290
 291void dp_set_hw_test_pattern(
 292        struct dc_link *link,
 293        enum dp_test_pattern test_pattern,
 294        uint8_t *custom_pattern,
 295        uint32_t custom_pattern_size)
 296{
 297        struct encoder_set_dp_phy_pattern_param pattern_param = {0};
 298        struct link_encoder *encoder = link->link_enc;
 299
 300        pattern_param.dp_phy_pattern = test_pattern;
 301        pattern_param.custom_pattern = custom_pattern;
 302        pattern_param.custom_pattern_size = custom_pattern_size;
 303        pattern_param.dp_panel_mode = dp_get_panel_mode(link);
 304
 305        encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
 306}
 307
 308void dp_retrain_link_dp_test(struct dc_link *link,
 309                        struct dc_link_settings *link_setting,
 310                        bool skip_video_pattern)
 311{
 312        struct pipe_ctx *pipes =
 313                        &link->dc->current_state->res_ctx.pipe_ctx[0];
 314        unsigned int i;
 315
 316        for (i = 0; i < MAX_PIPES; i++) {
 317                if (pipes[i].stream != NULL &&
 318                        !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
 319                        pipes[i].stream->link != NULL &&
 320                        pipes[i].stream_res.stream_enc != NULL &&
 321                        pipes[i].stream->link == link) {
 322                        udelay(100);
 323
 324                        pipes[i].stream_res.stream_enc->funcs->dp_blank(
 325                                        pipes[i].stream_res.stream_enc);
 326
 327                        /* disable any test pattern that might be active */
 328                        dp_set_hw_test_pattern(link,
 329                                        DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
 330
 331                        dp_receiver_power_ctrl(link, false);
 332
 333                        link->dc->hwss.disable_stream(&pipes[i]);
 334                        if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
 335                                (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
 336
 337                        link->link_enc->funcs->disable_output(
 338                                        link->link_enc,
 339                                        SIGNAL_TYPE_DISPLAY_PORT);
 340
 341                        /* Clear current link setting. */
 342                        memset(&link->cur_link_settings, 0,
 343                                sizeof(link->cur_link_settings));
 344
 345                        perform_link_training_with_retries(
 346                                        link_setting,
 347                                        skip_video_pattern,
 348                                        LINK_TRAINING_ATTEMPTS,
 349                                        &pipes[i],
 350                                        SIGNAL_TYPE_DISPLAY_PORT);
 351
 352                        link->dc->hwss.enable_stream(&pipes[i]);
 353
 354                        link->dc->hwss.unblank_stream(&pipes[i],
 355                                        link_setting);
 356
 357                        if (pipes[i].stream_res.audio) {
 358                                /* notify audio driver for
 359                                 * audio modes of monitor */
 360                                pipes[i].stream_res.audio->funcs->az_enable(
 361                                                pipes[i].stream_res.audio);
 362
 363                                /* un-mute audio */
 364                                /* TODO: audio should be per stream rather than
 365                                 * per link */
 366                                pipes[i].stream_res.stream_enc->funcs->
 367                                audio_mute_control(
 368                                        pipes[i].stream_res.stream_enc, false);
 369                        }
 370                }
 371        }
 372}
 373
 374#define DC_LOGGER \
 375        dsc->ctx->logger
 376static void dsc_optc_config_log(struct display_stream_compressor *dsc,
 377                struct dsc_optc_config *config)
 378{
 379        uint32_t precision = 1 << 28;
 380        uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
 381        uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
 382        uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
 383
 384        /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
 385         * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
 386         * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
 387         */
 388        ll_bytes_per_pix_fraq *= 10000000;
 389        ll_bytes_per_pix_fraq /= precision;
 390
 391        DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
 392                        config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
 393        DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
 394        DC_LOG_DSC("\tslice_width %d", config->slice_width);
 395}
 396
 397static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
 398{
 399        struct dc *dc = pipe_ctx->stream->ctx->dc;
 400        struct dc_stream_state *stream = pipe_ctx->stream;
 401        bool result = false;
 402
 403        if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
 404                result = true;
 405        else
 406                result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
 407        return result;
 408}
 409
 410/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
 411 * i.e. after dp_enable_dsc_on_rx() had been called
 412 */
 413void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 414{
 415        struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 416        struct dc *dc = pipe_ctx->stream->ctx->dc;
 417        struct dc_stream_state *stream = pipe_ctx->stream;
 418        struct pipe_ctx *odm_pipe;
 419        int opp_cnt = 1;
 420
 421        for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
 422                opp_cnt++;
 423
 424        if (enable) {
 425                struct dsc_config dsc_cfg;
 426                struct dsc_optc_config dsc_optc_cfg;
 427                enum optc_dsc_mode optc_dsc_mode;
 428
 429                /* Enable DSC hw block */
 430                dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
 431                dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
 432                dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
 433                dsc_cfg.color_depth = stream->timing.display_color_depth;
 434                dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
 435                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
 436                ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
 437                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
 438
 439                dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
 440                dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
 441                for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 442                        struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
 443
 444                        odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
 445                        odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
 446                }
 447                dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
 448                dsc_cfg.pic_width *= opp_cnt;
 449
 450                optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
 451
 452                /* Enable DSC in encoder */
 453                if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
 454                        DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
 455                        dsc_optc_config_log(dsc, &dsc_optc_cfg);
 456                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
 457                                                                        optc_dsc_mode,
 458                                                                        dsc_optc_cfg.bytes_per_pixel,
 459                                                                        dsc_optc_cfg.slice_width);
 460
 461                        /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
 462                }
 463
 464                /* Enable DSC in OPTC */
 465                DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
 466                dsc_optc_config_log(dsc, &dsc_optc_cfg);
 467                pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
 468                                                        optc_dsc_mode,
 469                                                        dsc_optc_cfg.bytes_per_pixel,
 470                                                        dsc_optc_cfg.slice_width);
 471        } else {
 472                /* disable DSC in OPTC */
 473                pipe_ctx->stream_res.tg->funcs->set_dsc_config(
 474                                pipe_ctx->stream_res.tg,
 475                                OPTC_DSC_DISABLED, 0, 0);
 476
 477                /* disable DSC in stream encoder */
 478                if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
 479                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
 480                                        pipe_ctx->stream_res.stream_enc,
 481                                        OPTC_DSC_DISABLED, 0, 0);
 482
 483                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 484                                        pipe_ctx->stream_res.stream_enc, false, NULL);
 485                }
 486
 487                /* disable DSC block */
 488                pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
 489                for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
 490                        odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
 491        }
 492}
 493
 494bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
 495{
 496        struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 497        bool result = false;
 498
 499        if (!pipe_ctx->stream->timing.flags.DSC)
 500                goto out;
 501        if (!dsc)
 502                goto out;
 503
 504        if (enable) {
 505                if (dp_set_dsc_on_rx(pipe_ctx, true)) {
 506                        dp_set_dsc_on_stream(pipe_ctx, true);
 507                        result = true;
 508                }
 509        } else {
 510                dp_set_dsc_on_rx(pipe_ctx, false);
 511                dp_set_dsc_on_stream(pipe_ctx, false);
 512                result = true;
 513        }
 514out:
 515        return result;
 516}
 517
 518bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
 519{
 520        struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 521        struct dc *dc = pipe_ctx->stream->ctx->dc;
 522        struct dc_stream_state *stream = pipe_ctx->stream;
 523
 524        if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
 525                return false;
 526
 527        if (enable) {
 528                struct dsc_config dsc_cfg;
 529                uint8_t dsc_packed_pps[128];
 530
 531                memset(&dsc_cfg, 0, sizeof(dsc_cfg));
 532                memset(dsc_packed_pps, 0, 128);
 533
 534                /* Enable DSC hw block */
 535                dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
 536                dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
 537                dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
 538                dsc_cfg.color_depth = stream->timing.display_color_depth;
 539                dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
 540                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
 541
 542                DC_LOG_DSC(" ");
 543                dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
 544                if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
 545                        DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
 546                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 547                                                                        pipe_ctx->stream_res.stream_enc,
 548                                                                        true,
 549                                                                        &dsc_packed_pps[0]);
 550                }
 551        } else {
 552                /* disable DSC PPS in stream encoder */
 553                if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
 554                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 555                                                pipe_ctx->stream_res.stream_enc, false, NULL);
 556                }
 557        }
 558
 559        return true;
 560}
 561
 562
 563bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
 564{
 565        struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 566
 567        if (!pipe_ctx->stream->timing.flags.DSC)
 568                return false;
 569        if (!dsc)
 570                return false;
 571
 572        dp_set_dsc_on_stream(pipe_ctx, true);
 573        dp_set_dsc_pps_sdp(pipe_ctx, true);
 574        return true;
 575}
 576
 577