From: Nevenko Stupar <nevenko.stupar@xxxxxxx> [Why & How] When MPC enabled, need to adjust x and hot spot x position on one pipe when the cursor is between MPC slices i.e. when the cursor is moving from one MPC slice to next slice, while whole cursor size is not contained within one pipe, to make part of the cursor to be visible on the other pipe. Reviewed-by: Sridevi Arvindekar <sridevi.arvindekar@xxxxxxx> Signed-off-by: Jerry Zuo <jerry.zuo@xxxxxxx> Signed-off-by: Nevenko Stupar <nevenko.stupar@xxxxxxx> --- .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 47 +++++++++++++++---- .../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 1 + 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 11570ef06086..2c50c0f745a0 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -1088,6 +1088,17 @@ static bool dcn401_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) return false; } +void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, struct dc_cursor_position *pos_cpy) +{ + if (cursor_width <= 128) { + pos_cpy->x_hotspot /= 2; + pos_cpy->x_hotspot += 1; + } else { + pos_cpy->x_hotspot /= 2; + pos_cpy->x_hotspot += 2; + } +} + void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) { struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; @@ -1109,12 +1120,21 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) int prev_odm_width = 0; int prev_odm_offset = 0; struct pipe_ctx *prev_odm_pipe = NULL; + bool mpc_combine_on = false; + int bottom_pipe_x_pos = 0; int x_pos = pos_cpy.x; int y_pos = pos_cpy.y; int recout_x_pos = 0; int recout_y_pos = 0; + if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) { + if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) || + (pipe_ctx->plane_state->src_rect.height != pipe_ctx->plane_res.scl_data.viewport.height)) { + mpc_combine_on = true; + } + } + /* DCN4 moved cursor composition after Scaler, so in HW it is in * recout space and for HW Cursor position programming need to * translate to recout space. @@ -1177,15 +1197,8 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) if (x_pos < 0) { pos_cpy.x_hotspot -= x_pos; - if ((odm_combine_on) && (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION)) { - if (hubp->curs_attr.width <= 128) { - pos_cpy.x_hotspot /= 2; - pos_cpy.x_hotspot += 1; - } else { - pos_cpy.x_hotspot /= 2; - pos_cpy.x_hotspot += 2; - } - } + if (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION) + adjust_hotspot_between_slices_for_2x_magnify(hubp->curs_attr.width, &pos_cpy); x_pos = 0; } @@ -1194,6 +1207,22 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) y_pos = 0; } + /* If the position on bottom MPC pipe is negative then we need to add to the hotspot and + * adjust x_pos on bottom pipe to make cursor visible when crossing between MPC slices. + */ + if (mpc_combine_on && + pipe_ctx->top_pipe && + (pipe_ctx == pipe_ctx->top_pipe->bottom_pipe)) { + + bottom_pipe_x_pos = x_pos - pipe_ctx->plane_res.scl_data.recout.x; + if (bottom_pipe_x_pos < 0) { + x_pos = pipe_ctx->plane_res.scl_data.recout.x; + pos_cpy.x_hotspot -= bottom_pipe_x_pos; + if (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION) + adjust_hotspot_between_slices_for_2x_magnify(hubp->curs_attr.width, &pos_cpy); + } + } + pos_cpy.x = (uint32_t)x_pos; pos_cpy.y = (uint32_t)y_pos; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h index c1d4287d5a0d..8e9c1c17aa66 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h @@ -80,4 +80,5 @@ void dcn401_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *l void dcn401_hardware_release(struct dc *dc); void dcn401_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *otg_master); +void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, struct dc_cursor_position *pos_cpy); #endif /* __DC_HWSS_DCN401_H__ */ -- 2.34.1