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
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch566
1 files changed, 566 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch
new file mode 100644
index 00000000..bb89323b
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3416-drm-amd-display-Set-DSC-before-DIG-front-end-is-conn.patch
@@ -0,0 +1,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
+