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