aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c47
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h1
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__ */