Commit 39b485e4 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher

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: default avatarEric Yang <Eric.Yang2@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 43b9d273
...@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes( ...@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes(
core_dc = stream->ctx->dc; core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx; res_ctx = &core_dc->current_state->res_ctx;
stream->cursor_attributes = *attributes;
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
...@@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes( ...@@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes(
continue; continue;
if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL) core_dc->hwss.set_cursor_attribute(pipe_ctx);
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);
} }
stream->cursor_attributes = *attributes;
return true; return true;
} }
...@@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position( ...@@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position(
core_dc = stream->ctx->dc; core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx; res_ctx = &core_dc->current_state->res_ctx;
stream->cursor_position = *position;
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[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 || if (pipe_ctx->stream != stream ||
(!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
...@@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position( ...@@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position(
!pipe_ctx->plane_res.ipp) !pipe_ctx->plane_res.ipp)
continue; continue;
if (pipe_ctx->plane_state->address.type core_dc->hwss.set_cursor_position(pipe_ctx);
== 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);
} }
stream->cursor_position = *position;
return true; return true;
} }
......
...@@ -2930,6 +2930,44 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, ...@@ -2930,6 +2930,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 ready_shared_resources(struct dc *dc, struct dc_state *context) {}
static void optimize_shared_resources(struct dc *dc) {} static void optimize_shared_resources(struct dc *dc) {}
...@@ -2972,6 +3010,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { ...@@ -2972,6 +3010,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.edp_backlight_control = hwss_edp_backlight_control, .edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control, .edp_power_control = hwss_edp_power_control,
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, .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) void dce110_hw_sequencer_construct(struct dc *dc)
......
...@@ -1761,6 +1761,11 @@ static void update_dchubp_dpp( ...@@ -1761,6 +1761,11 @@ static void update_dchubp_dpp(
&pipe_ctx->plane_res.scl_data.viewport_c); &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) { if (plane_state->update_flags.bits.full_update) {
/*gamut remap*/ /*gamut remap*/
program_gamut_remap(pipe_ctx); program_gamut_remap(pipe_ctx);
...@@ -2296,7 +2301,7 @@ static bool dcn10_dummy_display_power_gating( ...@@ -2296,7 +2301,7 @@ static bool dcn10_dummy_display_power_gating(
return true; 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 dc_plane_state *plane_state = pipe_ctx->plane_state;
struct timing_generator *tg = pipe_ctx->stream_res.tg; struct timing_generator *tg = pipe_ctx->stream_res.tg;
...@@ -2316,12 +2321,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) ...@@ -2316,12 +2321,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) if (hws->ctx->dc->res_pool->hubbub != NULL)
hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); 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 = { static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap, .program_gamut_remap = program_gamut_remap,
.program_csc_matrix = program_csc_matrix, .program_csc_matrix = program_csc_matrix,
...@@ -2362,6 +2401,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { ...@@ -2362,6 +2401,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.edp_backlight_control = hwss_edp_backlight_control, .edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control, .edp_power_control = hwss_edp_power_control,
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, .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
}; };
......
...@@ -198,6 +198,9 @@ struct hw_sequencer_funcs { ...@@ -198,6 +198,9 @@ struct hw_sequencer_funcs {
bool enable); bool enable);
void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); 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( void color_space_to_black_color(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment