aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch170
1 files changed, 170 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch
new file mode 100644
index 00000000..c6a4b2fa
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2502-drm-amd-display-add-global-master-update-lock-for-DC.patch
@@ -0,0 +1,170 @@
+From 2b593b7c34424d6e62665667e89a5ea19da27457 Mon Sep 17 00:00:00 2001
+From: Wenjing Liu <Wenjing.Liu@amd.com>
+Date: Tue, 5 Mar 2019 19:28:10 -0500
+Subject: [PATCH 2502/2940] drm/amd/display: add global master update lock for
+ DCN2
+
+[why]
+when an update programming sequence requires both
+front end and back end pipe to be updated synchronously,
+a global update lock needs to be set to ensure that
+we don't get a frame with only front end update but
+not the back end update.
+
+[how]
+setup global lock parameters on enable_stream_timing.
+enable global lock when pipe_control_lock_global is called.
+disable global lock when pipe_control_lock is called.
+
+Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++
+ .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 63 ++++++++++++++++++-
+ .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.h | 3 +
+ .../amd/display/dc/inc/hw/timing_generator.h | 2 +
+ .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 1 +
+ 5 files changed, 72 insertions(+), 1 deletion(-)
+
+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 dc34ce28505c..fbcb4d860e7a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -727,6 +727,10 @@ 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);
+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 43e71b4ab5e8..ea6a19063b22 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
+@@ -330,6 +330,65 @@ void optc2_triplebuffer_unlock(struct timing_generator *optc)
+
+ }
+
++
++void optc2_setup_global_lock(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;
++
++ REG_SET(OTG_GLOBAL_CONTROL1, 0, MASTER_UPDATE_LOCK_DB_EN, 1);
++
++ REG_SET(OTG_GLOBAL_CONTROL2, 0, 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,
++ h_blank_start - 200 - 1,
++ MASTER_UPDATE_LOCK_DB_Y,
++ v_blank_start - 1);
++}
++
++void optc2_lock_global(struct timing_generator *optc)
++{
++ struct optc *optc1 = DCN10TG_FROM_TG(optc);
++
++ 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_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 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);
++}
++
+ void optc2_lock_doublebuffer_enable(struct timing_generator *optc)
+ {
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+@@ -424,8 +483,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 = optc1_lock,
++ .lock = optc2_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,
+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 d2651d846424..a21781332a06 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
+@@ -104,6 +104,9 @@ 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);
+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 75314de83b3e..2dee10f7f1fe 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,8 +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)
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index a0227dedbdf6..13b113d0fe19 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -205,6 +205,7 @@ struct hw_sequencer_funcs {
+ struct dc *dc,
+ struct pipe_ctx *pipe,
+ bool lock);
++
+ void (*pipe_control_lock_global)(
+ struct dc *dc,
+ struct pipe_ctx *pipe,
+--
+2.17.1
+