]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/display: Clean up dynamic metadata logic
authorJulian Parkin <julian.parkin@amd.com>
Wed, 3 Jul 2019 17:59:26 +0000 (13:59 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 18 Jul 2019 19:27:26 +0000 (14:27 -0500)
 [Why]
Code to enable DCN20 dynamic metadata feature is duplicated in two places
and was added to DCE110 enable stream.

[How]
Create DCN20 specific enable stream function for clarity, and add a hardware
sequencer function to program dynamic metadata to avoid the duplicate
code.

Signed-off-by: Julian Parkin <julian.parkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@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_stream.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index 352862370390e947dbbd06bd41a07d6de48ed0e7..bf1d7bb90e0f98885f9112b3ff2f32e6c205bb84 100644 (file)
@@ -566,6 +566,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
 
        return ret;
 }
+
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 bool dc_stream_dmdata_status_done(struct dc *dc, struct dc_stream_state *stream)
 {
@@ -597,6 +598,14 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
        struct hubp *hubp;
        int i;
 
+       /* Dynamic metadata is only supported on HDMI or DP */
+       if (!dc_is_hdmi_signal(stream->signal) && !dc_is_dp_signal(stream->signal))
+               return false;
+
+       /* Check hardware support */
+       if (!dc->hwss.program_dmdata_engine)
+               return false;
+
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream == stream)
@@ -612,23 +621,7 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 
        pipe_ctx->stream->dmdata_address = attr->address;
 
-       if (pipe_ctx->stream_res.stream_enc &&
-                       pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL) {
-               if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-                       /* if using dynamic meta, don't set up generic infopackets */
-                       pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-                       pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-                                       pipe_ctx->stream_res.stream_enc,
-                                       true, pipe_ctx->plane_res.hubp->inst,
-                                       dc_is_dp_signal(pipe_ctx->stream->signal) ?
-                                                       dmdata_dp : dmdata_hdmi);
-               } else
-                       pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-                                       pipe_ctx->stream_res.stream_enc,
-                                       false, pipe_ctx->plane_res.hubp->inst,
-                                       dc_is_dp_signal(pipe_ctx->stream->signal) ?
-                                                       dmdata_dp : dmdata_hdmi);
-       }
+       dc->hwss.program_dmdata_engine(pipe_ctx);
 
        if (hubp->funcs->dmdata_set_attributes != NULL &&
                        pipe_ctx->stream->dmdata_address.quad_part != 0) {
index 41f5ef6c5085474c75820d5d7574a4fc55525ff6..ddc5add503ec595141377b55d95ea362ae93bf6e 100644 (file)
@@ -667,29 +667,7 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
        link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
                                                    pipe_ctx->stream_res.stream_enc->id, true);
 
-       /* update AVI info frame (HDMI, DP)*/
-       /* TODO: FPGA may change to hwss.update_info_frame */
-
-#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
-       if (pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL &&
-                       pipe_ctx->plane_res.hubp != NULL) {
-               if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-                       /* if using dynamic meta, don't set up generic infopackets */
-                       pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-                       pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-                                       pipe_ctx->stream_res.stream_enc,
-                                       true, pipe_ctx->plane_res.hubp->inst,
-                                       dc_is_dp_signal(pipe_ctx->stream->signal) ?
-                                                       dmdata_dp : dmdata_hdmi);
-               } else
-                       pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-                                       pipe_ctx->stream_res.stream_enc,
-                                       false, pipe_ctx->plane_res.hubp->inst,
-                                       dc_is_dp_signal(pipe_ctx->stream->signal) ?
-                                                       dmdata_dp : dmdata_hdmi);
-       }
-#endif
-       dce110_update_info_frame(pipe_ctx);
+       link->dc->hwss.update_info_frame(pipe_ctx);
 
        /* enable early control to avoid corruption on DP monitor*/
        active_total_with_borders =
index 566cd4cdfef4b76b307d8823b35944dd83d2a595..76ce622e1421b690401f9454ebe756de4006997e 100644 (file)
@@ -2056,6 +2056,78 @@ static void dcn20_set_flip_control_gsl(
 
 }
 
+static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
+{
+       enum dc_lane_count lane_count =
+               pipe_ctx->stream->link->cur_link_settings.lane_count;
+
+       struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       struct dc_link *link = pipe_ctx->stream->link;
+
+       uint32_t active_total_with_borders;
+       uint32_t early_control = 0;
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+       /* For MST, there are multiply stream go to only one link.
+        * connect DIG back_end to front_end while enable_stream and
+        * disconnect them during disable_stream
+        * BY this, it is logic clean to separate stream and link
+        */
+       link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+                                                   pipe_ctx->stream_res.stream_enc->id, true);
+
+       if (link->dc->hwss.program_dmdata_engine)
+               link->dc->hwss.program_dmdata_engine(pipe_ctx);
+
+       link->dc->hwss.update_info_frame(pipe_ctx);
+
+       /* enable early control to avoid corruption on DP monitor*/
+       active_total_with_borders =
+                       timing->h_addressable
+                               + timing->h_border_left
+                               + timing->h_border_right;
+
+       if (lane_count != 0)
+               early_control = active_total_with_borders % lane_count;
+
+       if (early_control == 0)
+               early_control = lane_count;
+
+       tg->funcs->set_early_control(tg, early_control);
+
+       /* enable audio only within mode set */
+       if (pipe_ctx->stream_res.audio != NULL) {
+               if (dc_is_dp_signal(pipe_ctx->stream->signal))
+                       pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
+       }
+}
+
+static void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_stream_state    *stream     = pipe_ctx->stream;
+       struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
+       bool                       enable     = false;
+       struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
+       enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
+                                                       ? dmdata_dp
+                                                       : dmdata_hdmi;
+
+       /* if using dynamic meta, don't set up generic infopackets */
+       if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
+               pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
+               enable = true;
+       }
+
+       if (!hubp)
+               return;
+
+       if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
+               return;
+
+       stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
+                                               hubp->inst, mode);
+}
+
 void dcn20_hw_sequencer_construct(struct dc *dc)
 {
        dcn10_hw_sequencer_construct(dc);
@@ -2080,6 +2152,8 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
        dc->hwss.update_odm = dcn20_update_odm;
        dc->hwss.blank_pixel_data = dcn20_blank_pixel_data;
        dc->hwss.dmdata_status_done = dcn20_dmdata_status_done;
+       dc->hwss.program_dmdata_engine = dcn20_program_dmdata_engine;
+       dc->hwss.enable_stream = dcn20_enable_stream;
        dc->hwss.disable_stream = dcn20_disable_stream;
        dc->hwss.init_sys_ctx = dcn20_init_sys_ctx;
        dc->hwss.init_vm_ctx = dcn20_init_vm_ctx;
index 36be08adae0502da2921476e618a06a1914e179f..28645e10f854e057b833f06ee7ef16fdec879b06 100644 (file)
@@ -231,6 +231,7 @@ struct hw_sequencer_funcs {
        bool (*update_bandwidth)(
                        struct dc *dc,
                        struct dc_state *context);
+       void (*program_dmdata_engine)(struct pipe_ctx *pipe_ctx);
        bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
 #endif