forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
....@@ -12,6 +12,39 @@
1212 #include "dc_link_ddc.h"
1313 #include "dm_helpers.h"
1414 #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
+}
1548
1649 enum dc_status core_link_read_dpcd(
1750 struct dc_link *link,
....@@ -19,10 +52,11 @@
1952 uint8_t *data,
2053 uint32_t size)
2154 {
22
- if (!dm_helpers_dp_read_dpcd(link->ctx,
23
- link,
24
- address, data, size))
25
- return DC_ERROR_UNEXPECTED;
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
+ }
2660
2761 return DC_OK;
2862 }
....@@ -33,10 +67,11 @@
3367 const uint8_t *data,
3468 uint32_t size)
3569 {
36
- if (!dm_helpers_dp_write_dpcd(link->ctx,
37
- link,
38
- address, data, size))
39
- return DC_ERROR_UNEXPECTED;
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
+ }
4075
4176 return DC_OK;
4277 }
....@@ -46,6 +81,9 @@
4681 uint8_t state;
4782
4883 state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
84
+
85
+ if (link->sync_lt_in_progress)
86
+ return;
4987
5088 core_link_write_dpcd(link, DP_SET_POWER, &state,
5189 sizeof(state));
....@@ -58,25 +96,32 @@
5896 const struct dc_link_settings *link_settings)
5997 {
6098 struct link_encoder *link_enc = link->link_enc;
99
+ struct dc *dc = link->ctx->dc;
100
+ struct dmcu *dmcu = dc->res_pool->dmcu;
61101
62102 struct pipe_ctx *pipes =
63103 link->dc->current_state->res_ctx.pipe_ctx;
64104 struct clock_source *dp_cs =
65105 link->dc->res_pool->dp_clock_source;
66106 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
+
67113 /* If the current pixel clock source is not DTO(happens after
68114 * switching from HDMI passive dongle to DP on the same connector),
69115 * switch the pixel clock source to DTO.
70116 */
71117 for (i = 0; i < MAX_PIPES; i++) {
72118 if (pipes[i].stream != NULL &&
73
- pipes[i].stream->sink != NULL &&
74
- pipes[i].stream->sink->link == link) {
119
+ pipes[i].stream->link == link) {
75120 if (pipes[i].clock_source != NULL &&
76121 pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
77122 pipes[i].clock_source = dp_cs;
78
- pipes[i].stream_res.pix_clk_params.requested_pix_clk =
79
- pipes[i].stream->timing.pix_clk_khz;
123
+ pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
124
+ pipes[i].stream->timing.pix_clk_100hz;
80125 pipes[i].clock_source->funcs->program_pix_clk(
81126 pipes[i].clock_source,
82127 &pipes[i].stream_res.pix_clk_params,
....@@ -84,6 +129,14 @@
84129 }
85130 }
86131 }
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);
87140
88141 if (dc_is_dp_sst_signal(signal)) {
89142 link_enc->funcs->enable_dp_output(
....@@ -97,6 +150,9 @@
97150 clock_source);
98151 }
99152
153
+ if (dmcu != NULL && dmcu->funcs->unlock_phy)
154
+ dmcu->funcs->unlock_phy(dmcu);
155
+
100156 dp_receiver_power_ctrl(link, true);
101157 }
102158
....@@ -105,59 +161,94 @@
105161 unsigned int tries = 0;
106162 unsigned char sinkstatus = 0;
107163 unsigned char edpRev = 0;
108
- enum dc_status result = DC_OK;
164
+ enum dc_status result;
165
+
109166 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
110
- if (edpRev < DP_EDP_12)
111
- return true;
112
- /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
113
- do {
114
- sinkstatus = 1;
115
- result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
116
- if (sinkstatus == 0)
117
- break;
118
- if (result != DC_OK)
119
- break;
120
- udelay(100); //MAx T9
121
- } while (++tries < 50);
167
+
168
+ /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
169
+ if (result == DC_OK && edpRev >= DP_EDP_12) {
170
+ do {
171
+ sinkstatus = 1;
172
+ result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
173
+ if (sinkstatus == 0)
174
+ break;
175
+ if (result != DC_OK)
176
+ break;
177
+ udelay(100); //MAx T9
178
+ } while (++tries < 50);
179
+ }
180
+
181
+ if (link->local_sink &&
182
+ link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
183
+ udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
184
+
122185 return result;
123186 }
124187 bool edp_receiver_ready_T7(struct dc_link *link)
125188 {
126
- unsigned int tries = 0;
127189 unsigned char sinkstatus = 0;
128190 unsigned char edpRev = 0;
129
- enum dc_status result = DC_OK;
191
+ enum dc_status result;
192
+
193
+ /* use absolute time stamp to constrain max T7*/
194
+ unsigned long long enter_timestamp = 0;
195
+ unsigned long long finish_timestamp = 0;
196
+ unsigned long long time_taken_in_ns = 0;
130197
131198 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
132
- if (result == DC_OK && edpRev < DP_EDP_12)
133
- return true;
134
- /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
135
- do {
136
- sinkstatus = 0;
137
- result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
138
- if (sinkstatus == 1)
139
- break;
140
- if (result != DC_OK)
141
- break;
142
- udelay(25); //MAx T7 is 50ms
143
- } while (++tries < 300);
199
+
200
+ if (result == DC_OK && edpRev >= DP_EDP_12) {
201
+ /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
202
+ enter_timestamp = dm_get_timestamp(link->ctx);
203
+ do {
204
+ sinkstatus = 0;
205
+ result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
206
+ if (sinkstatus == 1)
207
+ break;
208
+ if (result != DC_OK)
209
+ break;
210
+ udelay(25);
211
+ finish_timestamp = dm_get_timestamp(link->ctx);
212
+ time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
213
+ } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
214
+ }
215
+
216
+ if (link->local_sink &&
217
+ link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
218
+ udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
219
+
144220 return result;
145221 }
146222
147223 void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
148224 {
225
+ struct dc *dc = link->ctx->dc;
226
+ struct dmcu *dmcu = dc->res_pool->dmcu;
227
+
149228 if (!link->wa_flags.dp_keep_receiver_powered)
150229 dp_receiver_power_ctrl(link, false);
151230
152231 if (signal == SIGNAL_TYPE_EDP) {
232
+ if (link->dc->hwss.edp_backlight_control)
233
+ link->dc->hwss.edp_backlight_control(link, false);
153234 link->link_enc->funcs->disable_output(link->link_enc, signal);
154235 link->dc->hwss.edp_power_control(link, false);
155
- } else
236
+ } else {
237
+ if (dmcu != NULL && dmcu->funcs->lock_phy)
238
+ dmcu->funcs->lock_phy(dmcu);
239
+
156240 link->link_enc->funcs->disable_output(link->link_enc, signal);
241
+
242
+ if (dmcu != NULL && dmcu->funcs->unlock_phy)
243
+ dmcu->funcs->unlock_phy(dmcu);
244
+ }
157245
158246 /* Clear current link setting.*/
159247 memset(&link->cur_link_settings, 0,
160248 sizeof(link->cur_link_settings));
249
+
250
+ if (dc->clk_mgr->funcs->notify_link_rate_change)
251
+ dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
161252 }
162253
163254 void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
....@@ -174,21 +265,22 @@
174265
175266 bool dp_set_hw_training_pattern(
176267 struct dc_link *link,
177
- enum hw_dp_training_pattern pattern)
268
+ enum dc_dp_training_pattern pattern,
269
+ uint32_t offset)
178270 {
179271 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
180272
181273 switch (pattern) {
182
- case HW_DP_TRAINING_PATTERN_1:
274
+ case DP_TRAINING_PATTERN_SEQUENCE_1:
183275 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
184276 break;
185
- case HW_DP_TRAINING_PATTERN_2:
277
+ case DP_TRAINING_PATTERN_SEQUENCE_2:
186278 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
187279 break;
188
- case HW_DP_TRAINING_PATTERN_3:
280
+ case DP_TRAINING_PATTERN_SEQUENCE_3:
189281 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
190282 break;
191
- case HW_DP_TRAINING_PATTERN_4:
283
+ case DP_TRAINING_PATTERN_SEQUENCE_4:
192284 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
193285 break;
194286 default:
....@@ -202,52 +294,16 @@
202294
203295 void dp_set_hw_lane_settings(
204296 struct dc_link *link,
205
- const struct link_training_settings *link_settings)
297
+ const struct link_training_settings *link_settings,
298
+ uint32_t offset)
206299 {
207300 struct link_encoder *encoder = link->link_enc;
208301
302
+ if (link->lttpr_non_transparent_mode && !is_immediate_downstream(link, offset))
303
+ return;
304
+
209305 /* call Encoder to set lane settings */
210306 encoder->funcs->dp_set_lane_settings(encoder, link_settings);
211
-}
212
-
213
-enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
214
-{
215
- /* We need to explicitly check that connector
216
- * is not DP. Some Travis_VGA get reported
217
- * by video bios as DP.
218
- */
219
- if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
220
-
221
- switch (link->dpcd_caps.branch_dev_id) {
222
- case DP_BRANCH_DEVICE_ID_2:
223
- if (strncmp(
224
- link->dpcd_caps.branch_dev_name,
225
- DP_VGA_LVDS_CONVERTER_ID_2,
226
- sizeof(
227
- link->dpcd_caps.
228
- branch_dev_name)) == 0) {
229
- return DP_PANEL_MODE_SPECIAL;
230
- }
231
- break;
232
- case DP_BRANCH_DEVICE_ID_3:
233
- if (strncmp(link->dpcd_caps.branch_dev_name,
234
- DP_VGA_LVDS_CONVERTER_ID_3,
235
- sizeof(
236
- link->dpcd_caps.
237
- branch_dev_name)) == 0) {
238
- return DP_PANEL_MODE_SPECIAL;
239
- }
240
- break;
241
- default:
242
- break;
243
- }
244
- }
245
-
246
- if (link->dpcd_caps.panel_mode_edp) {
247
- return DP_PANEL_MODE_EDP;
248
- }
249
-
250
- return DP_PANEL_MODE_DEFAULT;
251307 }
252308
253309 void dp_set_hw_test_pattern(
....@@ -277,11 +333,10 @@
277333
278334 for (i = 0; i < MAX_PIPES; i++) {
279335 if (pipes[i].stream != NULL &&
280
- !pipes[i].top_pipe &&
281
- pipes[i].stream->sink != NULL &&
282
- pipes[i].stream->sink->link != NULL &&
336
+ !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
337
+ pipes[i].stream->link != NULL &&
283338 pipes[i].stream_res.stream_enc != NULL &&
284
- pipes[i].stream->sink->link == link) {
339
+ pipes[i].stream->link == link) {
285340 udelay(100);
286341
287342 pipes[i].stream_res.stream_enc->funcs->dp_blank(
....@@ -293,7 +348,9 @@
293348
294349 dp_receiver_power_ctrl(link, false);
295350
296
- link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
351
+ link->dc->hwss.disable_stream(&pipes[i]);
352
+ if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
353
+ (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
297354
298355 link->link_enc->funcs->disable_output(
299356 link->link_enc,
....@@ -303,20 +360,12 @@
303360 memset(&link->cur_link_settings, 0,
304361 sizeof(link->cur_link_settings));
305362
306
- link->link_enc->funcs->enable_dp_output(
307
- link->link_enc,
308
- link_setting,
309
- pipes[i].clock_source->id);
310
-
311
- dp_receiver_power_ctrl(link, true);
312
-
313363 perform_link_training_with_retries(
314
- link,
315364 link_setting,
316365 skip_video_pattern,
317
- LINK_TRAINING_ATTEMPTS);
318
-
319
- link->cur_link_settings = *link_setting;
366
+ LINK_TRAINING_ATTEMPTS,
367
+ &pipes[i],
368
+ SIGNAL_TYPE_DISPLAY_PORT);
320369
321370 link->dc->hwss.enable_stream(&pipes[i]);
322371
....@@ -339,3 +388,208 @@
339388 }
340389 }
341390 }
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
+static 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
+ if (dp_set_dsc_on_rx(pipe_ctx, true)) {
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
+