From db5378c1dcff3391dac42d714e6064c80702fa3d Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 28 Mar 2019 11:27:05 -0400 Subject: [PATCH] drm/amd/display: isolate global double buffer lock programming [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 Reviewed-by: Jun Lei Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- .../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.30.2