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