]> www.infradead.org Git - nvme.git/commitdiff
drm/amd/display: Adjust cursor visibility between MPC slices
authorNevenko Stupar <nevenko.stupar@amd.com>
Wed, 19 Jun 2024 20:08:41 +0000 (16:08 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 1 Jul 2024 20:06:53 +0000 (16:06 -0400)
[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@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Nevenko Stupar <nevenko.stupar@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h

index 11570ef060866e0b8189bdd98568882dcc8bda16..2c50c0f745a0be589c5307a66bcbba9cd0e204ac 100644 (file)
@@ -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;
 
index c1d4287d5a0dd55434d77a24156f82c7b6cba540..8e9c1c17aa6627b517adb1de91337b39a3045462 100644 (file)
@@ -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__ */