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