diff options
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.patch | 170 |
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 + |