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, ¶m); + 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 = ¶ms->set_cursor_position_params.pos; + const struct dc_cursor_mi_param *param = ¶ms->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, ¶m); + dc->hwss.set_cursor_position(pipe_ctx->plane_res.hubp, + pipe_ctx->plane_res.dpp, &pos, ¶m); + } 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, ¶m); + 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, ¶m); - dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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, ¶m); - dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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
