drm/amd/display: disable PSR/ABM before destroy DMCU struct

[Why]
1. DMCU is not running on some platform but driver still send ABM
   command. It may cause assert due to DMCU is not alive.
2. To make sure PSR disable when driver disable

[How]
1. Add dmcu_is_running in ABM struct, driver can check this flag to
   determine driver should send ABM command or not.
2. Send PSR disable command when destroy PSR

Signed-off-by: Paul Hsieh <paul.hsieh@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Paul Hsieh 2019-05-07 17:58:58 +08:00 committed by Alex Deucher
parent e63e2491ad
commit 70d9e8cb8b
5 changed files with 24 additions and 2 deletions

View File

@ -58,6 +58,9 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id)
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
uint32_t rampingBoundary = 0xFFFF;
if (abm->dmcu_is_running == false)
return true;
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
1, 80000);
@ -302,6 +305,9 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level)
{
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
if (abm->dmcu_is_running == false)
return true;
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
1, 80000);
@ -320,6 +326,9 @@ static bool dce_abm_immediate_disable(struct abm *abm)
{
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
if (abm->dmcu_is_running == false)
return true;
dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY);
abm->stored_backlight_registers.BL_PWM_CNTL =
@ -443,6 +452,7 @@ static void dce_abm_construct(
base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
base->dmcu_is_running = false;
abm_dce->regs = regs;
abm_dce->abm_shift = abm_shift;
@ -473,7 +483,8 @@ void dce_abm_destroy(struct abm **abm)
{
struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
abm_dce->base.funcs->set_abm_immediate_disable(*abm);
if (abm_dce->base.dmcu_is_running == true)
abm_dce->base.funcs->set_abm_immediate_disable(*abm);
kfree(abm_dce);
*abm = NULL;

View File

@ -813,6 +813,9 @@ void dce_dmcu_destroy(struct dmcu **dmcu)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu);
if (dmcu_dce->base.dmcu_state == DMCU_RUNNING)
dmcu_dce->base.funcs->set_psr_enable(*dmcu, false, true);
kfree(dmcu_dce);
*dmcu = NULL;
}

View File

@ -2324,6 +2324,7 @@ static void init_hw(struct dc *dc)
struct dc_bios *bp;
struct transform *xfm;
struct abm *abm;
struct dmcu *dmcu;
bp = dc->ctx->dc_bios;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@ -2379,6 +2380,10 @@ static void init_hw(struct dc *dc)
abm->funcs->abm_init(abm);
}
dmcu = dc->res_pool->dmcu;
if (dmcu != NULL && abm != NULL)
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);

View File

@ -1146,6 +1146,9 @@ static void dcn10_init_hw(struct dc *dc)
if (dmcu != NULL)
dmcu->funcs->dmcu_init(dmcu);
if (abm != NULL && dmcu != NULL)
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
REG_WRITE(DIO_MEM_PWR_CTRL, 0);

View File

@ -37,7 +37,7 @@ struct abm_backlight_registers {
struct abm {
struct dc_context *ctx;
const struct abm_funcs *funcs;
bool dmcu_is_running;
/* registers setting needs to be saved and restored at InitBacklight */
struct abm_backlight_registers stored_backlight_registers;
};