From: Julian Parkin Date: Wed, 3 Jul 2019 17:59:26 +0000 (-0400) Subject: drm/amd/display: Clean up dynamic metadata logic X-Git-Tag: v5.4-rc1~106^2~17^2~238 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=f591344e89dca887afeb5bbe21fa199687fd4a5f;p=linux.git drm/amd/display: Clean up dynamic metadata logic [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 Reviewed-by: Charlene Liu Acked-by: Leo Li Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 352862370390..bf1d7bb90e0f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -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) { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 41f5ef6c5085..ddc5add503ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -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 = diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 566cd4cdfef4..76ce622e1421 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -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; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 36be08adae05..28645e10f854 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -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