diff --git a/drivers/gpu/drm/msm/shd/sde_encoder_phys_shd.c b/drivers/gpu/drm/msm/shd/sde_encoder_phys_shd.c index d1f9fec8eef7..e3f87fbb8fe8 100644 --- a/drivers/gpu/drm/msm/shd/sde_encoder_phys_shd.c +++ b/drivers/gpu/drm/msm/shd/sde_encoder_phys_shd.c @@ -103,6 +103,15 @@ static void sde_encoder_phys_shd_vblank_irq(void *arg, int irq_idx) if (flush_register & shd_ctl->flush_mask) goto not_flushed; + /* + * When flush_mask is changed to 0, we need additional vsync + * to make sure the detach flush is done + */ + if (flush_register && !shd_ctl->flush_mask && shd_ctl->old_mask) { + shd_ctl->old_mask = 0; + goto not_flushed; + } + new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)) diff --git a/drivers/gpu/drm/msm/shd/shd_hw.c b/drivers/gpu/drm/msm/shd/shd_hw.c index ea756f0a9a10..583a06664b80 100644 --- a/drivers/gpu/drm/msm/shd/shd_hw.c +++ b/drivers/gpu/drm/msm/shd/shd_hw.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -256,6 +256,8 @@ static void _sde_shd_flush_hw_ctl(struct sde_hw_ctl *ctx) hw_ctl = container_of(ctx, struct sde_shd_hw_ctl, base); + hw_ctl->old_mask = hw_ctl->flush_mask; + hw_ctl->flush_mask = ctx->flush.pending_flush_mask; hw_ctl->flush_mask &= CTL_SSPP_FLUSH_MASK; diff --git a/drivers/gpu/drm/msm/shd/shd_hw.h b/drivers/gpu/drm/msm/shd/shd_hw.h index 04a5424778c8..18142610a6b6 100644 --- a/drivers/gpu/drm/msm/shd/shd_hw.h +++ b/drivers/gpu/drm/msm/shd/shd_hw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,7 @@ struct sde_shd_hw_ctl { struct shd_stage_range range; struct sde_hw_ctl *orig; u32 flush_mask; + u32 old_mask; struct sde_shd_ctl_mixer_cfg mixer_cfg[MAX_BLOCKS]; };