aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch
blob: bb89323bff38260ef05c4203c33e36f79b7b256c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
From 17f4668db8e266746de89547d36a046457d090ae Mon Sep 17 00:00:00 2001
From: Nikola Cornij <nikola.cornij@amd.com>
Date: Wed, 17 Jul 2019 19:02:14 -0400
Subject: [PATCH 3416/4256] drm/amd/display: Set DSC before DIG front-end is
 connected to its back-end

[why]
At the time DIG FE is connected to its BE, the clocks in OTG are enabled and
PHY will also be set up. When DSC has to be used to fit the stream into the
available bandwidth, without DSC being set DIG could get exposed to the
higer bandwidth it (or link) could handle. This causes the HW to "reject"
video enable setup (the register shows that video enable was attempted, but
the status bit shows it as disabled).

[how]
- Separate DSC setup into DSC register config and DSC PPS SDP setup

- Move most of the DSC setup (register config) to before
  dcn10_link_encoder_connect_dig_be_to_fe() is  called

- Set up DSC PPS SDP after DIG FE is connected to its BE. This is because
  setting DSC PPS SDP before that has no effect.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  20 ++--
 .../drm/amd/display/dc/core/dc_link_hwss.c    |  78 +++++++++++---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c  | 100 ++++++++++--------
 .../display/dc/dcn20/dcn20_stream_encoder.c   |  25 +++--
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |   3 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h   |   4 +-
 .../amd/display/dc/inc/hw/stream_encoder.h    |  12 ++-
 7 files changed, 158 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 9fe324dbbe91..10b24af73c51 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2725,21 +2725,27 @@ void core_link_enable_stream(
 					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
 					COLOR_DEPTH_UNDEFINED);
 
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+		if (pipe_ctx->stream->timing.flags.DSC) {
+			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
+					dc_is_virtual_signal(pipe_ctx->stream->signal))
+				dp_set_dsc_enable(pipe_ctx, true);
+		}
+#endif
 		core_dc->hwss.enable_stream(pipe_ctx);
 
-		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
-			allocate_mst_payload(pipe_ctx);
-
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+		/* Set DPS PPS SDP (AKA "info frames") */
 		if (pipe_ctx->stream->timing.flags.DSC) {
 			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
 					dc_is_virtual_signal(pipe_ctx->stream->signal))
-				dp_set_dsc_enable(pipe_ctx, true);
-			pipe_ctx->stream_res.tg->funcs->wait_for_state(
-					pipe_ctx->stream_res.tg,
-					CRTC_STATE_VBLANK);
+				dp_set_dsc_pps_sdp(pipe_ctx, true);
 		}
 #endif
+
+		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
+			allocate_mst_payload(pipe_ctx);
+
 		core_dc->hwss.unblank_stream(pipe_ctx,
 			&pipe_ctx->stream->link->cur_link_settings);
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index daaff7319413..af65071b6cf5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -361,9 +361,10 @@ static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
 	return result;
 }
 
-/* This has to be done after DSC was enabled on RX first, i.e. after dp_enable_dsc_on_rx() had been called
+/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
+ * i.e. after dp_enable_dsc_on_rx() had been called
  */
-void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 	struct dc *core_dc = pipe_ctx->stream->ctx->dc;
@@ -371,11 +372,9 @@ void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 	struct pipe_ctx *odm_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx);
 
 	if (enable) {
-		/* TODO proper function */
 		struct dsc_config dsc_cfg;
 		struct dsc_optc_config dsc_optc_cfg;
 		enum optc_dsc_mode optc_dsc_mode;
-		uint8_t dsc_packed_pps[128];
 
 		/* Enable DSC hw block */
 		dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
@@ -384,19 +383,20 @@ void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 		dsc_cfg.color_depth = stream->timing.display_color_depth;
 		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
 
-		dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps[0]);
 		if (odm_pipe) {
 			struct display_stream_compressor *bot_dsc = odm_pipe->stream_res.dsc;
-			uint8_t dsc_packed_pps_odm[128];
 
 			dsc_cfg.pic_width /= 2;
 			ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % 2 == 0);
 			dsc_cfg.dc_dsc_cfg.num_slices_h /= 2;
-			dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps_odm[0]);
-			bot_dsc->funcs->dsc_set_config(bot_dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps_odm[0]);
+			dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+			bot_dsc->funcs->dsc_set_config(bot_dsc, &dsc_cfg, &dsc_optc_cfg);
+			dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
 			bot_dsc->funcs->dsc_enable(bot_dsc, odm_pipe->stream_res.opp->inst);
+		} else {
+			dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+			dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
 		}
-		dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
 
 		optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
 
@@ -406,8 +406,9 @@ void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
 									optc_dsc_mode,
 									dsc_optc_cfg.bytes_per_pixel,
-									dsc_optc_cfg.slice_width,
-									&dsc_packed_pps[0]);
+									dsc_optc_cfg.slice_width);
+
+			/* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
 
 		/* Enable DSC in OPTC */
 		pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
@@ -421,10 +422,14 @@ void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 				OPTC_DSC_DISABLED, 0, 0);
 
 		/* disable DSC in stream encoder */
-		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
+		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
 			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
 					pipe_ctx->stream_res.stream_enc,
-					OPTC_DSC_DISABLED, 0, 0, NULL);
+					OPTC_DSC_DISABLED, 0, 0);
+
+			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+					pipe_ctx->stream_res.stream_enc, false, NULL);
+		}
 
 		/* disable DSC block */
 		pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
@@ -445,18 +450,57 @@ bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
 
 	if (enable) {
 		if (dp_set_dsc_on_rx(pipe_ctx, true)) {
-			set_dsc_on_stream(pipe_ctx, true);
+			dp_set_dsc_on_stream(pipe_ctx, true);
 			result = true;
 		}
 	} else {
 		dp_set_dsc_on_rx(pipe_ctx, false);
-		set_dsc_on_stream(pipe_ctx, false);
+		dp_set_dsc_on_stream(pipe_ctx, false);
 		result = true;
 	}
 out:
 	return result;
 }
 
+bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
+{
+	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+	struct dc *core_dc = pipe_ctx->stream->ctx->dc;
+	struct dc_stream_state *stream = pipe_ctx->stream;
+
+	if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
+		return false;
+
+	if (enable) {
+		struct dsc_config dsc_cfg;
+		uint8_t dsc_packed_pps[128];
+
+		/* Enable DSC hw block */
+		dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
+		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+		dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+		dsc_cfg.color_depth = stream->timing.display_color_depth;
+		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+
+		dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
+		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
+			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+									pipe_ctx->stream_res.stream_enc,
+									true,
+									&dsc_packed_pps[0]);
+
+	} else {
+		/* disable DSC PPS in stream encoder */
+		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
+			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+						pipe_ctx->stream_res.stream_enc, false, NULL);
+		}
+	}
+
+	return true;
+}
+
+
 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -466,9 +510,9 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
 	if (!dsc)
 		return false;
 
-	set_dsc_on_stream(pipe_ctx, true);
+	dp_set_dsc_on_stream(pipe_ctx, true);
+	dp_set_dsc_pps_sdp(pipe_ctx, true);
 	return true;
 }
-
 #endif
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
index e870caa8d4fa..e4d184cdea82 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
@@ -29,7 +29,7 @@
 #include "dsc/dscc_types.h"
 
 static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_config *pps);
-static bool dsc_prepare_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
+static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals,
 			struct dsc_optc_config *dsc_optc_cfg);
 static void dsc_init_reg_values(struct dsc_reg_values *reg_vals);
 static void dsc_update_from_dsc_parameters(struct dsc_reg_values *reg_vals, const struct dsc_parameters *dsc_params);
@@ -42,7 +42,8 @@ static void dsc2_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock
 static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s);
 static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg);
 static void dsc2_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
-		struct dsc_optc_config *dsc_optc_cfg, uint8_t *dsc_packed_pps);
+		struct dsc_optc_config *dsc_optc_cfg);
+static bool dsc2_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, uint8_t *dsc_packed_pps);
 static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe);
 static void dsc2_disable(struct display_stream_compressor *dsc);
 
@@ -51,6 +52,7 @@ const struct dsc_funcs dcn20_dsc_funcs = {
 	.dsc_read_state = dsc2_read_state,
 	.dsc_validate_stream = dsc2_validate_stream,
 	.dsc_set_config = dsc2_set_config,
+	.dsc_get_packed_pps = dsc2_get_packed_pps,
 	.dsc_enable = dsc2_enable,
 	.dsc_disable = dsc2_disable,
 };
@@ -162,18 +164,17 @@ static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_ds
 static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg)
 {
 	struct dsc_optc_config dsc_optc_cfg;
+	struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
 
-	if (dsc_cfg->pic_width > TO_DCN20_DSC(dsc)->max_image_width)
+	if (dsc_cfg->pic_width > dsc20->max_image_width)
 		return false;
 
-	return dsc_prepare_config(dsc, dsc_cfg, &dsc_optc_cfg);
+	return dsc_prepare_config(dsc_cfg, &dsc20->reg_vals, &dsc_optc_cfg);
 }
 
 
-static void dsc_config_log(struct display_stream_compressor *dsc,
-		const struct dsc_config *config)
+static void dsc_config_log(struct display_stream_compressor *dsc, const struct dsc_config *config)
 {
-	DC_LOG_DSC("Setting DSC Config at DSC inst %d", dsc->inst);
 	DC_LOG_DSC("\n\tnum_slices_h %d\n\tnum_slices_v %d\n\tbits_per_pixel %d\n\tcolor_depth %d",
 		config->dc_dsc_cfg.num_slices_h,
 		config->dc_dsc_cfg.num_slices_v,
@@ -182,20 +183,37 @@ static void dsc_config_log(struct display_stream_compressor *dsc,
 }
 
 static void dsc2_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
-		struct dsc_optc_config *dsc_optc_cfg, uint8_t *dsc_packed_pps)
+		struct dsc_optc_config *dsc_optc_cfg)
 {
 	bool is_config_ok;
 	struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
 
+	DC_LOG_DSC("Setting DSC Config at DSC inst %d", dsc->inst);
 	dsc_config_log(dsc, dsc_cfg);
-	is_config_ok = dsc_prepare_config(dsc, dsc_cfg, dsc_optc_cfg);
+	is_config_ok = dsc_prepare_config(dsc_cfg, &dsc20->reg_vals, dsc_optc_cfg);
 	ASSERT(is_config_ok);
-	drm_dsc_pps_payload_pack((struct drm_dsc_picture_parameter_set *)dsc_packed_pps, &dsc20->reg_vals.pps);
 	dsc_log_pps(dsc, &dsc20->reg_vals.pps);
 	dsc_write_to_registers(dsc, &dsc20->reg_vals);
 }
 
 
+static bool dsc2_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, uint8_t *dsc_packed_pps)
+{
+	bool is_config_ok;
+	struct dsc_reg_values dsc_reg_vals;
+	struct dsc_optc_config dsc_optc_cfg;
+
+	DC_LOG_DSC("Packed DSC PPS for DSC Config:");
+	dsc_config_log(dsc, dsc_cfg);
+	is_config_ok = dsc_prepare_config(dsc_cfg, &dsc_reg_vals, &dsc_optc_cfg);
+	ASSERT(is_config_ok);
+	drm_dsc_pps_payload_pack((struct drm_dsc_picture_parameter_set *)dsc_packed_pps, &dsc_reg_vals.pps);
+	dsc_log_pps(dsc, &dsc_reg_vals.pps);
+
+	return is_config_ok;
+}
+
+
 static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe)
 {
 	struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
@@ -282,13 +300,11 @@ static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_co
 	}
 }
 
-static bool dsc_prepare_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
+static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals,
 			struct dsc_optc_config *dsc_optc_cfg)
 {
 	struct dsc_parameters dsc_params;
 
-	struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
-
 	/* Validate input parameters */
 	ASSERT(dsc_cfg->dc_dsc_cfg.num_slices_h);
 	ASSERT(dsc_cfg->dc_dsc_cfg.num_slices_v);
@@ -315,54 +331,54 @@ static bool dsc_prepare_config(struct display_stream_compressor *dsc, const stru
 		return false;
 	}
 
-	dsc_init_reg_values(&dsc20->reg_vals);
+	dsc_init_reg_values(dsc_reg_vals);
 
 	/* Copy input config */
-	dsc20->reg_vals.pixel_format = dsc_dc_pixel_encoding_to_dsc_pixel_format(dsc_cfg->pixel_encoding, dsc_cfg->dc_dsc_cfg.ycbcr422_simple);
-	dsc20->reg_vals.num_slices_h = dsc_cfg->dc_dsc_cfg.num_slices_h;
-	dsc20->reg_vals.num_slices_v = dsc_cfg->dc_dsc_cfg.num_slices_v;
-	dsc20->reg_vals.pps.dsc_version_minor = dsc_cfg->dc_dsc_cfg.version_minor;
-	dsc20->reg_vals.pps.pic_width = dsc_cfg->pic_width;
-	dsc20->reg_vals.pps.pic_height = dsc_cfg->pic_height;
-	dsc20->reg_vals.pps.bits_per_component = dsc_dc_color_depth_to_dsc_bits_per_comp(dsc_cfg->color_depth);
-	dsc20->reg_vals.pps.block_pred_enable = dsc_cfg->dc_dsc_cfg.block_pred_enable;
-	dsc20->reg_vals.pps.line_buf_depth = dsc_cfg->dc_dsc_cfg.linebuf_depth;
-	dsc20->reg_vals.alternate_ich_encoding_en = dsc20->reg_vals.pps.dsc_version_minor == 1 ? 0 : 1;
+	dsc_reg_vals->pixel_format = dsc_dc_pixel_encoding_to_dsc_pixel_format(dsc_cfg->pixel_encoding, dsc_cfg->dc_dsc_cfg.ycbcr422_simple);
+	dsc_reg_vals->num_slices_h = dsc_cfg->dc_dsc_cfg.num_slices_h;
+	dsc_reg_vals->num_slices_v = dsc_cfg->dc_dsc_cfg.num_slices_v;
+	dsc_reg_vals->pps.dsc_version_minor = dsc_cfg->dc_dsc_cfg.version_minor;
+	dsc_reg_vals->pps.pic_width = dsc_cfg->pic_width;
+	dsc_reg_vals->pps.pic_height = dsc_cfg->pic_height;
+	dsc_reg_vals->pps.bits_per_component = dsc_dc_color_depth_to_dsc_bits_per_comp(dsc_cfg->color_depth);
+	dsc_reg_vals->pps.block_pred_enable = dsc_cfg->dc_dsc_cfg.block_pred_enable;
+	dsc_reg_vals->pps.line_buf_depth = dsc_cfg->dc_dsc_cfg.linebuf_depth;
+	dsc_reg_vals->alternate_ich_encoding_en = dsc_reg_vals->pps.dsc_version_minor == 1 ? 0 : 1;
 
 	// TODO: in addition to validating slice height (pic height must be divisible by slice height),
 	// see what happens when the same condition doesn't apply for slice_width/pic_width.
-	dsc20->reg_vals.pps.slice_width = dsc_cfg->pic_width / dsc_cfg->dc_dsc_cfg.num_slices_h;
-	dsc20->reg_vals.pps.slice_height = dsc_cfg->pic_height / dsc_cfg->dc_dsc_cfg.num_slices_v;
+	dsc_reg_vals->pps.slice_width = dsc_cfg->pic_width / dsc_cfg->dc_dsc_cfg.num_slices_h;
+	dsc_reg_vals->pps.slice_height = dsc_cfg->pic_height / dsc_cfg->dc_dsc_cfg.num_slices_v;
 
-	ASSERT(dsc20->reg_vals.pps.slice_height * dsc_cfg->dc_dsc_cfg.num_slices_v == dsc_cfg->pic_height);
-	if (!(dsc20->reg_vals.pps.slice_height * dsc_cfg->dc_dsc_cfg.num_slices_v == dsc_cfg->pic_height)) {
+	ASSERT(dsc_reg_vals->pps.slice_height * dsc_cfg->dc_dsc_cfg.num_slices_v == dsc_cfg->pic_height);
+	if (!(dsc_reg_vals->pps.slice_height * dsc_cfg->dc_dsc_cfg.num_slices_v == dsc_cfg->pic_height)) {
 		dm_output_to_console("%s: pix height %d not divisible by num_slices_v %d\n\n", __func__, dsc_cfg->pic_height, dsc_cfg->dc_dsc_cfg.num_slices_v);
 		return false;
 	}
 
-	dsc20->reg_vals.bpp_x32 = dsc_cfg->dc_dsc_cfg.bits_per_pixel << 1;
-	if (dsc20->reg_vals.pixel_format == DSC_PIXFMT_NATIVE_YCBCR420 || dsc20->reg_vals.pixel_format == DSC_PIXFMT_NATIVE_YCBCR422)
-		dsc20->reg_vals.pps.bits_per_pixel = dsc20->reg_vals.bpp_x32;
+	dsc_reg_vals->bpp_x32 = dsc_cfg->dc_dsc_cfg.bits_per_pixel << 1;
+	if (dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR420 || dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR422)
+		dsc_reg_vals->pps.bits_per_pixel = dsc_reg_vals->bpp_x32;
 	else
-		dsc20->reg_vals.pps.bits_per_pixel = dsc20->reg_vals.bpp_x32 >> 1;
+		dsc_reg_vals->pps.bits_per_pixel = dsc_reg_vals->bpp_x32 >> 1;
 
-	dsc20->reg_vals.pps.convert_rgb = dsc20->reg_vals.pixel_format == DSC_PIXFMT_RGB ? 1 : 0;
-	dsc20->reg_vals.pps.native_422 = (dsc20->reg_vals.pixel_format == DSC_PIXFMT_NATIVE_YCBCR422);
-	dsc20->reg_vals.pps.native_420 = (dsc20->reg_vals.pixel_format == DSC_PIXFMT_NATIVE_YCBCR420);
-	dsc20->reg_vals.pps.simple_422 = (dsc20->reg_vals.pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422);
+	dsc_reg_vals->pps.convert_rgb = dsc_reg_vals->pixel_format == DSC_PIXFMT_RGB ? 1 : 0;
+	dsc_reg_vals->pps.native_422 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR422);
+	dsc_reg_vals->pps.native_420 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR420);
+	dsc_reg_vals->pps.simple_422 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422);
 
-	if (dscc_compute_dsc_parameters(&dsc20->reg_vals.pps, &dsc_params)) {
+	if (dscc_compute_dsc_parameters(&dsc_reg_vals->pps, &dsc_params)) {
 		dm_output_to_console("%s: DSC config failed\n", __func__);
 		return false;
 	}
 
-	dsc_update_from_dsc_parameters(&dsc20->reg_vals, &dsc_params);
+	dsc_update_from_dsc_parameters(dsc_reg_vals, &dsc_params);
 
 	dsc_optc_cfg->bytes_per_pixel = dsc_params.bytes_per_pixel;
-	dsc_optc_cfg->slice_width = dsc20->reg_vals.pps.slice_width;
-	dsc_optc_cfg->is_pixel_format_444 = dsc20->reg_vals.pixel_format == DSC_PIXFMT_RGB ||
-					dsc20->reg_vals.pixel_format == DSC_PIXFMT_YCBCR444 ||
-					dsc20->reg_vals.pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422;
+	dsc_optc_cfg->slice_width = dsc_reg_vals->pps.slice_width;
+	dsc_optc_cfg->is_pixel_format_444 = dsc_reg_vals->pixel_format == DSC_PIXFMT_RGB ||
+					dsc_reg_vals->pixel_format == DSC_PIXFMT_YCBCR444 ||
+					dsc_reg_vals->pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422;
 
 	return true;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
index a2f15387e946..6d54942ab98b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
@@ -205,9 +205,8 @@ static void enc2_stream_encoder_stop_hdmi_info_packets(
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 
-
 /* Update GSP7 SDP 128 byte long */
-static void enc2_send_gsp7_128_info_packet(
+static void enc2_update_gsp7_128_info_packet(
 	struct dcn10_stream_encoder *enc1,
 	const struct dc_info_packet_128 *info_packet)
 {
@@ -275,8 +274,7 @@ static void enc2_send_gsp7_128_info_packet(
 static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 					enum optc_dsc_mode dsc_mode,
 					uint32_t dsc_bytes_per_pixel,
-					uint32_t dsc_slice_width,
-					uint8_t *dsc_packed_pps)
+					uint32_t dsc_slice_width)
 {
 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 	uint32_t dsc_value = 0;
@@ -294,8 +292,16 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 
 	REG_SET(DP_DSC_BYTES_PER_PIXEL, 0,
 		DP_DSC_BYTES_PER_PIXEL, dsc_bytes_per_pixel);
+}
+
+
+static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
+					bool enable,
+					uint8_t *dsc_packed_pps)
+{
+	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
-	if (dsc_mode != OPTC_DSC_DISABLED) {
+	if (enable) {
 		struct dc_info_packet_128 pps_sdp;
 
 		ASSERT(dsc_packed_pps);
@@ -307,7 +313,7 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 		pps_sdp.hb2 = 127;
 		pps_sdp.hb3 = 0;
 		memcpy(&pps_sdp.sb[0], dsc_packed_pps, sizeof(pps_sdp.sb));
-		enc2_send_gsp7_128_info_packet(enc1, &pps_sdp);
+		enc2_update_gsp7_128_info_packet(enc1, &pps_sdp);
 
 		/* Enable Generic Stream Packet 7 (GSP) transmission */
 		//REG_UPDATE(DP_SEC_CNTL,
@@ -338,9 +344,8 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 		REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 0);
 	}
 }
-#endif
 
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+
 /* this function read dsc related register fields to be logged later in dcn10_log_hw_state
  * into a dcn_dsc_state struct.
  */
@@ -581,10 +586,8 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
 	.dig_source_otg = enc1_dig_source_otg,
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 	.enc_read_state = enc2_read_state,
-#endif
-
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 	.dp_set_dsc_config = enc2_dp_set_dsc_config,
+	.dp_set_dsc_pps_info_packet = enc2_dp_set_dsc_pps_info_packet,
 #endif
 	.set_dynamic_metadata = enc2_set_dynamic_metadata,
 	.hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index 2ef23963e1f7..b4e7b0c56f83 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -69,7 +69,8 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode);
 void dp_set_fec_ready(struct dc_link *link, bool ready);
 void dp_set_fec_enable(struct dc_link *link, bool enable);
 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
-void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
+bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable);
+void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
 #endif
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h
index c905d020b59e..1ddb1c6fa149 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h
@@ -92,7 +92,9 @@ struct dsc_funcs {
 	void (*dsc_read_state)(struct display_stream_compressor *dsc, struct dcn_dsc_state *s);
 	bool (*dsc_validate_stream)(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg);
 	void (*dsc_set_config)(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
-			struct dsc_optc_config *dsc_optc_cfg, uint8_t *dsc_packed_pps);
+			struct dsc_optc_config *dsc_optc_cfg);
+	bool (*dsc_get_packed_pps)(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
+			uint8_t *dsc_packed_pps);
 	void (*dsc_enable)(struct display_stream_compressor *dsc, int opp_pipe);
 	void (*dsc_disable)(struct display_stream_compressor *dsc);
 };
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index 067ba6fc04c1..8bb3e3d56ac9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -122,9 +122,6 @@ struct enc_state {
 #endif
 
 struct stream_encoder_funcs {
-	#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-		void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s);
-	#endif
 	void (*dp_set_stream_attribute)(
 		struct stream_encoder *enc,
 		struct dc_crtc_timing *crtc_timing,
@@ -219,12 +216,17 @@ struct stream_encoder_funcs {
 
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s);
+
 	void (*dp_set_dsc_config)(
 			struct stream_encoder *enc,
 			enum optc_dsc_mode dsc_mode,
 			uint32_t dsc_bytes_per_pixel,
-			uint32_t dsc_slice_width,
-			uint8_t *dsc_packed_pps);
+			uint32_t dsc_slice_width);
+
+	void (*dp_set_dsc_pps_info_packet)(struct stream_encoder *enc,
+				bool enable,
+				uint8_t *dsc_packed_pps);
 #endif
 
 	void (*set_dynamic_metadata)(struct stream_encoder *enc,
-- 
2.17.1