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 <Wenjing.Liu@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:

committed by
Alex Deucher

parent
87029eb4fa
commit
db5378c1dc
@@ -727,10 +727,6 @@ enum dc_status dcn20_enable_stream_timing(
|
|||||||
pipe_ctx->stream->signal,
|
pipe_ctx->stream->signal,
|
||||||
true);
|
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 */
|
/* program otg blank color */
|
||||||
color_space = stream->output_color_space;
|
color_space = stream->output_color_space;
|
||||||
color_space_to_black_color(dc, color_space, &black_color);
|
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,
|
struct pipe_ctx *pipe,
|
||||||
bool lock)
|
bool lock)
|
||||||
{
|
{
|
||||||
if (lock)
|
if (lock) {
|
||||||
pipe->stream_res.tg->funcs->lock_global(pipe->stream_res.tg);
|
pipe->stream_res.tg->funcs->lock_doublebuffer_enable(
|
||||||
else
|
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->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(
|
static void dcn20_pipe_control_lock(
|
||||||
|
@@ -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);
|
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||||
uint32_t v_blank_start = 0;
|
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_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_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,
|
REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
|
||||||
MASTER_UPDATE_LOCK_DB_X,
|
MASTER_UPDATE_LOCK_DB_X,
|
||||||
0,
|
h_blank_start - 200 - 1,
|
||||||
MASTER_UPDATE_LOCK_DB_Y,
|
MASTER_UPDATE_LOCK_DB_Y,
|
||||||
v_blank_start - 1);
|
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);
|
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||||
|
|
||||||
REG_SET(OTG_GLOBAL_CONTROL1, 0, MASTER_UPDATE_LOCK_DB_EN, 1);
|
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, 1);
|
REG_UPDATE_2(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 0,
|
||||||
|
DIG_UPDATE_LOCATION, 0);
|
||||||
|
|
||||||
REG_SET(OTG_GLOBAL_CONTROL0, 0,
|
REG_UPDATE(OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_EN, 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(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_setup_manual_trigger(struct timing_generator *optc)
|
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_lock = optc2_triplebuffer_lock,
|
||||||
.triplebuffer_unlock = optc2_triplebuffer_unlock,
|
.triplebuffer_unlock = optc2_triplebuffer_unlock,
|
||||||
.disable_reset_trigger = optc1_disable_reset_trigger,
|
.disable_reset_trigger = optc1_disable_reset_trigger,
|
||||||
.lock = optc2_lock,
|
.lock = optc1_lock,
|
||||||
.unlock = optc1_unlock,
|
.unlock = optc1_unlock,
|
||||||
.lock_global = optc2_lock_global,
|
.lock_doublebuffer_enable = optc2_lock_doublebuffer_enable,
|
||||||
.setup_global_lock = optc2_setup_global_lock,
|
.lock_doublebuffer_disable = optc2_lock_doublebuffer_disable,
|
||||||
.enable_optc_clock = optc1_enable_optc_clock,
|
.enable_optc_clock = optc1_enable_optc_clock,
|
||||||
.set_drr = optc1_set_drr,
|
.set_drr = optc1_set_drr,
|
||||||
.set_static_screen_control = optc1_set_static_screen_control,
|
.set_static_screen_control = optc1_set_static_screen_control,
|
||||||
|
@@ -104,9 +104,8 @@ void optc2_get_optc_source(struct timing_generator *optc,
|
|||||||
|
|
||||||
void optc2_triplebuffer_lock(struct timing_generator *optc);
|
void optc2_triplebuffer_lock(struct timing_generator *optc);
|
||||||
void optc2_triplebuffer_unlock(struct timing_generator *optc);
|
void optc2_triplebuffer_unlock(struct timing_generator *optc);
|
||||||
void optc2_lock(struct timing_generator *optc);
|
void optc2_lock_doublebuffer_disable(struct timing_generator *optc);
|
||||||
void optc2_lock_global(struct timing_generator *optc);
|
void optc2_lock_doublebuffer_enable(struct timing_generator *optc);
|
||||||
void optc2_setup_global_lock(struct timing_generator *optc);
|
|
||||||
void optc2_program_manual_trigger(struct timing_generator *optc);
|
void optc2_program_manual_trigger(struct timing_generator *optc);
|
||||||
|
|
||||||
#endif /* __DC_OPTC_DCN20_H__ */
|
#endif /* __DC_OPTC_DCN20_H__ */
|
||||||
|
@@ -184,10 +184,10 @@ struct timing_generator_funcs {
|
|||||||
bool (*did_triggered_reset_occur)(struct timing_generator *tg);
|
bool (*did_triggered_reset_occur)(struct timing_generator *tg);
|
||||||
void (*setup_global_swap_lock)(struct timing_generator *tg,
|
void (*setup_global_swap_lock)(struct timing_generator *tg,
|
||||||
const struct dcp_gsl_params *gsl_params);
|
const struct dcp_gsl_params *gsl_params);
|
||||||
void (*setup_global_lock)(struct timing_generator *tg);
|
|
||||||
void (*unlock)(struct timing_generator *tg);
|
void (*unlock)(struct timing_generator *tg);
|
||||||
void (*lock)(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)
|
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||||
void(*triplebuffer_unlock)(struct timing_generator *tg);
|
void(*triplebuffer_unlock)(struct timing_generator *tg);
|
||||||
void(*triplebuffer_lock)(struct timing_generator *tg);
|
void(*triplebuffer_lock)(struct timing_generator *tg);
|
||||||
|
Reference in New Issue
Block a user