Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm/disp/dpu: wait for extra vsync till timing engine status is disabled

There can be a race between timing gen disable and vblank irq. The
wait post timing gen disable may return early but intf disable sequence
might not be completed. Ensure that, intf status is disabled before
we retire the function.

Signed-off-by: Vinod Polimera <quic_vpolimer@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/524727/
Link: https://lore.kernel.org/r/1677774797-31063-7-git-send-email-quic_vpolimer@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

authored by

Vinod Polimera and committed by
Dmitry Baryshkov
8e1ff4bb e3969ead

+21
+21
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
··· 523 523 { 524 524 unsigned long lock_flags; 525 525 int ret; 526 + struct intf_status intf_status = {0}; 526 527 527 528 if (!phys_enc->parent || !phys_enc->parent->dev) { 528 529 DPU_ERROR("invalid encoder/device\n"); ··· 559 558 * scanout buffer) don't latch properly.. 560 559 */ 561 560 if (dpu_encoder_phys_vid_is_master(phys_enc)) { 561 + ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); 562 + if (ret) { 563 + atomic_set(&phys_enc->pending_kickoff_cnt, 0); 564 + DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", 565 + DRMID(phys_enc->parent), 566 + phys_enc->hw_intf->idx - INTF_0, ret); 567 + } 568 + } 569 + 570 + if (phys_enc->hw_intf && phys_enc->hw_intf->ops.get_status) 571 + phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &intf_status); 572 + 573 + /* 574 + * Wait for a vsync if timing en status is on after timing engine 575 + * is disabled. 576 + */ 577 + if (intf_status.is_en && dpu_encoder_phys_vid_is_master(phys_enc)) { 578 + spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 579 + dpu_encoder_phys_inc_pending(phys_enc); 580 + spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 562 581 ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); 563 582 if (ret) { 564 583 atomic_set(&phys_enc->pending_kickoff_cnt, 0);