From: Tomasz Siemek <[email protected]>

[why]
Periodic interrupt line calculations depends on stream and pipe state, not
ASIC-specific register programming. Keeping it in the DCN10 implementation
also prevents block-sequence callers from carrying fully resolved
parameters.
We want HWSS block parameters to not include complex structures like
pipe_ctx.

[how]
- Move the vertical interrupt line calculation into common HWSS code.
- Update the periodic interrupt callback.
- Calculate the values before direct or block-sequence execution.

Reviewed-by: Alvin Lee <[email protected]>
Signed-off-by: Tomasz Siemek <[email protected]>
Signed-off-by: James Lin <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  4 +-
 .../drm/amd/display/dc/core/dc_hw_sequencer.c | 76 ++++++++++++++++---
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c   | 41 +---------
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.h   |  5 +-
 .../drm/amd/display/dc/hwss/hw_sequencer.h    | 12 +--
 5 files changed, 83 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 68f228014305..bc2207d29954 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4367,8 +4367,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
 
                if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && 
pipe_ctx->stream == stream) {
 
-                       if (stream_update->periodic_interrupt && 
dc->hwss.setup_periodic_interrupt)
-                               dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+                       if (stream_update->periodic_interrupt)
+                               hwss_setup_periodic_interrupt(dc, pipe_ctx);
 
                        if ((stream_update->hdr_static_metadata && 
!stream->use_dynamic_meta) ||
                                        stream_update->vrr_infopacket ||
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 90d754d192f1..bfb598a22c26 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
@@ -745,6 +745,38 @@ static bool get_update_dchubp_dpp_flags_status(struct 
pipe_ctx *pipe)
        return false;
 }
 
+static void calc_vline_position(
+               struct dc *dc,
+               struct pipe_ctx *pipe_ctx,
+               uint32_t *start_line,
+               uint32_t *end_line)
+{
+       if (!dc->hwss.get_vupdate_offset_from_vsync)
+               return;
+
+       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+       int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
+
+       if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
+               if (vline_pos > 0)
+                       vline_pos--;
+               else if (vline_pos < 0)
+                       vline_pos++;
+
+               vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+               if (vline_pos >= 0)
+                       *start_line = vline_pos - ((vline_pos / 
timing->v_total) * timing->v_total);
+               else
+                       *start_line = vline_pos + ((-vline_pos / 
timing->v_total) + 1) * timing->v_total - 1;
+               *end_line = (*start_line + 2) % timing->v_total;
+       } else if (pipe_ctx->stream->periodic_interrupt.ref_point == 
START_V_SYNC) {
+               // vsync is line 0 so start_line is just the requested line 
offset
+               *start_line = vline_pos;
+               *end_line = (*start_line + 2) % timing->v_total;
+       } else
+               ASSERT(0);
+}
+
 // Function to check if any update flags are set
 static bool get_pipe_update_bits_status(struct pipe_ctx *pipe, struct 
dc_plane_state *plane, struct dc_stream_state *stream)
 {
@@ -1173,8 +1205,16 @@ void hwss_build_fast_sequence(struct dc *dc,
        }
 
        if (dc->hwss.setup_periodic_interrupt && 
stream->update_flags.bits.periodic_interrupt) {
-               
block_sequence[*num_steps].params.setup_periodic_interrupt_params.dc = dc;
-               
block_sequence[*num_steps].params.setup_periodic_interrupt_params.pipe_ctx = 
pipe_ctx;
+               uint32_t start_line = 0;
+               uint32_t end_line = 0;
+
+               calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
+               
block_sequence[*num_steps].params.setup_periodic_interrupt_params.tg =
+                               pipe_ctx->stream_res.tg;
+               
block_sequence[*num_steps].params.setup_periodic_interrupt_params.start_line =
+                               start_line;
+               
block_sequence[*num_steps].params.setup_periodic_interrupt_params.end_line =
+                               end_line;
                block_sequence[*num_steps].func = HWSS_SETUP_PERIODIC_INTERRUPT;
                (*num_steps)++;
        }
@@ -1668,7 +1708,11 @@ void hwss_execute_sequence(struct dc *dc,
                        hwss_tg_setup_vertical_interrupt0(params);
                        break;
                case HWSS_SETUP_PERIODIC_INTERRUPT:
-                       hwss_setup_periodic_interrupt(dc, params);
+                       if (dc->hwss.setup_periodic_interrupt)
+                               dc->hwss.setup_periodic_interrupt(
+                                               
params->setup_periodic_interrupt_params.tg,
+                                               
params->setup_periodic_interrupt_params.start_line,
+                                               
params->setup_periodic_interrupt_params.end_line);
                        break;
                case HWSS_UPDATE_INFO_FRAME:
                        hwss_update_info_frame(dc, params);
@@ -3322,12 +3366,18 @@ void hwss_update_info_frame(struct dc *dc, union 
block_sequence_params *params)
                dc->hwss.update_info_frame(pipe_ctx);
 }
 
-void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params 
*params)
+void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
 {
-       struct pipe_ctx *pipe_ctx = 
params->setup_periodic_interrupt_params.pipe_ctx;
+       uint32_t start_line = 0;
+       uint32_t end_line = 0;
 
-       if (dc->hwss.setup_periodic_interrupt)
-               dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+       if (dc->hwss.setup_periodic_interrupt) {
+               calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
+               dc->hwss.setup_periodic_interrupt(
+                               pipe_ctx->stream_res.tg,
+                               start_line,
+                               end_line);
+       }
 }
 
 void hwss_tg_setup_vertical_interrupt0(union block_sequence_params *params)
@@ -5934,9 +5984,17 @@ void hwss_add_setup_periodic_interrupt(struct 
block_sequence_state *seq_state,
                struct pipe_ctx *pipe_ctx)
 {
        if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
+               uint32_t start_line = 0;
+               uint32_t end_line = 0;
+
+               calc_vline_position(dc, pipe_ctx, &start_line, &end_line);
                seq_state->steps[*seq_state->num_steps].func = 
HWSS_SETUP_PERIODIC_INTERRUPT;
-               
seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.dc
 = dc;
-               
seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.pipe_ctx
 = pipe_ctx;
+               
seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.tg
 =
+                               pipe_ctx->stream_res.tg;
+               
seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.start_line
 =
+                               start_line;
+               
seq_state->steps[*seq_state->num_steps].params.setup_periodic_interrupt_params.end_line
 =
+                               end_line;
                (*seq_state->num_steps)++;
        }
 }
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 097e4ac2df05..850639b6fd9b 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
@@ -4026,45 +4026,12 @@ void dcn10_calc_vupdate_position(
        *end_line = (*start_line + 2) % timing->v_total;
 }
 
-static void dcn10_cal_vline_position(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx,
-               uint32_t *start_line,
-               uint32_t *end_line)
-{
-       const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
-       int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
-
-       if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
-               if (vline_pos > 0)
-                       vline_pos--;
-               else if (vline_pos < 0)
-                       vline_pos++;
-
-               vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
-               if (vline_pos >= 0)
-                       *start_line = vline_pos - ((vline_pos / 
timing->v_total) * timing->v_total);
-               else
-                       *start_line = vline_pos + ((-vline_pos / 
timing->v_total) + 1) * timing->v_total - 1;
-               *end_line = (*start_line + 2) % timing->v_total;
-       } else if (pipe_ctx->stream->periodic_interrupt.ref_point == 
START_V_SYNC) {
-               // vsync is line 0 so start_line is just the requested line 
offset
-               *start_line = vline_pos;
-               *end_line = (*start_line + 2) % timing->v_total;
-       } else
-               ASSERT(0);
-}
-
 void dcn10_setup_periodic_interrupt(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx)
+               struct timing_generator *tg,
+               uint32_t start_line,
+               uint32_t end_line
+       )
 {
-       struct timing_generator *tg = pipe_ctx->stream_res.tg;
-       uint32_t start_line = 0;
-       uint32_t end_line = 0;
-
-       dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
-
        tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
 }
 
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 2cb674ba54e1..a93109c2199b 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
@@ -183,8 +183,9 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx);
 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(
-               struct dc *dc,
-               struct pipe_ctx *pipe_ctx);
+               struct timing_generator *tg,
+               uint32_t start_line,
+               uint32_t end_line);
 enum dc_status dcn10_set_clock(struct dc *dc,
                enum dc_clock_type clock_type,
                uint32_t clk_khz,
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 cdf2562a9a40..129120ac6d9e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -819,8 +819,9 @@ struct cursor_lock_params {
 };
 
 struct setup_periodic_interrupt_params {
-       struct dc *dc;
-       struct pipe_ctx *pipe_ctx;
+       struct timing_generator *tg;
+       uint32_t start_line;
+       uint32_t end_line;
 };
 
 struct send_cursor_info_to_dmu_params {
@@ -1452,8 +1453,9 @@ struct hw_sequencer_funcs {
        void (*enable_vblanks_synchronization)(struct dc *dc,
                        int group_index, int group_size,
                        struct pipe_ctx *grouped_pipes[]);
-       void (*setup_periodic_interrupt)(struct dc *dc,
-                       struct pipe_ctx *pipe_ctx);
+       void (*setup_periodic_interrupt)(struct timing_generator *tg,
+                       uint32_t start_line,
+                       uint32_t end_line);
        void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
                        struct dc_crtc_timing_adjust adjust);
        void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
@@ -2113,7 +2115,7 @@ void hwss_commit_cursor_offload_update(union 
block_sequence_params *params);
 
 void hwss_update_cursor_offload_pipe(union block_sequence_params *params);
 
-void hwss_setup_periodic_interrupt(struct dc *dc, union block_sequence_params 
*params);
+void hwss_setup_periodic_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
 
 void hwss_disable_audio_stream(struct dc *dc, union block_sequence_params 
*params);
 
-- 
2.43.0

Reply via email to