[PATCH 376/459] drm/amd/display: isolate global double buffer lock programming

Alex Deucher alexdeucher at gmail.com
Mon Jun 17 19:45:17 UTC 2019


From: Wenjing Liu <Wenjing.Liu at amd.com>

[why]
Global optic double buffer lock is currently disabled due to
incorrect programming sequence that affects non global lock.

[how]
Isolate global lock programming sequence out of non global lock
programming sequence, so it can be enabled without affecting
non global lock.

Signed-off-by: Wenjing Liu <Wenjing.Liu at amd.com>
Reviewed-by: Jun Lei <Jun.Lei at amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 19 +++---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 60 ++++++-------------
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.h |  5 +-
 .../amd/display/dc/inc/hw/timing_generator.h  |  4 +-
 4 files changed, 35 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 0cad51ece06e..542f144f807f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -727,10 +727,6 @@ enum dc_status dcn20_enable_stream_timing(
 			pipe_ctx->stream->signal,
 			true);
 
-	if (pipe_ctx->stream_res.tg->funcs->setup_global_lock)
-		pipe_ctx->stream_res.tg->funcs->setup_global_lock(
-				pipe_ctx->stream_res.tg);
-
 	/* program otg blank color */
 	color_space = stream->output_color_space;
 	color_space_to_black_color(dc, color_space, &black_color);
@@ -1227,10 +1223,19 @@ static void dcn20_pipe_control_lock_global(
 		struct pipe_ctx *pipe,
 		bool lock)
 {
-	if (lock)
-		pipe->stream_res.tg->funcs->lock_global(pipe->stream_res.tg);
-	else
+	if (lock) {
+		pipe->stream_res.tg->funcs->lock_doublebuffer_enable(
+				pipe->stream_res.tg);
+		pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
+	} else {
 		pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
+		pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg,
+				CRTC_STATE_VACTIVE);
+		pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg,
+				CRTC_STATE_VBLANK);
+		pipe->stream_res.tg->funcs->lock_doublebuffer_disable(
+				pipe->stream_res.tg);
+	}
 }
 
 static void dcn20_pipe_control_lock(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
index 34f5a7d671b2..43e71b4ab5e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
@@ -330,64 +330,42 @@ void optc2_triplebuffer_unlock(struct timing_generator *optc)
 
 }
 
-void optc2_setup_global_lock(struct timing_generator *optc)
+void optc2_lock_doublebuffer_enable(struct timing_generator *optc)
 {
 	struct optc *optc1 = DCN10TG_FROM_TG(optc);
 	uint32_t v_blank_start = 0;
-	uint32_t h_blank_start = 0, h_total = 0;
+	uint32_t h_blank_start = 0;
 
-	REG_SET(OTG_GLOBAL_CONTROL2, 0, DIG_UPDATE_LOCATION, 20);
+	REG_UPDATE(OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_EN, 1);
+
+	REG_UPDATE_2(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1,
+			DIG_UPDATE_LOCATION, 20);
 
 	REG_GET(OTG_V_BLANK_START_END, OTG_V_BLANK_START, &v_blank_start);
 
 	REG_GET(OTG_H_BLANK_START_END, OTG_H_BLANK_START, &h_blank_start);
 
-	REG_GET(OTG_H_TOTAL, OTG_H_TOTAL, &h_total);
 	REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
 			MASTER_UPDATE_LOCK_DB_X,
-			0,
+			h_blank_start - 200 - 1,
 			MASTER_UPDATE_LOCK_DB_Y,
 			v_blank_start - 1);
 }
 
-void optc2_lock_global(struct timing_generator *optc)
+void optc2_lock_doublebuffer_disable(struct timing_generator *optc)
 {
 	struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
-	REG_SET(OTG_GLOBAL_CONTROL1, 0, MASTER_UPDATE_LOCK_DB_EN, 1);
-
-	REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1);
-
-	REG_SET(OTG_GLOBAL_CONTROL0, 0,
-			OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
-	REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
-			OTG_MASTER_UPDATE_LOCK, 1);
-
-	/* Should be fast, status does not update on maximus */
-	if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
-		REG_WAIT(OTG_MASTER_UPDATE_LOCK,
-				UPDATE_LOCK_STATUS, 1,
-				1, 10);
-}
-
-void optc2_lock(struct timing_generator *optc)
-{
-	struct optc *optc1 = DCN10TG_FROM_TG(optc);
-
-	REG_SET(OTG_GLOBAL_CONTROL1, 0, MASTER_UPDATE_LOCK_DB_EN, 0);
+	REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
+				MASTER_UPDATE_LOCK_DB_X,
+				0,
+				MASTER_UPDATE_LOCK_DB_Y,
+				0);
 
-	REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 0);
+	REG_UPDATE_2(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 0,
+				DIG_UPDATE_LOCATION, 0);
 
-	REG_SET(OTG_GLOBAL_CONTROL0, 0,
-			OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
-	REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
-			OTG_MASTER_UPDATE_LOCK, 1);
-
-	/* Should be fast, status does not update on maximus */
-	if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
-		REG_WAIT(OTG_MASTER_UPDATE_LOCK,
-				UPDATE_LOCK_STATUS, 1,
-				1, 10);
+	REG_UPDATE(OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_EN, 0);
 }
 
 void optc2_setup_manual_trigger(struct timing_generator *optc)
@@ -446,10 +424,10 @@ static struct timing_generator_funcs dcn20_tg_funcs = {
 		.triplebuffer_lock = optc2_triplebuffer_lock,
 		.triplebuffer_unlock = optc2_triplebuffer_unlock,
 		.disable_reset_trigger = optc1_disable_reset_trigger,
-		.lock = optc2_lock,
+		.lock = optc1_lock,
 		.unlock = optc1_unlock,
-		.lock_global = optc2_lock_global,
-		.setup_global_lock = optc2_setup_global_lock,
+		.lock_doublebuffer_enable = optc2_lock_doublebuffer_enable,
+		.lock_doublebuffer_disable = optc2_lock_doublebuffer_disable,
 		.enable_optc_clock = optc1_enable_optc_clock,
 		.set_drr = optc1_set_drr,
 		.set_static_screen_control = optc1_set_static_screen_control,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
index a00bb0d92a49..d2651d846424 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
@@ -104,9 +104,8 @@ void optc2_get_optc_source(struct timing_generator *optc,
 
 void optc2_triplebuffer_lock(struct timing_generator *optc);
 void optc2_triplebuffer_unlock(struct timing_generator *optc);
-void optc2_lock(struct timing_generator *optc);
-void optc2_lock_global(struct timing_generator *optc);
-void optc2_setup_global_lock(struct timing_generator *optc);
+void optc2_lock_doublebuffer_disable(struct timing_generator *optc);
+void optc2_lock_doublebuffer_enable(struct timing_generator *optc);
 void optc2_program_manual_trigger(struct timing_generator *optc);
 
 #endif /* __DC_OPTC_DCN20_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index 251baebe5386..75314de83b3e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -184,10 +184,10 @@ struct timing_generator_funcs {
 	bool (*did_triggered_reset_occur)(struct timing_generator *tg);
 	void (*setup_global_swap_lock)(struct timing_generator *tg,
 							const struct dcp_gsl_params *gsl_params);
-	void (*setup_global_lock)(struct timing_generator *tg);
 	void (*unlock)(struct timing_generator *tg);
 	void (*lock)(struct timing_generator *tg);
-	void (*lock_global)(struct timing_generator *tg);
+	void (*lock_doublebuffer_disable)(struct timing_generator *tg);
+	void (*lock_doublebuffer_enable)(struct timing_generator *tg);
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 	void(*triplebuffer_unlock)(struct timing_generator *tg);
 	void(*triplebuffer_lock)(struct timing_generator *tg);
-- 
2.20.1



More information about the amd-gfx mailing list