mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
43b9d27360
commit
39b485e4dd
|
@ -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];
|
||||
|
@ -204,34 +205,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;
|
||||
}
|
||||
|
||||
|
@ -255,21 +230,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) ||
|
||||
|
@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position(
|
|||
!pipe_ctx->plane_res.ipp)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, ¶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) {}
|
||||
|
@ -2972,6 +3010,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)
|
||||
|
|
|
@ -1761,6 +1761,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);
|
||||
|
@ -2296,7 +2301,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;
|
||||
|
@ -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)
|
||||
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,
|
||||
|
@ -2362,6 +2401,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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -198,6 +198,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(
|
||||
|
|
Loading…
Reference in New Issue