Commit 5fdccd5b authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher

drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate

[WHY]
Every other CM LUT power down sequence is deferred to next vupdate as
memory powerdown updates immediately while selecting LUTs is double
buffered.  Previous update to defer LUT power down missed GAMCOR and
DSCL, causing some visible flicker when entering/exiting fullscreen
video playback.

[HOW]
Update dpp deferred update loop to check for valid DPPs in res_pool
instead of referencing dcn_ip which turns out to not be populated during
runtime.  Move GAMCOR and DSCL powerdown to dpp deferred updates.
Reviewed-by: default avatarHaonan Wang <Haonan.Wang2@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Acked-by: default avatarAgustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5ffb5267
...@@ -1897,12 +1897,14 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) ...@@ -1897,12 +1897,14 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
static void process_deferred_updates(struct dc *dc) static void process_deferred_updates(struct dc *dc)
{ {
#ifdef CONFIG_DRM_AMD_DC_DCN #ifdef CONFIG_DRM_AMD_DC_DCN
int i; int i = 0;
if (dc->debug.enable_mem_low_power.bits.cm) if (dc->debug.enable_mem_low_power.bits.cm) {
ASSERT(dc->dcn_ip->max_num_dpp);
for (i = 0; i < dc->dcn_ip->max_num_dpp; i++) for (i = 0; i < dc->dcn_ip->max_num_dpp; i++)
if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update) if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update)
dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]); dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]);
}
#endif #endif
} }
......
...@@ -205,9 +205,17 @@ static void dpp1_power_on_dscl( ...@@ -205,9 +205,17 @@ static void dpp1_power_on_dscl(
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) { if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) {
REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, power_on ? 0 : 3); if (power_on) {
if (power_on) REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0);
REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5); REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5);
} else {
if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) {
dpp->base.ctx->dc->optimized_required = true;
dpp->base.deferred_reg_writes.bits.disable_dscl = true;
} else {
REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
}
}
} }
} }
......
...@@ -494,6 +494,20 @@ void dpp3_deferred_update( ...@@ -494,6 +494,20 @@ void dpp3_deferred_update(
int bypass_state; int bypass_state;
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
if (dpp_base->deferred_reg_writes.bits.disable_dscl) {
REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
dpp_base->deferred_reg_writes.bits.disable_dscl = false;
}
if (dpp_base->deferred_reg_writes.bits.disable_gamcor) {
REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state);
if (bypass_state == 0) { // only program if bypass was latched
REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3);
} else
ASSERT(0); // LUT select was updated again before vupdate
dpp_base->deferred_reg_writes.bits.disable_gamcor = false;
}
if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) { if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state); REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
if (bypass_state == 0) { // only program if bypass was latched if (bypass_state == 0) { // only program if bypass was latched
......
...@@ -136,9 +136,13 @@ static void dpp3_power_on_gamcor_lut( ...@@ -136,9 +136,13 @@ static void dpp3_power_on_gamcor_lut(
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3); if (power_on) {
if (power_on) REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0);
REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5);
} else {
dpp_base->ctx->dc->optimized_required = true;
dpp_base->deferred_reg_writes.bits.disable_gamcor = true;
}
} else } else
REG_SET(CM_MEM_PWR_CTRL, 0, REG_SET(CM_MEM_PWR_CTRL, 0,
GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1);
......
...@@ -2460,6 +2460,8 @@ static bool dcn31_resource_construct( ...@@ -2460,6 +2460,8 @@ static bool dcn31_resource_construct(
dc->cap_funcs = cap_funcs; dc->cap_funcs = cap_funcs;
dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp;
DC_FP_END(); DC_FP_END();
return true; return true;
......
...@@ -34,6 +34,8 @@ union defer_reg_writes { ...@@ -34,6 +34,8 @@ union defer_reg_writes {
bool disable_blnd_lut:1; bool disable_blnd_lut:1;
bool disable_3dlut:1; bool disable_3dlut:1;
bool disable_shaper:1; bool disable_shaper:1;
bool disable_gamcor:1;
bool disable_dscl:1;
} bits; } bits;
uint32_t raw; uint32_t raw;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment