diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch new file mode 100644 index 00000000..fc8a493d --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch @@ -0,0 +1,289 @@ +From 33a27a11e963eb1e112b77ac96698fb380b3783d Mon Sep 17 00:00:00 2001 +From: Eric Yang <Eric.Yang2@amd.com> +Date: Thu, 18 Jan 2018 19:07:54 -0500 +Subject: [PATCH 3498/4131] drm/amd/display: fix cursor related Pstate hang + +Move cursor programming to inside the OTG_MASTER_UPDATE_LOCK + +If graphics plane go from 1 pipe to hsplit, the cursor updates +after mpc programming and unlock. Which means there is a window +of time where cursor is enabled on the wrong pipe if it's on +the right side of the screen (i.e. case where cursor need to +move from pipe 0 to pipe 3 post split). This will cause pstate hang. + +Solution is to program the cursor while still locked. + +Signed-off-by: Eric Yang <Eric.Yang2@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@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_stream.c | 68 ++-------------------- + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 40 +++++++++++++ + .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 45 +++++++++++++- + drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 + + 4 files changed, 90 insertions(+), 66 deletions(-) + +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 c3b1988..87a193a 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes( + + core_dc = stream->ctx->dc; + res_ctx = &core_dc->current_state->res_ctx; ++ stream->cursor_attributes = *attributes; + + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; +@@ -203,34 +204,8 @@ bool dc_stream_set_cursor_attributes( + continue; + + +- if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL) +- pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( +- pipe_ctx->plane_res.ipp, attributes); +- +- if (pipe_ctx->plane_res.hubp != NULL && +- pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL) +- pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( +- pipe_ctx->plane_res.hubp, attributes); +- +- if (pipe_ctx->plane_res.mi != NULL && +- pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) +- pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( +- pipe_ctx->plane_res.mi, attributes); +- +- +- if (pipe_ctx->plane_res.xfm != NULL && +- pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) +- pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( +- pipe_ctx->plane_res.xfm, attributes); +- +- if (pipe_ctx->plane_res.dpp != NULL && +- pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL) +- pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( +- pipe_ctx->plane_res.dpp, attributes->color_format); ++ core_dc->hwss.set_cursor_attribute(pipe_ctx); + } +- +- stream->cursor_attributes = *attributes; +- + return true; + } + +@@ -254,21 +229,10 @@ bool dc_stream_set_cursor_position( + + core_dc = stream->ctx->dc; + res_ctx = &core_dc->current_state->res_ctx; ++ stream->cursor_position = *position; + + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; +- struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; +- struct mem_input *mi = pipe_ctx->plane_res.mi; +- struct hubp *hubp = pipe_ctx->plane_res.hubp; +- struct dpp *dpp = pipe_ctx->plane_res.dpp; +- struct dc_cursor_position pos_cpy = *position; +- struct dc_cursor_mi_param param = { +- .pixel_clk_khz = stream->timing.pix_clk_khz, +- .ref_clk_khz = core_dc->res_pool->ref_clock_inKhz, +- .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, +- .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, +- .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz +- }; + + if (pipe_ctx->stream != stream || + (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || +@@ -276,33 +240,9 @@ bool dc_stream_set_cursor_position( + (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) + continue; + +- if (pipe_ctx->plane_state->address.type +- == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) +- pos_cpy.enable = false; +- +- if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) +- pos_cpy.enable = false; +- +- +- if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL) +- ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); +- +- if (mi != NULL && mi->funcs->set_cursor_position != NULL) +- mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); +- +- if (!hubp) +- continue; +- +- if (hubp->funcs->set_cursor_position != NULL) +- hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); +- +- if (dpp != NULL && dpp->funcs->set_cursor_position != NULL) +- dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); +- ++ core_dc->hwss.set_cursor_position(pipe_ctx); + } + +- stream->cursor_position = *position; +- + return true; + } + +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 fbb84a7..914d39e 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 +@@ -2908,6 +2908,44 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, + } + } + ++void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; ++ struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; ++ struct mem_input *mi = pipe_ctx->plane_res.mi; ++ struct dc_cursor_mi_param param = { ++ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, ++ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, ++ .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, ++ .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, ++ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz ++ }; ++ ++ if (pipe_ctx->plane_state->address.type ++ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) ++ pos_cpy.enable = false; ++ ++ if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) ++ pos_cpy.enable = false; ++ ++ ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); ++ mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); ++} ++ ++void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; ++ ++ pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( ++ pipe_ctx->plane_res.ipp, attributes); ++ ++ pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( ++ pipe_ctx->plane_res.mi, attributes); ++ ++ pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( ++ pipe_ctx->plane_res.xfm, attributes); ++} ++ + static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} + + static void optimize_shared_resources(struct dc *dc) {} +@@ -2951,6 +2989,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .edp_backlight_control = hwss_edp_backlight_control, + .edp_power_control = hwss_edp_power_control, + .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, ++ .set_cursor_position = dce110_set_cursor_position, ++ .set_cursor_attribute = dce110_set_cursor_attribute + }; + + void dce110_hw_sequencer_construct(struct dc *dc) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index e6f8227..a17b0b7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -1716,6 +1716,11 @@ static void update_dchubp_dpp( + &pipe_ctx->plane_res.scl_data.viewport_c); + } + ++ if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) { ++ dc->hwss.set_cursor_position(pipe_ctx); ++ dc->hwss.set_cursor_attribute(pipe_ctx); ++ } ++ + if (plane_state->update_flags.bits.full_update) { + /*gamut remap*/ + program_gamut_remap(pipe_ctx); +@@ -2265,7 +2270,7 @@ static bool dcn10_dummy_display_power_gating( + return true; + } + +-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) ++static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) + { + struct dc_plane_state *plane_state = pipe_ctx->plane_state; + struct timing_generator *tg = pipe_ctx->stream_res.tg; +@@ -2285,12 +2290,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) + } + } + +-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) ++static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) + { + if (hws->ctx->dc->res_pool->hubbub != NULL) + hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); + } + ++static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; ++ struct hubp *hubp = pipe_ctx->plane_res.hubp; ++ struct dpp *dpp = pipe_ctx->plane_res.dpp; ++ struct dc_cursor_mi_param param = { ++ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, ++ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, ++ .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, ++ .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, ++ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz ++ }; ++ ++ if (pipe_ctx->plane_state->address.type ++ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) ++ pos_cpy.enable = false; ++ ++ if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) ++ pos_cpy.enable = false; ++ ++ hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); ++ dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); ++} ++ ++static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; ++ ++ pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( ++ pipe_ctx->plane_res.hubp, attributes); ++ pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( ++ pipe_ctx->plane_res.dpp, attributes->color_format); ++} ++ + static const struct hw_sequencer_funcs dcn10_funcs = { + .program_gamut_remap = program_gamut_remap, + .program_csc_matrix = program_csc_matrix, +@@ -2332,6 +2371,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .edp_backlight_control = hwss_edp_backlight_control, + .edp_power_control = hwss_edp_power_control, + .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, ++ .set_cursor_position = dcn10_set_cursor_position, ++ .set_cursor_attribute = dcn10_set_cursor_attribute + }; + + +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 5e9a593..ad956ae 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -199,6 +199,9 @@ struct hw_sequencer_funcs { + bool enable); + void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); + ++ void (*set_cursor_position)(struct pipe_ctx *pipe); ++ void (*set_cursor_attribute)(struct pipe_ctx *pipe); ++ + }; + + void color_space_to_black_color( +-- +2.7.4 + |