]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/display: Set DSC before DIG front-end is connected to its back-end
authorNikola Cornij <nikola.cornij@amd.com>
Wed, 17 Jul 2019 23:02:14 +0000 (19:02 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 15 Aug 2019 15:54:53 +0000 (10:54 -0500)
[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>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h

index 892542d28c46161696b07a32c9957f84e6b58edb..af42adca6e50babc1a9af3169e3dd5870cb2a88b 100644 (file)
@@ -2727,21 +2727,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);
 
index daaff73194133baf2a101ee7e32999e896802953..af65071b6cf5f38c2a501d76e977c065699248f5 100644 (file)
@@ -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
 
index e870caa8d4fa4a63b66c8cf18eabf8f1407f8702..e4d184cdea820ce5a4c464902771d7c0cb5f390e 100644 (file)
@@ -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;
 }
index 88428950e29c8788962b544ff6f06dfb65f10330..aab0d21459bc04d2c89e77fc38f3e6df320a6bf2 100644 (file)
@@ -207,9 +207,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)
 {
@@ -277,8 +276,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;
@@ -296,8 +294,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);
@@ -309,7 +315,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,
@@ -340,9 +346,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.
  */
@@ -583,10 +588,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,
index 2ef23963e1f76c81cf2a058ca28685c07a42aa05..b4e7b0c56f83983068fabbcf25e6a4d7061279fa 100644 (file)
@@ -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
 
index c905d020b59e829bb204ffcd0e83dac356e3e3a1..1ddb1c6fa1493c1ece0cdda16ef93d2c123be7f1 100644 (file)
@@ -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);
 };
index 067ba6fc04c1e5972680909d574875c7e0667563..8bb3e3d56ac91135d1a11f61c87c2fef0fee1623 100644 (file)
@@ -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,