From: <IVAN.LIPSKI@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Harry Wentland <harry.wentland@amd.com>,
Leo Li <sunpeng.li@amd.com>,
Aurabindo Pillai <aurabindo.pillai@amd.com>,
Roman Li <roman.li@amd.com>, Wayne Lin <wayne.lin@amd.com>,
Tom Chung <chiahsuan.chung@amd.com>,
"Fangzhi Zuo" <jerry.zuo@amd.com>,
Dan Wheeler <daniel.wheeler@amd.com>, Ray Wu <Ray.Wu@amd.com>,
Ivan Lipski <ivan.lipski@amd.com>, Alex Hung <alex.hung@amd.com>,
James Lin <PingLei.Lin@amd.com>,
Chenyu Chen <Chen-Yu.Chen@amd.com>,
Tomasz Siemek <tomasz.siemek@amd.com>,
Alvin Lee <alvin.lee2@amd.com>
Subject: [PATCH 05/82] drm/amd/display: Split OPTC_PIPE_CONTROL_LOCK into smaller HWSS blocks
Date: Tue, 18 Aug 2026 16:14:57 -0400 [thread overview]
Message-ID: <20260818202139.4172592-6-IVAN.LIPSKI@amd.com> (raw)
In-Reply-To: <20260818202139.4172592-1-IVAN.LIPSKI@amd.com>
From: Tomasz Siemek <tomasz.siemek@amd.com>
[why]
Block level sequence operations should not use global state structs such
as pipe_ctx. OPTC_PIPE_CONTROL_LOCK is a BLS with complex logic
dispatching a lot of smaller hardware programming operations.
BLS should be a simple and atomic hardware operation without performing
mutations or having an access to global state. All operations on global
state should be moved to build step in HWSS.
[how]
- Split OPTC_PIPE_CONTROL_LOCK into substeps:
- HUBP_WAIT_FLIP_PENDING,
- TG_SET_GSL,
- TG_SET_GSL_SOURCE_SELECT,
- TG_LOCK,
- TG_3DLUT_WA_UNLOCK.
- Add hwss_pipe_control_lock - for in place build + execution.
- Remove timeout from HUBP_WAIT_FOR_FLIP_PENDING.
- Move software logic to builder. which fills pipe_control_lock_params
containing data for programming actual hwss blocks.
- Due to differences in what pipe control lock means bettween
asics following builder variants are added:
- dce_build_pipe_control_lock_sequence for asics pre DCN20,
- dcn20_build_pipe_control_lock_sequence.
- Rework gsl group programming to use builder / executor pattern.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Tomasz Siemek <tomasz.siemek@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 8 +-
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 125 ++++++++++----
.../drm/amd/display/dc/hwss/dce/dce_hwseq.c | 46 ++++--
.../drm/amd/display/dc/hwss/dce/dce_hwseq.h | 12 +-
.../amd/display/dc/hwss/dce110/dce110_hwseq.c | 5 +-
.../amd/display/dc/hwss/dce60/dce60_hwseq.c | 5 +-
.../amd/display/dc/hwss/dce80/dce80_hwseq.c | 3 +-
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 31 ++--
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.h | 5 +-
.../amd/display/dc/hwss/dcn10/dcn10_init.c | 4 +-
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 153 +++++++++++-------
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.h | 14 +-
.../amd/display/dc/hwss/dcn20/dcn20_init.c | 3 +-
.../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 34 ++--
.../amd/display/dc/hwss/dcn201/dcn201_hwseq.h | 5 +-
.../amd/display/dc/hwss/dcn201/dcn201_init.c | 4 +-
.../amd/display/dc/hwss/dcn21/dcn21_init.c | 3 +-
.../amd/display/dc/hwss/dcn30/dcn30_init.c | 3 +-
.../amd/display/dc/hwss/dcn301/dcn301_init.c | 3 +-
.../amd/display/dc/hwss/dcn31/dcn31_init.c | 3 +-
.../amd/display/dc/hwss/dcn314/dcn314_init.c | 3 +-
.../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 4 +-
.../amd/display/dc/hwss/dcn32/dcn32_init.c | 3 +-
.../amd/display/dc/hwss/dcn35/dcn35_init.c | 3 +-
.../amd/display/dc/hwss/dcn351/dcn351_init.c | 3 +-
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 140 ++++------------
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 3 +-
.../amd/display/dc/hwss/dcn401/dcn401_init.c | 3 +-
.../amd/display/dc/hwss/dcn42/dcn42_init.c | 3 +-
.../amd/display/dc/hwss/dcn60/dcn60_init.c | 3 +-
.../drm/amd/display/dc/hwss/hw_sequencer.h | 43 +++--
.../display/dc/hwss/hw_sequencer_private.h | 3 +-
32 files changed, 367 insertions(+), 316 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 6f7b715d4717e..3c6936943960d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1221,7 +1221,7 @@ static void apply_ctx_interdependent_lock(struct dc *dc,
if (stream == pipe_ctx->stream) {
if (resource_is_pipe_type(pipe_ctx, OPP_HEAD) &&
(pipe_ctx->plane_state || old_pipe_ctx->plane_state))
- dc->hwss.pipe_control_lock(dc, pipe_ctx, lock);
+ hwss_pipe_control_lock(dc, pipe_ctx, lock);
}
}
}
@@ -4991,7 +4991,7 @@ static void commit_planes_for_stream(struct dc *dc,
* plane addr update event triggers to be synchronized.
* top_pipe_to_program is expected to never be NULL
*/
- dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
+ hwss_pipe_control_lock(dc, top_pipe_to_program, true);
}
dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context);
@@ -5013,7 +5013,7 @@ static void commit_planes_for_stream(struct dc *dc,
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
dc->hwss.interdependent_update_lock(dc, context, false);
} else {
- dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
+ hwss_pipe_control_lock(dc, top_pipe_to_program, false);
}
dc->hwss.post_unlock_program_front_end(dc, context);
@@ -5200,7 +5200,7 @@ static void commit_planes_for_stream(struct dc *dc,
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
dc->hwss.interdependent_update_lock(dc, context, false);
} else {
- dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
+ hwss_pipe_control_lock(dc, top_pipe_to_program, false);
}
if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
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 d61c4d9488c59..8b723c3ca933d 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
@@ -1051,7 +1051,7 @@ void hwss_build_post_unlock_full_sequence(struct dc *dc,
unsigned int polling_interval_us;
polling_interval_us = 1;
- hwss_add_hubp_wait_flip_pending(&seq_state, pipe->plane_res.hubp, 100000, polling_interval_us);
+ hwss_add_hubp_wait_flip_pending(&seq_state, pipe->plane_res.hubp, polling_interval_us);
}
}
@@ -1212,13 +1212,9 @@ void hwss_build_fast_sequence(struct dc *dc,
block_sequence[*num_steps].func = DMUB_HW_CONTROL_LOCK_FAST;
(*num_steps)++;
}
- if (dc->hwss.pipe_control_lock) {
- block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
- block_sequence[*num_steps].params.pipe_control_lock_params.lock = true;
- block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
- block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
- (*num_steps)++;
- }
+ hwss_add_optc_pipe_control_lock(
+ &(struct block_sequence_state){ block_sequence, num_steps },
+ dc, pipe_ctx, true);
for (i = 0; i < dmub_cmd_count; i++) {
block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx;
@@ -1646,13 +1642,9 @@ void hwss_build_fast_sequence(struct dc *dc,
current_pipe = current_pipe->next_odm_pipe;
}
- if (dc->hwss.pipe_control_lock) {
- block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc;
- block_sequence[*num_steps].params.pipe_control_lock_params.lock = false;
- block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
- block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK;
- (*num_steps)++;
- }
+ hwss_add_optc_pipe_control_lock(
+ &(struct block_sequence_state){ block_sequence, num_steps },
+ dc, pipe_ctx, false);
if (dc->hwss.subvp_pipe_control_lock_fast) {
block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc;
block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false;
@@ -1710,10 +1702,14 @@ void hwss_execute_sequence(struct dc *dc,
case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST:
dc->hwss.subvp_pipe_control_lock_fast(params);
break;
- case OPTC_PIPE_CONTROL_LOCK:
- dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc,
- params->pipe_control_lock_params.pipe_ctx,
- params->pipe_control_lock_params.lock);
+ case TG_LOCK:
+ dc->hwss.tg_lock(¶ms->tg_lock_params);
+ break;
+ case TG_3DLUT_WA_UNLOCK:
+ if (dc->hwseq->funcs.perform_3dlut_wa_unlock)
+ dc->hwseq->funcs.perform_3dlut_wa_unlock(
+ params->tg_3dlut_wa_unlock_params.tg,
+ params->tg_3dlut_wa_unlock_params.hubp);
break;
case HUBP_SET_FLIP_CONTROL_GSL:
params->set_flip_control_gsl_params.hubp->funcs->hubp_set_flip_control_surface_gsl(
@@ -1925,7 +1921,8 @@ void hwss_execute_sequence(struct dc *dc,
hwss_tg_set_gsl_source_select(params);
break;
case HUBP_WAIT_FLIP_PENDING:
- hwss_hubp_wait_flip_pending(params);
+ hwss_hubp_wait_flip_pending(params->hubp_wait_flip_pending_params.hubp,
+ params->hubp_wait_flip_pending_params.polling_interval_us);
break;
case TG_WAIT_DOUBLE_BUFFER_PENDING:
hwss_tg_wait_double_buffer_pending(params);
@@ -2234,23 +2231,85 @@ void hwss_execute_sequence(struct dc *dc,
}
}
-/*
- * Helper function to add OPTC pipe control lock to block sequence
- */
void hwss_add_optc_pipe_control_lock(struct block_sequence_state *seq_state,
struct dc *dc,
struct pipe_ctx *pipe_ctx,
bool lock)
{
- if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
- seq_state->steps[*seq_state->num_steps].params.pipe_control_lock_params.dc = dc;
- seq_state->steps[*seq_state->num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx;
- seq_state->steps[*seq_state->num_steps].params.pipe_control_lock_params.lock = lock;
- seq_state->steps[*seq_state->num_steps].func = OPTC_PIPE_CONTROL_LOCK;
- (*seq_state->num_steps)++;
+ struct pipe_control_lock_params params = { 0 };
+ unsigned int hubp_idx;
+ unsigned int polling_interval_us = 1;
+
+ if (!dc->hwss.build_pipe_control_lock_sequence ||
+ !dc->hwss.build_pipe_control_lock_sequence(dc, pipe_ctx, lock, ¶ms))
+ return;
+
+ for (hubp_idx = 0; hubp_idx < MAX_PIPES; hubp_idx++)
+ if (params.hubps_to_wait_for_flip[hubp_idx])
+ hwss_add_hubp_wait_flip_pending(seq_state, params.hubps_to_wait_for_flip[hubp_idx],
+ polling_interval_us);
+
+ if (params.gsl_lock) {
+ hwss_add_tg_set_gsl(seq_state, params.gsl.tg, params.gsl.gsl);
+ hwss_add_tg_set_gsl_source_select(seq_state, params.gsl_source_select.tg,
+ params.gsl_source_select.group_idx, params.gsl_source_select.gsl_ready_signal);
+ }
+
+ if (params.tg_3dlut_wa_unlock) {
+ if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
+ seq_state->steps[*seq_state->num_steps].params.tg_3dlut_wa_unlock_params =
+ params.tg_3dlut_wa_unlock_params;
+ seq_state->steps[*seq_state->num_steps].func = TG_3DLUT_WA_UNLOCK;
+ (*seq_state->num_steps)++;
+ }
+ } else {
+ if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
+ seq_state->steps[*seq_state->num_steps].params.tg_lock_params = params.tg_lock;
+ seq_state->steps[*seq_state->num_steps].func = TG_LOCK;
+ (*seq_state->num_steps)++;
+ }
}
}
+void hwss_pipe_control_lock(struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ bool lock)
+{
+ struct pipe_control_lock_params params = { 0 };
+ unsigned int hubp_idx;
+ unsigned int polling_interval_us = 1;
+
+ if (!dc->hwss.build_pipe_control_lock_sequence ||
+ !dc->hwss.build_pipe_control_lock_sequence(dc, pipe_ctx, lock, ¶ms))
+ return;
+
+ for (hubp_idx = 0; hubp_idx < MAX_PIPES; hubp_idx++)
+ if (params.hubps_to_wait_for_flip[hubp_idx])
+ hwss_hubp_wait_flip_pending(
+ params.hubps_to_wait_for_flip[hubp_idx],
+ polling_interval_us);
+
+ if (params.gsl_lock) {
+ if (params.gsl.tg->funcs->set_gsl)
+ params.gsl.tg->funcs->set_gsl(params.gsl.tg, ¶ms.gsl.gsl);
+ if (params.gsl_source_select.tg->funcs->set_gsl_source_select)
+ params.gsl_source_select.tg->funcs->set_gsl_source_select(
+ params.gsl_source_select.tg,
+ params.gsl_source_select.group_idx,
+ params.gsl_source_select.gsl_ready_signal);
+ }
+
+ if (params.tg_3dlut_wa_unlock) {
+ dc->hwseq->funcs.perform_3dlut_wa_unlock(
+ params.tg_3dlut_wa_unlock_params.tg,
+ params.tg_3dlut_wa_unlock_params.hubp);
+ return;
+ }
+
+ if (dc->hwss.tg_lock)
+ dc->hwss.tg_lock(¶ms.tg_lock);
+}
+
/*
* Helper function to add HUBP set flip control GSL to block sequence
*/
@@ -2853,12 +2912,10 @@ void hwss_add_tg_enable_crtc(struct block_sequence_state *seq_state,
*/
void hwss_add_hubp_wait_flip_pending(struct block_sequence_state *seq_state,
struct hubp *hubp,
- unsigned int timeout_us,
unsigned int polling_interval_us)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].params.hubp_wait_flip_pending_params.hubp = hubp;
- seq_state->steps[*seq_state->num_steps].params.hubp_wait_flip_pending_params.timeout_us = timeout_us;
seq_state->steps[*seq_state->num_steps].params.hubp_wait_flip_pending_params.polling_interval_us = polling_interval_us;
seq_state->steps[*seq_state->num_steps].func = HUBP_WAIT_FLIP_PENDING;
(*seq_state->num_steps)++;
@@ -3611,11 +3668,9 @@ void hwss_tg_set_gsl_source_select(union block_sequence_params *params)
tg->funcs->set_gsl_source_select(tg, group_idx, gsl_ready_signal);
}
-void hwss_hubp_wait_flip_pending(union block_sequence_params *params)
+void hwss_hubp_wait_flip_pending(struct hubp *hubp, unsigned int polling_interval_us)
{
- struct hubp *hubp = params->hubp_wait_flip_pending_params.hubp;
- unsigned int timeout_us = params->hubp_wait_flip_pending_params.timeout_us;
- unsigned int polling_interval_us = params->hubp_wait_flip_pending_params.polling_interval_us;
+ const unsigned int timeout_us = 100000U;
unsigned int j = 0;
for (j = 0; j < timeout_us / polling_interval_us
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c
index 4202fadb2c0e9..0f44577572fbe 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.c
@@ -44,20 +44,36 @@ void dce_enable_fe_clock(struct dce_hwseq *hws,
DCFE_CLOCK_ENABLE, enable);
}
-void dce_pipe_control_lock(struct dc *dc,
+bool dce_build_pipe_control_lock_sequence(struct dc *dc,
struct pipe_ctx *pipe,
- bool lock)
+ bool lock,
+ struct pipe_control_lock_params *params)
{
- uint32_t lock_val = lock ? 1 : 0;
+ if (!pipe || pipe->top_pipe)
+ return false;
+
+ params->lock = lock;
+ params->tg_lock.dc = dc;
+ params->tg_lock.tg = pipe->stream_res.tg;
+ params->tg_lock.lock = lock;
+ params->tg_lock.triplebuffer_flips = pipe->plane_state &&
+ pipe->plane_state->triplebuffer_flips;
+ return true;
+}
+
+void dce_tg_lock(struct tg_lock_params *params)
+{
+ uint32_t lock_val = params->lock ? 1 : 0;
uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
- struct dce_hwseq *hws = dc->hwseq;
+ struct dce_hwseq *hws = params->dc->hwseq;
+ unsigned int tg_inst = params->tg->inst;
/* Not lock pipe when blank */
- if (lock && pipe->stream_res.tg->funcs->is_blanked &&
- pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
+ if (params->lock && params->tg->funcs->is_blanked &&
+ params->tg->funcs->is_blanked(params->tg))
return;
- val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
+ val = REG_GET_4(BLND_V_UPDATE_LOCK[tg_inst],
BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
BLND_SCL_V_UPDATE_LOCK, &scl,
BLND_BLND_V_UPDATE_LOCK, &blnd,
@@ -68,28 +84,28 @@ void dce_pipe_control_lock(struct dc *dc,
blnd = lock_val;
update_lock_mode = lock_val;
- REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
+ REG_SET_2(BLND_V_UPDATE_LOCK[tg_inst], val,
BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
BLND_SCL_V_UPDATE_LOCK, scl);
if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
- REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
+ REG_SET_2(BLND_V_UPDATE_LOCK[tg_inst], val,
BLND_BLND_V_UPDATE_LOCK, blnd,
BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
if (hws->wa.blnd_crtc_trigger) {
- if (!lock) {
- uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
- REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
+ if (!params->lock) {
+ uint32_t value = REG_READ(CRTC_H_BLANK_START_END[tg_inst]);
+
+ REG_WRITE(CRTC_H_BLANK_START_END[tg_inst], value);
}
}
}
#if defined(CONFIG_DRM_AMD_DC_SI)
-void dce60_pipe_control_lock(struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock)
+void dce60_tg_lock(struct tg_lock_params *params)
{
+ (void)params;
/* DCE6 has no BLND_V_UPDATE_LOCK register */
}
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h
index 2cc4e7516a5d7..0b9b418626110 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h
@@ -26,6 +26,7 @@
#define __DCE_HWSEQ_H__
#include "dc_types.h"
+#include "hw_sequencer_private.h"
#define HWSEQ_DCEF_REG_LIST_DCE8() \
.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
@@ -1299,17 +1300,16 @@ struct clock_source;
void dce_enable_fe_clock(struct dce_hwseq *hwss,
unsigned int inst, bool enable);
-void dce_pipe_control_lock(struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock);
+bool dce_build_pipe_control_lock_sequence(struct dc *dc,
+ struct pipe_ctx *pipe, bool lock,
+ struct pipe_control_lock_params *params);
+void dce_tg_lock(struct tg_lock_params *params);
void dce_set_blender_mode(struct dce_hwseq *hws,
unsigned int blnd_inst, enum blnd_mode mode);
#if defined(CONFIG_DRM_AMD_DC_SI)
-void dce60_pipe_control_lock(struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock);
+void dce60_tg_lock(struct tg_lock_params *params);
#endif
void dce_clock_gating_power_up(struct dce_hwseq *hws,
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 ef91c61033a33..bb46d72490259 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
@@ -3640,9 +3640,10 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dce110_power_down_fe,
- .pipe_control_lock = dce_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dce_build_pipe_control_lock_sequence,
+ .tg_lock = dce_tg_lock,
.interdependent_update_lock = NULL,
- .cursor_lock = dce_pipe_control_lock,
+ .cursor_lock = hwss_pipe_control_lock,
.prepare_bandwidth = dce110_prepare_bandwidth,
.optimize_bandwidth = dce110_optimize_bandwidth,
.set_drr = set_drr,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce60/dce60_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce60/dce60_hwseq.c
index 1652e47716a0a..b73a10b0acbd7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce60/dce60_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce60/dce60_hwseq.c
@@ -423,8 +423,9 @@ void dce60_hw_sequencer_construct(struct dc *dc)
dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface;
- dc->hwss.cursor_lock = dce60_pipe_control_lock;
- dc->hwss.pipe_control_lock = dce60_pipe_control_lock;
+ dc->hwss.cursor_lock = hwss_pipe_control_lock;
+ dc->hwss.build_pipe_control_lock_sequence = dce_build_pipe_control_lock_sequence;
+ dc->hwss.tg_lock = dce60_tg_lock;
dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c
index 76fd45550c5e7..f44f41b13007d 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce80/dce80_hwseq.c
@@ -47,7 +47,8 @@ void dce80_hw_sequencer_construct(struct dc *dc)
dce110_hw_sequencer_construct(dc);
dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
- dc->hwss.pipe_control_lock = dce_pipe_control_lock;
+ dc->hwss.build_pipe_control_lock_sequence = dce_build_pipe_control_lock_sequence;
+ dc->hwss.tg_lock = dce_tg_lock;
dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
dc->hwss.clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling;
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 d76fc6ef38c4e..b1679791f903f 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
@@ -246,9 +246,9 @@ void dcn10_lock_all_pipes(struct dc *dc,
continue;
if (lock)
- dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
+ hwss_pipe_control_lock(dc, pipe_ctx, true);
else
- dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
+ hwss_pipe_control_lock(dc, pipe_ctx, false);
}
}
@@ -2202,29 +2202,20 @@ bool dcn10_set_output_transfer_func(struct set_output_transfer_func_params *para
return true;
}
-void dcn10_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock)
+void dcn10_tg_lock(struct tg_lock_params *params)
{
- struct dce_hwseq *hws = dc->hwseq;
-
- /* use TG master update lock to lock everything on the TG
- * therefore only top pipe need to lock
- */
- if (!pipe || pipe->top_pipe)
- return;
+ struct dce_hwseq *hws = params->dc->hwseq;
- if (dc->debug.sanity_checks)
- hws->funcs.verify_allow_pstate_change_high(dc);
+ if (params->dc->debug.sanity_checks)
+ hws->funcs.verify_allow_pstate_change_high(params->dc);
- if (lock)
- pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+ if (params->lock)
+ params->tg->funcs->lock(params->tg);
else
- pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+ params->tg->funcs->unlock(params->tg);
- if (dc->debug.sanity_checks)
- hws->funcs.verify_allow_pstate_change_high(dc);
+ if (params->dc->debug.sanity_checks)
+ hws->funcs.verify_allow_pstate_change_high(params->dc);
}
/**
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 1f36bd58beb24..30c213f2e8d6c 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
@@ -57,10 +57,7 @@ void dcn10_wait_for_pipe_update_if_needed(
void dcn10_set_wait_for_update_needed_for_pipe(
struct dc *dc,
struct pipe_ctx *pipe_ctx);
-void dcn10_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock);
+void dcn10_tg_lock(struct tg_lock_params *params);
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
void dcn10_blank_pixel_data(
struct dc *dc,
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 b5e82e1901247..47ab50a3fab1c 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
@@ -27,6 +27,7 @@
#include "dce110/dce110_hwseq.h"
#include "dcn10/dcn10_hwseq.h"
#include "dcn20/dcn20_hwseq.h"
+#include "dc/hwss/dce/dce_hwseq.h"
static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = dcn10_program_gamut_remap,
@@ -54,7 +55,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn10_disable_plane,
- .pipe_control_lock = dcn10_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dce_build_pipe_control_lock_sequence,
+ .tg_lock = dcn10_tg_lock,
.cursor_lock = dcn10_cursor_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.prepare_bandwidth = dcn10_prepare_bandwidth,
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 23e191d472991..38d587af9dd82 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
@@ -217,15 +217,18 @@ static int find_free_gsl_group(const struct dc *dc)
* gsl_0 <=> pipe_ctx->stream_res.gsl_group == 1
* Using a magic value like -1 would require tracking all inits/resets
*/
-void dcn20_setup_gsl_group_as_lock(
+void dcn20_build_gsl_group_as_lock(
const struct dc *dc,
struct pipe_ctx *pipe_ctx,
- bool enable)
+ bool enable,
+ struct tg_set_gsl_params *gsl_params,
+ struct tg_set_gsl_source_select_params *gsl_source_select_params)
{
- struct gsl_params gsl;
int group_idx;
- memset(&gsl, 0, sizeof(struct gsl_params));
+ memset(&gsl_params->gsl, 0, sizeof(gsl_params->gsl));
+ gsl_params->tg = pipe_ctx->stream_res.tg;
+ gsl_source_select_params->tg = pipe_ctx->stream_res.tg;
if (enable) {
/* return if group already assigned since GSL was set up
@@ -241,22 +244,22 @@ void dcn20_setup_gsl_group_as_lock(
/* set gsl group reg field and mark resource used */
switch (group_idx) {
case 1:
- gsl.gsl0_en = 1;
+ gsl_params->gsl.gsl0_en = 1;
dc->res_pool->gsl_groups.gsl_0 = 1;
break;
case 2:
- gsl.gsl1_en = 1;
+ gsl_params->gsl.gsl1_en = 1;
dc->res_pool->gsl_groups.gsl_1 = 1;
break;
case 3:
- gsl.gsl2_en = 1;
+ gsl_params->gsl.gsl2_en = 1;
dc->res_pool->gsl_groups.gsl_2 = 1;
break;
default:
BREAK_TO_DEBUGGER();
return; // invalid case
}
- gsl.gsl_master_en = 1;
+ gsl_params->gsl.gsl_master_en = 1;
} else {
group_idx = pipe_ctx->stream_res.gsl_group;
if (group_idx == 0)
@@ -267,32 +270,46 @@ void dcn20_setup_gsl_group_as_lock(
/* unset gsl group reg field and mark resource free */
switch (group_idx) {
case 1:
- gsl.gsl0_en = 0;
dc->res_pool->gsl_groups.gsl_0 = 0;
break;
case 2:
- gsl.gsl1_en = 0;
dc->res_pool->gsl_groups.gsl_1 = 0;
break;
case 3:
- gsl.gsl2_en = 0;
dc->res_pool->gsl_groups.gsl_2 = 0;
break;
default:
BREAK_TO_DEBUGGER();
return;
}
- gsl.gsl_master_en = 0;
}
+ gsl_source_select_params->group_idx = group_idx;
+ gsl_source_select_params->gsl_ready_signal = enable ? 4 : 0;
+}
+
+void dcn20_setup_gsl_group_as_lock(
+ const struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ bool enable)
+{
+ struct tg_set_gsl_params gsl_params = { 0 };
+ struct tg_set_gsl_source_select_params gsl_source_select_params = { 0 };
+
+ dcn20_build_gsl_group_as_lock(dc, pipe_ctx, enable,
+ &gsl_params, &gsl_source_select_params);
+ if (!gsl_source_select_params.group_idx)
+ return;
+
/* at this point we want to program whether it's to enable or disable */
if (pipe_ctx->stream_res.tg->funcs->set_gsl != NULL) {
pipe_ctx->stream_res.tg->funcs->set_gsl(
pipe_ctx->stream_res.tg,
- &gsl);
+ &gsl_params.gsl);
if (pipe_ctx->stream_res.tg->funcs->set_gsl_source_select != NULL)
pipe_ctx->stream_res.tg->funcs->set_gsl_source_select(
- pipe_ctx->stream_res.tg, group_idx, enable ? 4 : 0);
+ pipe_ctx->stream_res.tg, gsl_source_select_params.group_idx,
+ gsl_source_select_params.gsl_ready_signal);
} else
BREAK_TO_DEBUGGER();
}
@@ -1386,19 +1403,30 @@ void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
// }
}
-void dcn20_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock)
+bool dcn20_build_pipe_control_lock_sequence(
+ struct dc *dc,
+ struct pipe_ctx *pipe,
+ bool lock,
+ struct pipe_control_lock_params *params)
{
struct pipe_ctx *temp_pipe;
bool flip_immediate = false;
+ unsigned int hubp_count = 0;
/* use TG master update lock to lock everything on the TG
* therefore only top pipe need to lock
*/
if (!pipe || pipe->top_pipe)
- return;
+ return false;
+
+ params->lock = lock;
+ params->tg_lock.dc = dc;
+ params->tg_lock.lock = lock;
+ params->tg_lock.tg = pipe->stream_res.tg;
+ params->tg_lock.use_dmub_inbox1 = pipe->stream &&
+ should_use_dmub_inbox1_lock(dc, pipe->stream->link);
+ params->tg_lock.triplebuffer_flips = pipe->plane_state &&
+ pipe->plane_state->triplebuffer_flips;
if (pipe->plane_state != NULL)
flip_immediate = pipe->plane_state->flip_immediate;
@@ -1413,22 +1441,10 @@ void dcn20_pipe_control_lock(
}
if (flip_immediate && lock) {
- const unsigned int TIMEOUT_FOR_FLIP_PENDING_US = 100000U;
- unsigned int polling_interval_us = 1;
- unsigned int i;
-
temp_pipe = pipe;
while (temp_pipe) {
- if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate) {
- for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING_US / polling_interval_us; ++i) {
- if (!temp_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(temp_pipe->plane_res.hubp))
- break;
- udelay(polling_interval_us);
- }
-
- /* no reason it should take this long for immediate flips */
- ASSERT(i != TIMEOUT_FOR_FLIP_PENDING_US);
- }
+ if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate)
+ params->hubps_to_wait_for_flip[hubp_count++] = temp_pipe->plane_res.hubp;
temp_pipe = temp_pipe->bottom_pipe;
}
}
@@ -1438,8 +1454,11 @@ void dcn20_pipe_control_lock(
*/
if (lock && (pipe->bottom_pipe != NULL || !flip_immediate))
if ((flip_immediate && pipe->stream_res.gsl_group == 0) ||
- (!flip_immediate && pipe->stream_res.gsl_group > 0))
- dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate);
+ (!flip_immediate && pipe->stream_res.gsl_group > 0)) {
+ params->gsl_lock = true;
+ dcn20_build_gsl_group_as_lock(dc, pipe, flip_immediate,
+ ¶ms->gsl, ¶ms->gsl_source_select);
+ }
if (pipe->plane_state != NULL)
flip_immediate = pipe->plane_state->flip_immediate;
@@ -1452,37 +1471,53 @@ void dcn20_pipe_control_lock(
}
if (!lock && pipe->stream_res.gsl_group > 0 && pipe->plane_state &&
- !flip_immediate)
- dcn20_setup_gsl_group_as_lock(dc, pipe, false);
+ !flip_immediate) {
+ params->gsl_lock = true;
+ dcn20_build_gsl_group_as_lock(dc, pipe, false,
+ ¶ms->gsl, ¶ms->gsl_source_select);
+ }
+
+ if (!lock && !params->tg_lock.use_dmub_inbox1 &&
+ !params->tg_lock.triplebuffer_flips &&
+ dc->hwseq->funcs.perform_3dlut_wa_unlock) {
+ const struct pipe_ctx *otg_master_pipe = resource_get_otg_master(pipe);
+ const struct pipe_ctx *primary_dpp_pipe = resource_is_pipe_type(pipe, DPP_PIPE) ?
+ resource_get_primary_dpp_pipe(pipe) : pipe;
+
+ if (otg_master_pipe && otg_master_pipe->stream_res.tg &&
+ primary_dpp_pipe && primary_dpp_pipe->plane_state &&
+ primary_dpp_pipe->plane_state->cm.flags.bits.lut3d_enable &&
+ primary_dpp_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) {
+ params->tg_3dlut_wa_unlock = true;
+ params->tg_3dlut_wa_unlock_params.tg = otg_master_pipe->stream_res.tg;
+ params->tg_3dlut_wa_unlock_params.hubp = primary_dpp_pipe->plane_res.hubp;
+ }
+ }
+
+ return true;
+}
- if (pipe->stream && should_use_dmub_inbox1_lock(dc, pipe->stream->link)) {
+void dcn20_tg_lock(struct tg_lock_params *params)
+{
+ if (params->use_dmub_inbox1) {
union dmub_hw_lock_flags hw_locks = { 0 };
struct dmub_hw_lock_inst_flags inst_flags = { 0 };
hw_locks.bits.lock_pipe = 1;
- inst_flags.otg_inst = (uint8_t)pipe->stream_res.tg->inst;
-
- if (pipe->plane_state != NULL)
- hw_locks.bits.triple_buffer_lock = pipe->plane_state->triplebuffer_flips;
-
- dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv,
- lock,
- &hw_locks,
- &inst_flags);
- } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
- if (lock)
- pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+ inst_flags.otg_inst = (uint8_t)params->tg->inst;
+ hw_locks.bits.triple_buffer_lock = params->triplebuffer_flips;
+ dmub_hw_lock_mgr_cmd(params->dc->ctx->dmub_srv, params->lock,
+ &hw_locks, &inst_flags);
+ } else if (params->triplebuffer_flips) {
+ if (params->lock)
+ params->tg->funcs->triplebuffer_lock(params->tg);
else
- pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
+ params->tg->funcs->triplebuffer_unlock(params->tg);
} else {
- if (lock)
- pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
- else {
- if (dc->hwseq->funcs.perform_3dlut_wa_unlock)
- dc->hwseq->funcs.perform_3dlut_wa_unlock(pipe);
- else
- pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
- }
+ if (params->lock)
+ params->tg->funcs->lock(params->tg);
+ else
+ params->tg->funcs->unlock(params->tg);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h
index 9312c88e31ad9..c7bf79fda54c7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.h
@@ -61,10 +61,16 @@ void dcn20_blank_pixel_data(
struct dc *dc,
struct pipe_ctx *pipe_ctx,
bool blank);
-void dcn20_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock);
+bool dcn20_build_pipe_control_lock_sequence(struct dc *dc,
+ struct pipe_ctx *pipe, bool lock,
+ struct pipe_control_lock_params *params);
+void dcn20_build_gsl_group_as_lock(
+ const struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ bool enable,
+ struct tg_set_gsl_params *gsl_params,
+ struct tg_set_gsl_source_select_params *gsl_source_select_params);
+void dcn20_tg_lock(struct tg_lock_params *params);
void dcn20_prepare_bandwidth(
struct dc *dc,
struct dc_state *context);
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 1797a91b0186e..1c6c4e19bdda3 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
@@ -56,7 +56,8 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
index 7b820bdae55b4..9f4bc2a498730 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
@@ -525,35 +525,27 @@ void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
hubp->mpcc_id = mpcc_id;
}
-void dcn201_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock)
+void dcn201_tg_lock(struct tg_lock_params *params)
{
- struct dce_hwseq *hws = dc->hwseq;
- /* use TG master update lock to lock everything on the TG
- * therefore only top pipe need to lock
- */
- if (pipe->top_pipe)
- return;
+ struct dce_hwseq *hws = params->dc->hwseq;
- if (dc->debug.sanity_checks)
- hws->funcs.verify_allow_pstate_change_high(dc);
+ if (params->dc->debug.sanity_checks)
+ hws->funcs.verify_allow_pstate_change_high(params->dc);
- if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
- if (lock)
- pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+ if (params->triplebuffer_flips) {
+ if (params->lock)
+ params->tg->funcs->triplebuffer_lock(params->tg);
else
- pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
+ params->tg->funcs->triplebuffer_unlock(params->tg);
} else {
- if (lock)
- pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+ if (params->lock)
+ params->tg->funcs->lock(params->tg);
else
- pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+ params->tg->funcs->unlock(params->tg);
}
- if (dc->debug.sanity_checks)
- hws->funcs.verify_allow_pstate_change_high(dc);
+ if (params->dc->debug.sanity_checks)
+ hws->funcs.verify_allow_pstate_change_high(params->dc);
}
void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h
index 6a50a9894be6a..bab5d9e6912e4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.h
@@ -36,10 +36,7 @@ void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx);
void dcn201_plane_atomic_disconnect(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx);
void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx);
void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
-void dcn201_pipe_control_lock(
- struct dc *dc,
- struct pipe_ctx *pipe,
- bool lock);
+void dcn201_tg_lock(struct tg_lock_params *params);
void dcn201_init_blank(
struct dc *dc,
struct timing_generator *tg);
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 dec57fb4c05c9..95dda06b6b175 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
@@ -23,6 +23,7 @@
*
*/
+#include "dce/dce_hwseq.h"
#include "dce110/dce110_hwseq.h"
#include "dcn10/dcn10_hwseq.h"
#include "dcn20/dcn20_hwseq.h"
@@ -55,7 +56,8 @@ static const struct hw_sequencer_funcs dcn201_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn10_disable_plane,
- .pipe_control_lock = dcn201_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dce_build_pipe_control_lock_sequence,
+ .tg_lock = dcn201_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
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 c7701a8b574aa..b8ed664e1babf 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
@@ -56,7 +56,8 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
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 d5aa58462855c..b655c01f013bc 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
@@ -57,7 +57,8 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn30_prepare_bandwidth,
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 a570333aeac18..dfacc59166cdd 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
@@ -58,7 +58,8 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
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 7197414e5bd69..3c2e2162da117 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
@@ -60,7 +60,8 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
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 4966c044a8644..b50ab468b8f8f 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
@@ -62,7 +62,8 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index ec38fc2ba65cc..79be5c385280c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -1867,9 +1867,9 @@ void dcn32_interdependent_update_lock(struct dc *dc,
continue;
if (lock)
- dc->hwss.pipe_control_lock(dc, pipe, true);
+ hwss_pipe_control_lock(dc, pipe, true);
else
- dc->hwss.pipe_control_lock(dc, pipe, false);
+ hwss_pipe_control_lock(dc, pipe, false);
}
}
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 364b4108f5d6f..2251289622167 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
@@ -60,7 +60,8 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn32_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn32_prepare_bandwidth,
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 fc18d2207711f..c9125cc25d157 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
@@ -64,7 +64,8 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn35_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn35_prepare_bandwidth,
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 19ec5b4edfdc9..e6f7d57cbfed5 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
@@ -63,7 +63,8 @@ static const struct hw_sequencer_funcs dcn351_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn35_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn35_prepare_bandwidth,
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 0e107754c891e..8e0ccc9d58199 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
@@ -32,6 +32,7 @@
#include "dcn10/dcn10_cm_common.h"
#include "dcn10/dcn10_hubbub.h"
#include "dcn20/dcn20_optc.h"
+#include "dcn20/dcn20_hwseq.h"
#include "dcn30/dcn30_cm_common.h"
#include "dcn32/dcn32_hwseq.h"
#include "dcn401_hwseq.h"
@@ -1935,7 +1936,7 @@ void dcn401_interdependent_update_lock(struct dc *dc,
!tg->funcs->is_tg_enabled(tg) ||
dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
continue;
- dc->hwss.pipe_control_lock(dc, pipe, true);
+ hwss_pipe_control_lock(dc, pipe, true);
}
} else {
/* Need to free DET being used first and have pipe update, then unlock the remaining pipes*/
@@ -1951,7 +1952,7 @@ void dcn401_interdependent_update_lock(struct dc *dc,
if (dc->scratch.pipes_to_unlock_first[i]) {
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
- dc->hwss.pipe_control_lock(dc, pipe, false);
+ hwss_pipe_control_lock(dc, pipe, false);
/* Assumes pipe of the same index in current_state is also an OTG_MASTER pipe*/
dcn401_wait_for_det_buffer_update_under_otg_master(dc, dc->current_state, old_pipe);
}
@@ -1970,12 +1971,13 @@ void dcn401_interdependent_update_lock(struct dc *dc,
continue;
}
- dc->hwss.pipe_control_lock(dc, pipe, false);
+ hwss_pipe_control_lock(dc, pipe, false);
}
}
}
-void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
+void dcn401_perform_3dlut_wa_unlock(struct timing_generator *tg,
+ struct hubp *primary_hubp)
{
/* If 3DLUT FL is enabled and 3DLUT is in use, follow the workaround sequence for pipe unlock to make sure that
* HUBP will properly fetch 3DLUT contents after unlock.
@@ -1983,45 +1985,24 @@ void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx)
* This is meant to work around a known HW issue where VREADY will cancel the pending 3DLUT_ENABLE signal regardless
* of whether OTG lock is currently being held or not.
*/
- if (!pipe_ctx)
+ if (!tg)
return;
- const struct pipe_ctx *otg_master_pipe_ctx = resource_get_otg_master(pipe_ctx);
- struct timing_generator *tg = otg_master_pipe_ctx ?
- otg_master_pipe_ctx->stream_res.tg : NULL;
- const struct pipe_ctx *primary_dpp_pipe_ctx = resource_is_pipe_type(pipe_ctx, DPP_PIPE) ?
- resource_get_primary_dpp_pipe(pipe_ctx) : pipe_ctx;
- struct hubp *primary_hubp = primary_dpp_pipe_ctx ?
- primary_dpp_pipe_ctx->plane_res.hubp : NULL;
-
- if (!otg_master_pipe_ctx || !tg) {
- return;
- }
-
- if (primary_dpp_pipe_ctx &&
- primary_dpp_pipe_ctx->plane_state &&
- primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_enable &&
- primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_dma_enable) {
- if (tg->funcs->set_vupdate_keepout)
- tg->funcs->set_vupdate_keepout(tg, true);
+ if (tg->funcs->set_vupdate_keepout)
+ tg->funcs->set_vupdate_keepout(tg, true);
- if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
- primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
- }
+ if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl)
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
- tg->funcs->unlock(tg);
- if (tg->funcs->wait_update_lock_status)
- tg->funcs->wait_update_lock_status(tg, false);
+ tg->funcs->unlock(tg);
+ if (tg->funcs->wait_update_lock_status)
+ tg->funcs->wait_update_lock_status(tg, false);
- if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) {
- primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
- }
+ if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl)
+ primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true);
- if (tg->funcs->set_vupdate_keepout)
- tg->funcs->set_vupdate_keepout(tg, false);
- } else {
- tg->funcs->unlock(tg);
- }
+ if (tg->funcs->set_vupdate_keepout)
+ tg->funcs->set_vupdate_keepout(tg, false);
}
void dcn401_program_outstanding_updates(struct dc *dc,
@@ -3462,89 +3443,24 @@ void dcn401_update_writeback_sequence(
hwss_add_mcif_wb_config_buf(seq_state, mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height);
}
-static int find_free_gsl_group(const struct dc *dc)
-{
- if (dc->res_pool->gsl_groups.gsl_0 == 0)
- return 1;
- if (dc->res_pool->gsl_groups.gsl_1 == 0)
- return 2;
- if (dc->res_pool->gsl_groups.gsl_2 == 0)
- return 3;
-
- return 0;
-}
-
void dcn401_setup_gsl_group_as_lock_sequence(
const struct dc *dc,
struct pipe_ctx *pipe_ctx,
bool enable,
struct block_sequence_state *seq_state)
{
- struct gsl_params gsl;
- int group_idx;
-
- memset(&gsl, 0, sizeof(struct gsl_params));
+ struct tg_set_gsl_params gsl_params = { 0 };
+ struct tg_set_gsl_source_select_params gsl_source_select_params = { 0 };
- if (enable) {
- /* return if group already assigned since GSL was set up
- * for vsync flip, we would unassign so it can't be "left over"
- */
- if (pipe_ctx->stream_res.gsl_group > 0)
- return;
-
- group_idx = find_free_gsl_group(dc);
- ASSERT(group_idx != 0);
- pipe_ctx->stream_res.gsl_group = (uint8_t)group_idx;
-
- /* set gsl group reg field and mark resource used */
- switch (group_idx) {
- case 1:
- gsl.gsl0_en = 1;
- dc->res_pool->gsl_groups.gsl_0 = 1;
- break;
- case 2:
- gsl.gsl1_en = 1;
- dc->res_pool->gsl_groups.gsl_1 = 1;
- break;
- case 3:
- gsl.gsl2_en = 1;
- dc->res_pool->gsl_groups.gsl_2 = 1;
- break;
- default:
- BREAK_TO_DEBUGGER();
- return; // invalid case
- }
- gsl.gsl_master_en = 1;
- } else {
- group_idx = pipe_ctx->stream_res.gsl_group;
- if (group_idx == 0)
- return; // if not in use, just return
-
- pipe_ctx->stream_res.gsl_group = 0;
-
- /* unset gsl group reg field and mark resource free */
- switch (group_idx) {
- case 1:
- gsl.gsl0_en = 0;
- dc->res_pool->gsl_groups.gsl_0 = 0;
- break;
- case 2:
- gsl.gsl1_en = 0;
- dc->res_pool->gsl_groups.gsl_1 = 0;
- break;
- case 3:
- gsl.gsl2_en = 0;
- dc->res_pool->gsl_groups.gsl_2 = 0;
- break;
- default:
- BREAK_TO_DEBUGGER();
- return;
- }
- gsl.gsl_master_en = 0;
- }
+ dcn20_build_gsl_group_as_lock(dc, pipe_ctx, enable,
+ &gsl_params, &gsl_source_select_params);
+ if (!gsl_source_select_params.group_idx)
+ return;
- hwss_add_tg_set_gsl(seq_state, pipe_ctx->stream_res.tg, gsl);
- hwss_add_tg_set_gsl_source_select(seq_state, pipe_ctx->stream_res.tg, group_idx, enable ? 4 : 0);
+ hwss_add_tg_set_gsl(seq_state, gsl_params.tg, gsl_params.gsl);
+ hwss_add_tg_set_gsl_source_select(seq_state, gsl_source_select_params.tg,
+ gsl_source_select_params.group_idx,
+ gsl_source_select_params.gsl_ready_signal);
}
void dcn401_disable_plane_sequence(
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 c08fd359b38b0..756b2d98a9309 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
@@ -109,7 +109,8 @@ void dcn401_program_pipe_sequence(
struct pipe_ctx *pipe_ctx,
struct dc_state *context,
struct block_sequence_state *seq_state);
-void dcn401_perform_3dlut_wa_unlock(struct pipe_ctx *pipe_ctx);
+void dcn401_perform_3dlut_wa_unlock(struct timing_generator *tg,
+ struct hubp *primary_hubp);
void dcn401_program_front_end_for_ctx(struct dc *dc, struct dc_state *context);
void dcn401_post_unlock_program_front_end(struct dc *dc, struct dc_state *context);
bool dcn401_update_bandwidth(struct dc *dc, struct dc_state *context);
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 7039f40ea880d..783415e4e3a10 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
@@ -40,7 +40,8 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_plane_sequence = dcn401_disable_plane_sequence,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn401_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn401_prepare_bandwidth,
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 ba12a97a220fe..aad1885cc9887 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
@@ -42,7 +42,8 @@ static const struct hw_sequencer_funcs dcn42_funcs = {
.enable_audio_stream = dce110_enable_audio_stream,
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn35_disable_plane,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn401_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn42_prepare_bandwidth,
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 1c908964153b7..37e88d45409be 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
@@ -42,7 +42,8 @@ static const struct hw_sequencer_funcs dcn60_funcs = {
.disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn20_disable_plane,
.disable_plane_sequence = dcn401_disable_plane_sequence,
- .pipe_control_lock = dcn20_pipe_control_lock,
+ .build_pipe_control_lock_sequence = dcn20_build_pipe_control_lock_sequence,
+ .tg_lock = dcn20_tg_lock,
.interdependent_update_lock = dcn401_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn401_prepare_bandwidth,
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 169f3420ac6dd..4f0d000eab948 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -66,10 +66,17 @@ struct subvp_pipe_control_lock_fast_params {
bool subvp_immediate_flip;
};
-struct pipe_control_lock_params {
+struct tg_lock_params {
struct dc *dc;
- struct pipe_ctx *pipe_ctx;
+ struct timing_generator *tg;
bool lock;
+ bool use_dmub_inbox1;
+ bool triplebuffer_flips;
+};
+
+struct tg_3dlut_wa_unlock_params {
+ struct timing_generator *tg;
+ struct hubp *hubp;
};
struct set_flip_control_gsl_params {
@@ -342,6 +349,17 @@ struct tg_set_gsl_source_select_params {
uint32_t gsl_ready_signal;
};
+struct pipe_control_lock_params {
+ bool lock;
+ struct hubp *hubps_to_wait_for_flip[MAX_PIPES];
+ bool gsl_lock;
+ struct tg_set_gsl_params gsl;
+ struct tg_set_gsl_source_select_params gsl_source_select;
+ struct tg_lock_params tg_lock;
+ bool tg_3dlut_wa_unlock;
+ struct tg_3dlut_wa_unlock_params tg_3dlut_wa_unlock_params;
+};
+
struct setup_vupdate_interrupt_params {
struct dc *dc;
struct pipe_ctx *pipe_ctx;
@@ -487,7 +505,6 @@ struct tg_enable_crtc_params {
struct hubp_wait_flip_pending_params {
struct hubp *hubp;
- unsigned int timeout_us;
unsigned int polling_interval_us;
};
@@ -1026,7 +1043,8 @@ struct link_set_dpms_on_params {
union block_sequence_params {
struct update_plane_addr_params update_plane_addr_params;
struct subvp_pipe_control_lock_fast_params subvp_pipe_control_lock_fast_params;
- struct pipe_control_lock_params pipe_control_lock_params;
+ struct tg_lock_params tg_lock_params;
+ struct tg_3dlut_wa_unlock_params tg_3dlut_wa_unlock_params;
struct set_flip_control_gsl_params set_flip_control_gsl_params;
struct program_triplebuffer_params program_triplebuffer_params;
struct set_input_transfer_func_params set_input_transfer_func_params;
@@ -1200,7 +1218,8 @@ union block_sequence_params {
enum block_sequence_func {
DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST = 0,
- OPTC_PIPE_CONTROL_LOCK,
+ TG_LOCK,
+ TG_3DLUT_WA_UNLOCK,
HUBP_SET_FLIP_CONTROL_GSL,
HUBP_PROGRAM_TRIPLEBUFFER,
HUBP_UPDATE_PLANE_ADDR,
@@ -1432,8 +1451,10 @@ struct hw_sequencer_funcs {
void (*clear_surface_dcc_and_tiling)(struct pipe_ctx *pipe_ctx, struct dc_plane_state *plane_state, bool clear_tiling);
/* Pipe Lock Related */
- void (*pipe_control_lock)(struct dc *dc,
- struct pipe_ctx *pipe, bool lock);
+ bool (*build_pipe_control_lock_sequence)(struct dc *dc,
+ struct pipe_ctx *pipe, bool lock,
+ struct pipe_control_lock_params *params);
+ void (*tg_lock)(struct tg_lock_params *params);
void (*interdependent_update_lock)(struct dc *dc,
struct dc_state *context, bool lock);
void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx,
@@ -1959,7 +1980,8 @@ void hwss_tg_set_gsl(union block_sequence_params *params);
void hwss_tg_set_gsl_source_select(union block_sequence_params *params);
-void hwss_hubp_wait_flip_pending(union block_sequence_params *params);
+void hwss_hubp_wait_flip_pending(struct hubp *hubp,
+ unsigned int polling_interval_us);
void hwss_tg_wait_double_buffer_pending(union block_sequence_params *params);
@@ -2130,6 +2152,9 @@ void hwss_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx);
void hwss_add_optc_pipe_control_lock(struct block_sequence_state *seq_state,
struct dc *dc, struct pipe_ctx *pipe_ctx, bool lock);
+void hwss_pipe_control_lock(struct dc *dc,
+ struct pipe_ctx *pipe_ctx, bool lock);
+
void hwss_add_hubp_set_flip_control_gsl(struct block_sequence_state *seq_state,
struct hubp *hubp, bool flip_immediate);
@@ -2243,7 +2268,7 @@ void hwss_add_tg_enable_crtc(struct block_sequence_state *seq_state,
struct timing_generator *tg);
void hwss_add_hubp_wait_flip_pending(struct block_sequence_state *seq_state,
- struct hubp *hubp, unsigned int timeout_us, unsigned int polling_interval_us);
+ struct hubp *hubp, unsigned int polling_interval_us);
void hwss_add_tg_wait_double_buffer_pending(struct block_sequence_state *seq_state,
struct timing_generator *tg, unsigned int timeout_us, unsigned int polling_interval_us);
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 956513125be0b..9730f51cf3c04 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
@@ -217,7 +217,8 @@ struct hwseq_private_funcs {
void (*reset_back_end_for_pipe)(struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_state *context);
- void (*perform_3dlut_wa_unlock)(struct pipe_ctx *pipe_ctx);
+ void (*perform_3dlut_wa_unlock)(struct timing_generator *tg,
+ struct hubp *primary_hubp);
void (*wait_for_pipe_update_if_needed)(struct dc *dc, struct pipe_ctx *pipe_ctx, bool is_surface_update_only);
void (*set_wait_for_update_needed_for_pipe)(struct dc *dc, struct pipe_ctx *pipe_ctx);
void (*dc_ip_request_cntl)(struct dc *dc, bool enable);
--
2.43.0
next prev parent reply other threads:[~2026-08-18 20:23 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 20:14 [PATCH 00/82] DC Patches August 17, 2026 IVAN.LIPSKI
2026-08-18 20:14 ` [PATCH 01/82] drm/amd/display: Fall back to overlay cursor on dcn4x when top plane doesn't fill CRTC IVAN.LIPSKI
2026-08-19 7:27 ` Michel Dänzer
2026-08-20 10:04 ` Timur Kristóf
2026-08-18 20:14 ` [PATCH 02/82] drm/amd/display: Fixes for HPO test regressions IVAN.LIPSKI
2026-08-18 20:14 ` [PATCH 03/82] drm/amd/display: Refactor DPP_SET_INPUT_TRANSFER_FUNC to drop pipe_ctx IVAN.LIPSKI
2026-08-18 20:14 ` [PATCH 04/82] drm/amd/display: Use fast update path for address-only plane flips IVAN.LIPSKI
2026-08-18 20:14 ` IVAN.LIPSKI [this message]
2026-08-18 20:14 ` [PATCH 06/82] drm/amd/display: Fix DPREFCLK override when SMU isn't present or ready for DCN315 IVAN.LIPSKI
2026-08-18 20:14 ` [PATCH 07/82] drm/amd/display: Test writeback connector IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 08/82] drm/amd/display: Test GPU memory allocation IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 09/82] drm/amd/display: Cover MST path in encoder atomic_check IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 10/82] drm/amd/display: Cover amdgpu_dm_encoder_init IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 11/82] drm/amd/display: Cover MST-start failure in detect_mst IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 12/82] drm/amd/display: Cover amdgpu_dm_update_connector_after_detect IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 13/82] drm/amd/display: Cover HDMI infoframe/freesync timing paths IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 14/82] drm/amd/display: Clear HUBPREQ_DEBUG_DB on DCN6 IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 15/82] drm/amd/display: Disable alt-ch until dependencies are ready IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 16/82] drm/amd/display: Fix CalculateFlipSchedule Calculation IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 17/82] drm/amd/display: Test EDID quirks and ACPI EDID read IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 18/82] drm/amd/display: Test execute_synaptics_rc_command failures IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 19/82] drm/amd/display: Test MST stream feature read failure IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 20/82] drm/amd/display: Test dm_helpers_submit_i2c_over_aux IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 21/82] drm/amd/display: Test GPU memory allocate and free helpers IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 22/82] drm/amd/display: Test dm_helpers_dmub_set_config_sync IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 23/82] drm/amd/display: Test dm_helpers_is_dp_sink_present IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 24/82] drm/amd/display: Test dm_helpers_read_local_edid IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 25/82] drm/amd/display: Test dp_handle_test_pattern_request patterns IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 26/82] drm/amd/display: Test DMUB reg callbacks IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 27/82] drm/amd/display: Test VBIOS bounding box IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 28/82] drm/amd/display: Test dm_init_microcode IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 29/82] drm/amd/display: Test dm_dmub_sw_init IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 30/82] drm/amd/display: Add hook to disable alt-ch in PMO IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 31/82] drm/amd/display: Update alt-ch size calculations IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 32/82] drm/amd/display: Enable min dispclk ODM on DCN42 IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 33/82] drm/amd/display: Add amdgpu_dm_connector_poll KUnit tests IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 34/82] drm/amd/display: Cover hide_secondary_tile_from_userspace IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 35/82] drm/amd/display: Cover dm_validate_stream_and_context IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 36/82] drm/amd/display: Cover amdgpu_dm_create_validate_stream_for_sink IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 37/82] drm/amd/display: Cover amdgpu_dm_connector_mode_valid IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 38/82] drm/amd/display: Test MST sideband message ack path IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 39/82] drm/amd/display: Test dm_dp_mst_get_modes without a remote EDID IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 40/82] drm/amd/display: Test dm_dp_mst_get_modes with " IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 41/82] drm/amd/display: Test dm_dp_mst_detect DPCD probe and unplug IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 42/82] drm/amd/display: Test MST connector register and unregister IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 43/82] drm/amd/display: Test dm_dp_mst_connector_destroy IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 44/82] drm/amd/display: Test plane state duplicate and destroy IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 45/82] drm/amd/display: Test modifier list de-duplication IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 46/82] drm/amd/display: Test GFX6-8 tiling info from modifiers IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 47/82] drm/amd/display: Test GFX6-8 tile mode and tile split lookups IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 48/82] drm/amd/display: Test GFX6-8 modifier calculation IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 49/82] drm/amd/display: Test GFX6-8 modifier list generation IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 50/82] drm/amd/display: Test framebuffer prepare and cleanup IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 51/82] drm/amd/display: Test cursor update and async plane update IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 52/82] drm/amd/display: Remove RMCM tetrahedral cube from dc_plane_state IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 53/82] drm/amd/display: Cover mode_valid EDID mgmt path IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 54/82] drm/amd/display: Cover amdgpu_dm_fill_hdr_info_packet IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 55/82] drm/amd/display: Cover amdgpu_dm_connector_atomic_check IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 56/82] drm/amd/display: Cover atomic_check modeset triggers IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 57/82] drm/amd/display: Cover funcs_force valid EDID path IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 58/82] drm/amd/display: Cover amdgpu_dm_connector_get_modes IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 59/82] drm/amd/display: Cover create_eml_sink valid EDID path IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 60/82] drm/amd/display: Cover amdgpu_set_panel_orientation IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 61/82] drm/amd/display: Refactor amdgpu_dm_irq_test IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 62/82] drm/amd/display: Test pageflip completion in the high IRQ handlers IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 63/82] drm/amd/display: Test writeback handling in dm_crtc_high_irq IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 64/82] drm/amd/display: Test schedule_dc_vmin_vmax IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 65/82] drm/amd/display: Test handle_hpd_irq_helper detect and debounce exits IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 66/82] drm/amd/display: Test HPD RX, HPD init and DMUB callback branches IVAN.LIPSKI
2026-08-18 20:15 ` [PATCH 67/82] drm/amd/display: Test dm_dmub_outbox1_low_irq drain and work guards IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 68/82] drm/amd/display: Test amdgpu_dm_dce110_register_irq_handlers IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 69/82] drm/amd/display: Test amdgpu_dm_dcn10_register_irq_handlers IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 70/82] drm/amd/display: Fix mismatch number of OPP/DPP accounting IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 71/82] drm/amd/display: Cover amdgpu_dm_prune_primary_tile_modes IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 72/82] drm/amd/display: Cover add_fs_modes mode generation IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 73/82] drm/amd/display: Cover add_fs_modes illegal timing skip IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 74/82] drm/amd/display: Refactor hdmi_frl_status_polling_work for Kunit testing IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 75/82] drm/amd/display: Cover hdmi_frl_status_polling_work IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 76/82] drm/amd/display: Cover amdgpu_dm_i2c_xfer IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 77/82] drm/amd/display: Cover amdgpu_dm_create_i2c IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 78/82] drm/amd/display: Add passthrough visual confirm IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 79/82] drm/amd/display: Populate vblank_nom according to bounding box IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 80/82] drm/amd/display: Adjust vblank_nom policy for HW SDP tranmission reqs IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 81/82] drm/amd/display: Guard amdgpu_dm_irq_schedule_work against NULL irq_wq IVAN.LIPSKI
2026-08-18 20:16 ` [PATCH 82/82] drm/amd/display: Promote DC to 3.2.395 IVAN.LIPSKI
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260818202139.4172592-6-IVAN.LIPSKI@amd.com \
--to=ivan.lipski@amd.com \
--cc=Chen-Yu.Chen@amd.com \
--cc=PingLei.Lin@amd.com \
--cc=Ray.Wu@amd.com \
--cc=alex.hung@amd.com \
--cc=alvin.lee2@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=aurabindo.pillai@amd.com \
--cc=chiahsuan.chung@amd.com \
--cc=daniel.wheeler@amd.com \
--cc=harry.wentland@amd.com \
--cc=jerry.zuo@amd.com \
--cc=roman.li@amd.com \
--cc=sunpeng.li@amd.com \
--cc=tomasz.siemek@amd.com \
--cc=wayne.lin@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.