From: Rafal Ostrowski <[email protected]>

Flatten the executor params for the initial set of HWSS block sequence ops
for SET_CURSOR_POSITION to separate SW and HW logic

Reviewed-by: Alvin Lee <[email protected]>
Signed-off-by: Rafal Ostrowski <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 .../drm/amd/display/dc/core/dc_hw_sequencer.c | 52 +++++++++++++--
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  2 +-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |  3 +
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.c  | 51 ++------------
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  2 +-
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c   | 20 ++++--
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h   |  7 +-
 .../amd/display/dc/hwss/dcn10/dcn10_init.c    |  1 +
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  2 +-
 .../amd/display/dc/hwss/dcn20/dcn20_init.c    |  1 +
 .../amd/display/dc/hwss/dcn201/dcn201_init.c  |  1 +
 .../amd/display/dc/hwss/dcn21/dcn21_init.c    |  1 +
 .../amd/display/dc/hwss/dcn30/dcn30_init.c    |  1 +
 .../amd/display/dc/hwss/dcn301/dcn301_init.c  |  1 +
 .../amd/display/dc/hwss/dcn31/dcn31_init.c    |  1 +
 .../amd/display/dc/hwss/dcn314/dcn314_init.c  |  1 +
 .../amd/display/dc/hwss/dcn32/dcn32_init.c    |  1 +
 .../amd/display/dc/hwss/dcn35/dcn35_init.c    |  1 +
 .../amd/display/dc/hwss/dcn351/dcn351_init.c  |  1 +
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 66 +++++++++++++++++--
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.h |  7 +-
 .../amd/display/dc/hwss/dcn401/dcn401_init.c  |  1 +
 .../amd/display/dc/hwss/dcn42/dcn42_init.c    |  1 +
 .../amd/display/dc/hwss/dcn50/dcn50_hwseq.c   |  2 +-
 .../amd/display/dc/hwss/dcn60/dcn60_init.c    |  1 +
 .../drm/amd/display/dc/hwss/hw_sequencer.h    | 13 +++-
 .../display/dc/hwss/hw_sequencer_private.h    |  3 +
 27 files changed, 172 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index f33562dff6ac..3bc0362d9dc0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -1304,7 +1304,8 @@ void hwss_build_fast_sequence(struct dc *dc,
        bool enable_cursor_offload = false;
 
        if ((dc->hwss.set_cursor_attribute && 
stream->update_flags.bits.cursor_attr) ||
-               (dc->hwss.set_cursor_position && 
stream->update_flags.bits.cursor_pos))
+               (dc->hwseq && dc->hwseq->funcs.build_cursor_position &&
+                       dc->hwss.set_cursor_position && 
stream->update_flags.bits.cursor_pos))
                enable_cursor_offload = 
dc_dmub_srv_is_cursor_offload_enabled(dc);
 
        /* Cursor attribute updates - separate lock/iterate/unlock */
@@ -1390,7 +1391,8 @@ void hwss_build_fast_sequence(struct dc *dc,
        }
 
        /* Cursor position updates */
-       if (dc->hwss.set_cursor_position && 
stream->update_flags.bits.cursor_pos) {
+       if (dc->hwseq && dc->hwseq->funcs.build_cursor_position &&
+                       dc->hwss.set_cursor_position && 
stream->update_flags.bits.cursor_pos) {
                struct pipe_ctx *cursor_pipe_to_program = NULL;
 
                for (i = 0; i < MAX_PIPES; i++) {
@@ -1417,8 +1419,16 @@ void hwss_build_fast_sequence(struct dc *dc,
                                }
                        }
 
+                       struct dc_cursor_position pos;
+                       struct dc_cursor_mi_param param;
+
+                       dc->hwseq->funcs.build_cursor_position(current_pipe, 
&pos, &param);
+
                        
block_sequence[*num_steps].params.set_cursor_position_params.dc = dc;
-                       
block_sequence[*num_steps].params.set_cursor_position_params.pipe_ctx = 
current_pipe;
+                       
block_sequence[*num_steps].params.set_cursor_position_params.hubp = 
current_pipe->plane_res.hubp;
+                       
block_sequence[*num_steps].params.set_cursor_position_params.dpp = 
current_pipe->plane_res.dpp;
+                       
block_sequence[*num_steps].params.set_cursor_position_params.pos = pos;
+                       
block_sequence[*num_steps].params.set_cursor_position_params.param = param;
                        block_sequence[*num_steps].func = SET_CURSOR_POSITION;
                        (*num_steps)++;
 
@@ -4357,10 +4367,28 @@ void hwss_dpp_set_cursor_attributes(union 
block_sequence_params *params)
 void hwss_set_cursor_position(union block_sequence_params *params)
 {
        struct dc *dc = params->set_cursor_position_params.dc;
-       struct pipe_ctx *pipe_ctx = params->set_cursor_position_params.pipe_ctx;
+       struct hubp *hubp = params->set_cursor_position_params.hubp;
+       struct dpp *dpp = params->set_cursor_position_params.dpp;
+       const struct dc_cursor_position *pos = 
&params->set_cursor_position_params.pos;
+       const struct dc_cursor_mi_param *param = 
&params->set_cursor_position_params.param;
 
+       /* DCN path: SW logic ran in the builder; just invoke the BLCs */
        if (dc && dc->hwss.set_cursor_position)
-               dc->hwss.set_cursor_position(pipe_ctx);
+               dc->hwss.set_cursor_position(hubp, dpp, pos, param);
+}
+
+void hwss_program_cursor_position(struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+       if (dc->hwseq && dc->hwseq->funcs.build_cursor_position && 
dc->hwss.set_cursor_position) {
+               struct dc_cursor_position pos;
+               struct dc_cursor_mi_param param;
+
+               dc->hwseq->funcs.build_cursor_position(pipe_ctx, &pos, &param);
+               dc->hwss.set_cursor_position(pipe_ctx->plane_res.hubp,
+                               pipe_ctx->plane_res.dpp, &pos, &param);
+       } else if (dc->hwss.set_cursor_position_legacy) {
+               dc->hwss.set_cursor_position_legacy(pipe_ctx);
+       }
 }
 
 void hwss_set_cursor_sdr_white_level(union block_sequence_params *params)
@@ -5783,10 +5811,20 @@ void hwss_add_set_cursor_position(struct 
block_sequence_state *seq_state,
                struct dc *dc,
                struct pipe_ctx *pipe_ctx)
 {
-       if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
+       if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE &&
+                       dc->hwseq && dc->hwseq->funcs.build_cursor_position &&
+                       dc->hwss.set_cursor_position) {
+               struct dc_cursor_position pos;
+               struct dc_cursor_mi_param param;
+
+               dc->hwseq->funcs.build_cursor_position(pipe_ctx, &pos, &param);
+
                seq_state->steps[*seq_state->num_steps].func = 
SET_CURSOR_POSITION;
                
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.dc = 
dc;
-               
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.pipe_ctx
 = pipe_ctx;
+               
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.hubp 
= pipe_ctx->plane_res.hubp;
+               
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.dpp = 
pipe_ctx->plane_res.dpp;
+               
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.pos = 
pos;
+               
seq_state->steps[*seq_state->num_steps].params.set_cursor_position_params.param 
= param;
                (*seq_state->num_steps)++;
        }
 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 88ac4a4cfd6e..b446c311e662 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -530,7 +530,7 @@ void program_cursor_position(
                        }
                }
 
-               dc->hwss.set_cursor_position(pipe_ctx);
+               hwss_program_cursor_position(dc, pipe_ctx);
                if (enable_cursor_offload && 
dc->hwss.update_cursor_offload_pipe) {
                        struct pipe_ctx *top_pipe = 
resource_get_otg_master(pipe_ctx);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 084c506a8a94..40cd4e5d1340 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -562,6 +562,9 @@ struct dc_cursor_mi_param {
        enum dc_rotation_angle rotation;
        bool mirror;
        struct dc_stream_state *stream;
+       int dst_x_offset;
+       int cur_rect_x;
+       int cur_rect_y;
 };
 
 /* IPP related types */
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index 5ca40941c355..a985c3e00dca 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -816,24 +816,9 @@ void hubp401_cursor_set_position(
        const struct dc_cursor_mi_param *param)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-       int rec_x_offset = pos->x - pos->x_hotspot;
-       int rec_y_offset = pos->y - pos->y_hotspot;
-       int dst_x_offset;
-       int x_pos_viewport = 0;
-       int x_hot_viewport = 0;
+       int dst_x_offset = param->dst_x_offset;
        uint32_t cur_en = pos->enable ? 1 : 0;
-       uint32_t x_hotspot_clamped = pos->x_hotspot;
        hubp->curs_pos = *pos;
-       /* Recout is zero for pipes if the entire dst_rect is contained
-        * within preceeding ODM slices.
-        */
-       if (param->recout.width) {
-               x_pos_viewport = pos->x * param->viewport.width / 
param->recout.width;
-               x_hot_viewport = pos->x_hotspot * param->viewport.width / 
param->recout.width;
-       } else {
-               ASSERT(!cur_en || pos->x == 0);
-               ASSERT(!cur_en || pos->x_hotspot == 0);
-       }
 
        /*
         * Guard aganst cursor_set_position() from being called with invalid
@@ -842,25 +827,6 @@ void hubp401_cursor_set_position(
        if (hubp->curs_attr.address.quad_part == 0)
                return;
 
-       /* Translate the x position of the cursor from rect
-        * space into viewport space. CURSOR_DST_X_OFFSET
-        * is the offset relative to viewport start position.
-        */
-       dst_x_offset = x_pos_viewport - x_hot_viewport *
-                       (1 + 
hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION);
-       dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0;
-       dst_x_offset *= param->ref_clk_khz;
-       dst_x_offset /= param->pixel_clk_khz;
-
-       ASSERT(param->h_scale_ratio.value);
-
-       if (x_hotspot_clamped > 0xFF)
-               x_hotspot_clamped = 0xFF;
-       if (param->h_scale_ratio.value)
-               dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
-                       dc_fixpt_from_int(dst_x_offset),
-                       param->h_scale_ratio));
-
        if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) {
                if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
                        hubp->funcs->set_cursor_attributes(hubp, 
&hubp->curs_attr);
@@ -876,7 +842,7 @@ void hubp401_cursor_set_position(
                        CURSOR_Y_POSITION, pos->y);
 
                REG_SET_2(CURSOR_HOT_SPOT, 0,
-                       CURSOR_HOT_SPOT_X, x_hotspot_clamped,
+                       CURSOR_HOT_SPOT_X, pos->x_hotspot,
                        CURSOR_HOT_SPOT_Y, pos->y_hotspot);
 
                REG_SET(CURSOR_DST_OFFSET, 0,
@@ -889,18 +855,9 @@ void hubp401_cursor_set_position(
        hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot;
        hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot;
        hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset;
-       /* Cursor Rectangle Cache
-        * Cursor bitmaps have different hotspot values
-        * There's a possibility that the above logic returns a negative value,
-        * so we clamp them to 0
-        */
-       if (rec_x_offset < 0)
-               rec_x_offset = 0;
-       if (rec_y_offset < 0)
-               rec_y_offset = 0;
        /* Save necessary cursor info x, y position. w, h is saved in attribute 
func. */
-       hubp->cur_rect.x = rec_x_offset + param->recout.x;
-       hubp->cur_rect.y = rec_y_offset + param->recout.y;
+       hubp->cur_rect.x = param->cur_rect_x;
+       hubp->cur_rect.y = param->cur_rect_y;
 }
 
 void hubp401_read_state(struct hubp *hubp)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index bb46d7249025..d48894017c0e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -3655,7 +3655,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
        .edp_backlight_control = dce110_edp_backlight_control,
        .edp_power_control = dce110_edp_power_control,
        .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
-       .set_cursor_position = dce110_set_cursor_position,
+       .set_cursor_position_legacy = dce110_set_cursor_position,
        .set_cursor_attribute = dce110_set_cursor_attribute,
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 84e146f2509c..613f1f62cd80 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -3176,7 +3176,7 @@ static void dcn10_update_dchubp_dpp(
                }
 
                dc->hwss.set_cursor_attribute(pipe_ctx);
-               dc->hwss.set_cursor_position(pipe_ctx);
+               hwss_program_cursor_position(dc, pipe_ctx);
 
                if (dc->hwss.set_cursor_sdr_white_level)
                        dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
@@ -3729,11 +3729,11 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct 
dchub_init_data *dh_data)
        hubbub->funcs->update_dchub(hubbub, dh_data);
 }
 
-void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+void dcn10_build_cursor_position(struct pipe_ctx *pipe_ctx,
+               struct dc_cursor_position *pos_out,
+               struct dc_cursor_mi_param *param_out)
 {
        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_100hz / 10,
                .ref_clk_khz = 
pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz,
@@ -3949,8 +3949,16 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                        pipe_ctx->plane_res.scl_data.viewport.height - 
pos_cpy.y;
        }
 
-       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 
hubp->curs_attr.width, hubp->curs_attr.height);
+       *pos_out = pos_cpy;
+       *param_out = param;
+}
+
+void dcn10_set_cursor_position(struct hubp *hubp, struct dpp *dpp,
+               const struct dc_cursor_position *pos,
+               const struct dc_cursor_mi_param *param)
+{
+       hubp->funcs->set_cursor_position(hubp, pos, param);
+       dpp->funcs->set_cursor_position(dpp, pos, param, hubp->curs_attr.width, 
hubp->curs_attr.height);
 }
 
 void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
index 5cb109040d3d..9c4f1186ca9f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.h
@@ -177,7 +177,12 @@ void dce110_edp_power_control(
 void dce110_edp_wait_for_hpd_ready(
                struct dc_link *link,
                bool power_up);
-void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx);
+void dcn10_build_cursor_position(struct pipe_ctx *pipe_ctx,
+               struct dc_cursor_position *pos,
+               struct dc_cursor_mi_param *param);
+void dcn10_set_cursor_position(struct hubp *hubp, struct dpp *dpp,
+               const struct dc_cursor_position *pos,
+               const struct dc_cursor_mi_param *param);
 void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
 void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
 void dcn10_setup_periodic_interrupt(
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
index 07e92742c11a..ddd52722bc49 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_init.c
@@ -94,6 +94,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn10_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .program_pipe = dcn10_program_pipe,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index e7ca38bcaabf..45a4a7707507 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -1846,7 +1846,7 @@ void dcn20_update_dchubp_dpp(
                }
 
                dc->hwss.set_cursor_attribute(pipe_ctx);
-               dc->hwss.set_cursor_position(pipe_ctx);
+               hwss_program_cursor_position(dc, pipe_ctx);
 
                if (dc->hwss.set_cursor_sdr_white_level)
                        dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
index c4de9cf11c23..5817fb44d2e0 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_init.c
@@ -107,6 +107,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn20_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
index be1fb2366c8a..d421bc813cbd 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_init.c
@@ -99,6 +99,7 @@ static const struct hw_sequencer_funcs dcn201_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn201_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = NULL,
        .plane_atomic_disconnect = dcn201_plane_atomic_disconnect,
        .program_pipe = dcn10_program_pipe,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
index 20c6e7d7c897..e691e86629c5 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_init.c
@@ -110,6 +110,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn21_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
index f62f1c6efff8..f7a095796039 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
@@ -117,6 +117,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn30_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
index a62434138eca..191245bde1ca 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
@@ -113,6 +113,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn301_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
index 30ad41d08d6e..5500eb46dedb 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c
@@ -119,6 +119,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn31_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
index a53e7fb6f23f..b278f58b844d 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c
@@ -122,6 +122,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn314_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
index 7e68029f1e12..49387de29382 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
@@ -130,6 +130,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
index 69fa91aeb836..e4864b9606ff 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
@@ -140,6 +140,7 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn35_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn35_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
index 3ceaa4590148..f57c0f6adccf 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
@@ -129,6 +129,7 @@ static const struct hw_sequencer_funcs dcn351_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn351_private_funcs = {
+       .build_cursor_position = dcn10_build_cursor_position,
        .init_pipes = dcn35_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn20_update_mpcc,
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 3dd3dacfe5ee..8fd60ed7669b 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
@@ -1045,11 +1045,12 @@ void dcn401_disable_link_output(struct dc_link *link,
        dc->link_srv->dp_trace_source_sequence(link, 
DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 }
 
-void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
+void dcn401_build_cursor_position(struct pipe_ctx *pipe_ctx,
+               struct dc_cursor_position *pos_out,
+               struct dc_cursor_mi_param *param_out)
 {
        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_100hz / 10,
                .ref_clk_khz = 
pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz,
@@ -1073,6 +1074,11 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
        int y_pos = pos_cpy.y;
        int recout_x_pos = 0;
        int recout_y_pos = 0;
+       int x_pos_viewport = 0;
+       int x_hot_viewport = 0;
+       int dst_x_offset = 0;
+       int rec_x_offset = 0;
+       int rec_y_offset = 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) ||
@@ -1215,8 +1221,60 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
        pos_cpy.x = x_pos;
        pos_cpy.y = y_pos;
 
-       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 
hubp->curs_attr.width, hubp->curs_attr.height);
+       /* Precompute the HW destination offset so the executor only programs
+        * registers. Translate cursor x position from rect space into viewport
+        * space; CURSOR_DST_X_OFFSET is relative to the viewport start 
position.
+        */
+       if (param.recout.width) {
+               x_pos_viewport = pos_cpy.x * param.viewport.width / 
param.recout.width;
+               x_hot_viewport = pos_cpy.x_hotspot * param.viewport.width / 
param.recout.width;
+       } else {
+               ASSERT(!pos_cpy.enable || pos_cpy.x == 0);
+               ASSERT(!pos_cpy.enable || pos_cpy.x_hotspot == 0);
+       }
+
+       dst_x_offset = x_pos_viewport - x_hot_viewport *
+                       (1 + 
hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION);
+       dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0;
+       dst_x_offset *= param.ref_clk_khz;
+       dst_x_offset /= param.pixel_clk_khz;
+
+       ASSERT(param.h_scale_ratio.value);
+
+       if (param.h_scale_ratio.value)
+               dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
+                       dc_fixpt_from_int(dst_x_offset),
+                       param.h_scale_ratio));
+
+       param.dst_x_offset = dst_x_offset;
+
+       /* Cursor rectangle cache origin: derived from the final cursor position
+        * minus hotspot, clamped to 0, offset by the recout origin. Precompute
+        * here so the executor only stores the value.
+        */
+       rec_x_offset = pos_cpy.x - pos_cpy.x_hotspot;
+       rec_y_offset = pos_cpy.y - pos_cpy.y_hotspot;
+       if (rec_x_offset < 0)
+               rec_x_offset = 0;
+       if (rec_y_offset < 0)
+               rec_y_offset = 0;
+       param.cur_rect_x = rec_x_offset + param.recout.x;
+       param.cur_rect_y = rec_y_offset + param.recout.y;
+
+       /* Clamp hotspot to the CURSOR_HOT_SPOT_X register field width */
+       if (pos_cpy.x_hotspot > 0xFF)
+               pos_cpy.x_hotspot = 0xFF;
+
+       *pos_out = pos_cpy;
+       *param_out = param;
+}
+
+void dcn401_set_cursor_position(struct hubp *hubp, struct dpp *dpp,
+               const struct dc_cursor_position *pos,
+               const struct dc_cursor_mi_param *param)
+{
+       hubp->funcs->set_cursor_position(hubp, pos, param);
+       dpp->funcs->set_cursor_position(dpp, pos, param, hubp->curs_attr.width, 
hubp->curs_attr.height);
 }
 
 static bool dcn401_check_no_memory_request_for_cab(struct dc *dc)
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 43bea09fb205..f958ea34a3c6 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
@@ -55,7 +55,12 @@ void dcn401_disable_link_output(struct dc_link *link,
                const struct link_resource *link_res,
                enum signal_type signal);
 
-void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx);
+void dcn401_build_cursor_position(struct pipe_ctx *pipe_ctx,
+               struct dc_cursor_position *pos,
+               struct dc_cursor_mi_param *param);
+void dcn401_set_cursor_position(struct hubp *hubp, struct dpp *dpp,
+               const struct dc_cursor_position *pos,
+               const struct dc_cursor_mi_param *param);
 
 bool dcn401_apply_idle_power_optimizations(struct dc *dc, bool enable);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index 5ac79c32ee48..ac5ebe546d0c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -125,6 +125,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn401_private_funcs = {
+       .build_cursor_position = dcn401_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .plane_atomic_disconnect_sequence = 
dcn401_plane_atomic_disconnect_sequence,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
index faeb365dbcab..eba34f124e39 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
@@ -129,6 +129,7 @@ static const struct hw_sequencer_funcs dcn42_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn42_private_funcs = {
+       .build_cursor_position = dcn401_build_cursor_position,
        .init_pipes = dcn35_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .update_mpcc = dcn42_update_mpcc,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn50/dcn50_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn50/dcn50_hwseq.c
index f1c044fe0ba2..0361c520b7d9 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn50/dcn50_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn50/dcn50_hwseq.c
@@ -212,7 +212,7 @@ void dcn50_update_dchubp_dpp(
                }
 
                dc->hwss.set_cursor_attribute(pipe_ctx);
-               dc->hwss.set_cursor_position(pipe_ctx);
+               hwss_program_cursor_position(dc, pipe_ctx);
 
                if (dc->hwss.set_cursor_sdr_white_level)
                        dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
index 4aaecd6f8bb7..ce0905820f7e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_init.c
@@ -128,6 +128,7 @@ static const struct hw_sequencer_funcs dcn60_funcs = {
 };
 
 static const struct hwseq_private_funcs dcn60_private_funcs = {
+       .build_cursor_position = dcn401_build_cursor_position,
        .init_pipes = dcn10_init_pipes,
        .plane_atomic_disconnect = dcn10_plane_atomic_disconnect,
        .plane_atomic_disconnect_sequence = 
dcn401_plane_atomic_disconnect_sequence,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h 
b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index c902a28b3220..7c5f88bf44c7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -874,7 +874,10 @@ struct dpp_set_cursor_attributes_params {
 
 struct set_cursor_position_params {
        struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
+       struct hubp *hubp;
+       struct dpp *dpp;
+       struct dc_cursor_position pos;
+       struct dc_cursor_mi_param param;
 };
 
 struct set_cursor_sdr_white_level_params {
@@ -1539,7 +1542,11 @@ struct hw_sequencer_funcs {
        bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
 
        /* Cursor Related */
-       void (*set_cursor_position)(struct pipe_ctx *pipe);
+       void (*set_cursor_position)(struct hubp *hubp, struct dpp *dpp,
+                       const struct dc_cursor_position *pos,
+                       const struct dc_cursor_mi_param *param);
+       /* Fallback for DCE */
+       void (*set_cursor_position_legacy)(struct pipe_ctx *pipe);
        void (*set_cursor_attribute)(struct pipe_ctx *pipe);
        void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe);
        void (*abort_cursor_offload_update)(struct dmub_srv *dmub, struct dpp 
*dpp,
@@ -2152,6 +2159,8 @@ void hwss_dpp_set_cursor_attributes(union 
block_sequence_params *params);
 
 void hwss_set_cursor_position(union block_sequence_params *params);
 
+void hwss_program_cursor_position(struct dc *dc, struct pipe_ctx *pipe_ctx);
+
 void hwss_set_cursor_sdr_white_level(union block_sequence_params *params);
 
 void hwss_program_gamut_remap(struct pipe_ctx *pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h 
b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
index b6932b9bc206..136c2c2eab1c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h
@@ -229,6 +229,9 @@ struct hwseq_private_funcs {
        void (*program_cm_hist)(struct dc *dc,
                struct pipe_ctx *pipe_ctx,
                const struct dc_plane_state *plane_state);
+       void (*build_cursor_position)(struct pipe_ctx *pipe_ctx,
+               struct dc_cursor_position *pos,
+               struct dc_cursor_mi_param *param);
 };
 
 struct dce_hwseq {
-- 
2.55.0

Reply via email to