diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0121-drm-amd-display-decouple-front-and-backend-pgm-using.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0121-drm-amd-display-decouple-front-and-backend-pgm-using.patch | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0121-drm-amd-display-decouple-front-and-backend-pgm-using.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0121-drm-amd-display-decouple-front-and-backend-pgm-using.patch new file mode 100644 index 00000000..51471645 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0121-drm-amd-display-decouple-front-and-backend-pgm-using.patch @@ -0,0 +1,352 @@ +From f5e42a19be94fca3ba5ab9188b1154b87cd12e2e Mon Sep 17 00:00:00 2001 +From: Samson Tam <Samson.Tam@amd.com> +Date: Tue, 1 May 2018 10:39:26 -0400 +Subject: [PATCH 0121/2940] drm/amd/display: decouple front and backend pgm + using dpms_off as backend enable flag + +Signed-off-by: Samson Tam <Samson.Tam@amd.com> +Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 125 +++++++++++------- + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 34 +++++ + .../gpu/drm/amd/display/dc/core/dc_resource.c | 6 + + drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 + + .../display/dc/dce110/dce110_hw_sequencer.c | 38 +----- + 5 files changed, 123 insertions(+), 82 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index a51d7ce84134..2d0176eca1ab 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1279,6 +1279,9 @@ static enum surface_update_type check_update_surfaces_for_stream( + + if (stream_update->abm_level) + return UPDATE_TYPE_FULL; ++ ++ if (stream_update->dpms_off) ++ return UPDATE_TYPE_FULL; + } + + for (i = 0 ; i < surface_count; i++) { +@@ -1333,6 +1336,71 @@ static struct dc_stream_status *stream_get_status( + static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; + + ++static void commit_planes_do_stream_update(struct dc *dc, ++ struct dc_stream_state *stream, ++ struct dc_stream_update *stream_update, ++ enum surface_update_type update_type, ++ struct dc_state *context) ++{ ++ int j; ++ ++ // Stream updates ++ for (j = 0; j < dc->res_pool->pipe_count; j++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; ++ ++ if (!pipe_ctx->top_pipe && ++ pipe_ctx->stream && ++ pipe_ctx->stream == stream) { ++ ++ /* Fast update*/ ++ // VRR program can be done as part of FAST UPDATE ++ if (stream_update->adjust) ++ dc->hwss.set_drr(&pipe_ctx, 1, ++ stream_update->adjust->v_total_min, ++ stream_update->adjust->v_total_max); ++ ++ /* Full fe update*/ ++ if (update_type == UPDATE_TYPE_FAST) ++ continue; ++ ++ if (stream_update->dpms_off) { ++ if (*stream_update->dpms_off) { ++ core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE); ++ dc->hwss.pplib_apply_display_requirements( ++ dc, dc->current_state); ++ } else { ++ dc->hwss.pplib_apply_display_requirements( ++ dc, dc->current_state); ++ core_link_enable_stream(dc->current_state, pipe_ctx); ++ } ++ } ++ ++ if (stream_update->abm_level && pipe_ctx->stream_res.abm) { ++ if (pipe_ctx->stream_res.tg->funcs->is_blanked) { ++ // if otg funcs defined check if blanked before programming ++ if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) ++ pipe_ctx->stream_res.abm->funcs->set_abm_level( ++ pipe_ctx->stream_res.abm, stream->abm_level); ++ } else ++ pipe_ctx->stream_res.abm->funcs->set_abm_level( ++ pipe_ctx->stream_res.abm, stream->abm_level); ++ } ++ ++ if (stream_update->periodic_fn_vsync_delta && ++ pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) ++ pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( ++ pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, ++ pipe_ctx->stream->periodic_fn_vsync_delta); ++ ++ if (stream_update->hdr_static_metadata || ++ stream_update->vrr_infopacket) { ++ resource_build_info_frame(pipe_ctx); ++ dc->hwss.update_info_frame(pipe_ctx); ++ } ++ } ++ } ++} ++ + static void commit_planes_for_stream(struct dc *dc, + struct dc_surface_update *srf_updates, + int surface_count, +@@ -1349,15 +1417,20 @@ static void commit_planes_for_stream(struct dc *dc, + context_clock_trace(dc, context); + } + ++ // Stream updates ++ if (stream_update) ++ commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); ++ + if (surface_count == 0) { + /* + * In case of turning off screen, no need to program front end a second time. +- * just return after program front end. ++ * just return after program blank. + */ +- dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context); ++ dc->hwss.apply_ctx_for_surface(dc, stream, 0, context); + return; + } + ++ // Update Type FULL, Surface updates + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; + +@@ -1371,13 +1444,6 @@ static void commit_planes_for_stream(struct dc *dc, + if (!pipe_ctx->plane_state) + continue; + +- /* Fast update*/ +- // VRR program can be done as part of FAST UPDATE +- if (stream_update && stream_update->adjust) +- dc->hwss.set_drr(&pipe_ctx, 1, +- stream_update->adjust->v_total_min, +- stream_update->adjust->v_total_max); +- + /* Full fe update*/ + if (update_type == UPDATE_TYPE_FAST) + continue; +@@ -1387,34 +1453,18 @@ static void commit_planes_for_stream(struct dc *dc, + + dc->hwss.apply_ctx_for_surface( + dc, pipe_ctx->stream, stream_status->plane_count, context); +- +- if (stream_update && stream_update->abm_level && pipe_ctx->stream_res.abm) { +- if (pipe_ctx->stream_res.tg->funcs->is_blanked) { +- // if otg funcs defined check if blanked before programming +- if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) +- pipe_ctx->stream_res.abm->funcs->set_abm_level( +- pipe_ctx->stream_res.abm, stream->abm_level); +- } else +- pipe_ctx->stream_res.abm->funcs->set_abm_level( +- pipe_ctx->stream_res.abm, stream->abm_level); +- } +- +- if (stream_update && stream_update->periodic_fn_vsync_delta && +- pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) +- pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( +- pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, +- pipe_ctx->stream->periodic_fn_vsync_delta); + } + } + + if (update_type == UPDATE_TYPE_FULL) + context_timing_trace(dc, &context->res_ctx); + +- /* Lock the top pipe while updating plane addrs, since freesync requires +- * plane addr update event triggers to be synchronized. +- * top_pipe_to_program is expected to never be NULL +- */ ++ // Update Type FAST, Surface updates + if (update_type == UPDATE_TYPE_FAST) { ++ /* Lock the top pipe while updating plane addrs, since freesync requires ++ * plane addr update event triggers to be synchronized. ++ * top_pipe_to_program is expected to never be NULL ++ */ + dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); + + /* Perform requested Updates */ +@@ -1437,21 +1487,6 @@ static void commit_planes_for_stream(struct dc *dc, + + dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); + } +- +- if (stream && stream_update) +- for (j = 0; j < dc->res_pool->pipe_count; j++) { +- struct pipe_ctx *pipe_ctx = +- &context->res_ctx.pipe_ctx[j]; +- +- if (pipe_ctx->stream != stream) +- continue; +- +- if (stream_update->hdr_static_metadata || +- (stream_update->vrr_infopacket)) { +- resource_build_info_frame(pipe_ctx); +- dc->hwss.update_info_frame(pipe_ctx); +- } +- } + } + + void dc_commit_updates_for_stream(struct dc *dc, +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 2c875a9ed832..b8e180f66e6a 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -2462,9 +2462,43 @@ void core_link_enable_stream( + struct pipe_ctx *pipe_ctx) + { + struct dc *core_dc = pipe_ctx->stream->ctx->dc; ++ struct dc_stream_state *stream = pipe_ctx->stream; + enum dc_status status; + DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); + ++ if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) { ++ stream->sink->link->link_enc->funcs->setup( ++ stream->sink->link->link_enc, ++ pipe_ctx->stream->signal); ++ pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync( ++ pipe_ctx->stream_res.stream_enc, ++ pipe_ctx->stream_res.tg->inst, ++ stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE); ++ } ++ ++ if (dc_is_dp_signal(pipe_ctx->stream->signal)) ++ pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( ++ pipe_ctx->stream_res.stream_enc, ++ &stream->timing, ++ stream->output_color_space); ++ ++ if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) ++ pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute( ++ pipe_ctx->stream_res.stream_enc, ++ &stream->timing, ++ stream->phy_pix_clk, ++ pipe_ctx->stream_res.audio != NULL); ++ ++ if (dc_is_dvi_signal(pipe_ctx->stream->signal)) ++ pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute( ++ pipe_ctx->stream_res.stream_enc, ++ &stream->timing, ++ (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? ++ true : false); ++ ++ resource_build_info_frame(pipe_ctx); ++ core_dc->hwss.update_info_frame(pipe_ctx); ++ + /* eDP lit up by bios already, no need to enable again. */ + if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && + core_dc->apply_edp_fast_boot_optimization) { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index 57004028c3f7..15cb5b80c592 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -1615,6 +1615,9 @@ static bool are_stream_backends_same( + if (is_hdr_static_meta_changed(stream_a, stream_b)) + return false; + ++ if (stream_a->dpms_off != stream_b->dpms_off) ++ return false; ++ + return true; + } + +@@ -2716,6 +2719,9 @@ bool pipe_need_reprogram( + if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream)) + return true; + ++ if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off) ++ return true; ++ + return false; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h +index 67101a525e3d..97d2dcf2547c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h +@@ -128,6 +128,8 @@ struct dc_stream_update { + unsigned long long *periodic_fn_vsync_delta; + struct dc_crtc_timing_adjust *adjust; + struct dc_info_packet *vrr_infopacket; ++ ++ bool *dpms_off; + }; + + bool dc_is_stream_unchanged( +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 b4b08dfe0658..d46181b1a3d8 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 +@@ -1349,8 +1349,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( + struct dc *dc) + { + struct dc_stream_state *stream = pipe_ctx->stream; +- struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. +- pipe_ctx[pipe_ctx->pipe_idx]; + + if (pipe_ctx->stream_res.audio != NULL) { + struct audio_output audio_output; +@@ -1405,46 +1403,12 @@ static enum dc_status apply_single_controller_ctx_to_hw( + stream->timing.display_color_depth, + pipe_ctx->stream->signal); + +- if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) +- stream->sink->link->link_enc->funcs->setup( +- stream->sink->link->link_enc, +- pipe_ctx->stream->signal); +- +- if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) +- pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync( +- pipe_ctx->stream_res.stream_enc, +- pipe_ctx->stream_res.tg->inst, +- stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE); +- +- + pipe_ctx->stream_res.opp->funcs->opp_program_fmt( + pipe_ctx->stream_res.opp, + &stream->bit_depth_params, + &stream->clamping); + +- if (dc_is_dp_signal(pipe_ctx->stream->signal)) +- pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( +- pipe_ctx->stream_res.stream_enc, +- &stream->timing, +- stream->output_color_space); +- +- if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) +- pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute( +- pipe_ctx->stream_res.stream_enc, +- &stream->timing, +- stream->phy_pix_clk, +- pipe_ctx->stream_res.audio != NULL); +- +- if (dc_is_dvi_signal(pipe_ctx->stream->signal)) +- pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute( +- pipe_ctx->stream_res.stream_enc, +- &stream->timing, +- (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? +- true : false); +- +- resource_build_info_frame(pipe_ctx); +- dce110_update_info_frame(pipe_ctx); +- if (!pipe_ctx_old->stream) ++ if (!stream->dpms_off) + core_link_enable_stream(context, pipe_ctx); + + pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; +-- +2.17.1 + |