aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3498-drm-amd-display-fix-cursor-related-Pstate-hang.patch
diff options
context:
space:
mode:
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.patch289
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, &param);
+-
+- if (mi != NULL && mi->funcs->set_cursor_position != NULL)
+- mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+-
+- if (!hubp)
+- continue;
+-
+- if (hubp->funcs->set_cursor_position != NULL)
+- hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+-
+- if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
+- dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 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, &param);
++ mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
++}
++
++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, &param);
++ dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 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
+