From baebfbe17bb22a540418fdf21dcd338b2299b679 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort Date: Tue, 26 Mar 2019 13:29:55 -0700 Subject: [PATCH] ANDROID: drm: kirin: remove wait for VACTIVE IRQ For each display cycle, the Kirin960 display IP will generate a VACTIVE interrupt followed by a VBLANK. During a FBIOPAN ioctl, the driver will then wait for the first one to then wait for the second one. This is an issue when the CPU load is too low: the wait_event() function might trigger a transition to a deep sleep state and then, waking up from that state will take too much time to catch the VBLANK interrupt on time, the difference between those two interrupts being only 60 us. * Ideal case: ACT VBL + + v v ---> wait(ACT) +------> wait(VBL) +--> * Our case: ACT VBL ACT VBL + + + + v v v v ---> wait(ACT) +------> wait(VBL) +--> The wait for VACTIVE IRQ can safely be removed: there is no hardware access performed between the VACTIVE and the VBLANK IRQs. This behavior has been introduced from 4.11 with the following patch: a3fbb53f4 drm/atomic: Wait for vblank whenever a plane is added to state. Bug: 146450171 Signed-off-by: Vincent Donnefort Signed-off-by: John Stultz Change-Id: I66e276c08f04257135c3d05483ce70c58d5070b6 --- .../gpu/drm/hisilicon/kirin/kirin_drm_dpe.c | 43 +------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c index c52314305f23..a15f8d452b13 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c @@ -76,9 +76,6 @@ struct dpe_hw_ctx { bool power_on; int irq; - wait_queue_head_t vactive0_end_wq; - u32 vactive0_end_flag; - struct drm_crtc *crtc; u32 hdisplay; @@ -278,7 +275,7 @@ static void dpe_interrupt_unmask(struct dpe_hw_ctx *ctx) writel(unmask, base + GLB_CPU_PDP_INT_MSK); unmask = ~0; - unmask &= ~(BIT_VSYNC | BIT_VACTIVE0_END | BIT_LDI_UNFLOW); + unmask &= ~(BIT_VSYNC | BIT_LDI_UNFLOW); writel(unmask, base + DPE_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK); } @@ -770,35 +767,6 @@ const struct drm_crtc_funcs dpe_crtc_funcs = { .disable_vblank = dpe_disable_vblank, }; -static int dpe_wait_for_complete(struct dpe_hw_ctx *ctx) -{ - int ret = 0; - u32 times = 0; - u32 prev_vactive0_end = ctx->vactive0_end_flag; - -REDO: - ret = wait_event_interruptible_timeout(ctx->vactive0_end_wq, - (prev_vactive0_end != ctx->vactive0_end_flag), - msecs_to_jiffies(300)); - if (ret == -ERESTARTSYS) { - if (times < 50) { - times++; - mdelay(10); - goto REDO; - } - } - - if (ret <= 0) { - DRM_ERROR("wait_for vactive0_end_flag timeout! ret=%d.\n", ret); - - ret = -ETIMEDOUT; - } else { - ret = 0; - } - - return ret; -} - static void dpe_unflow_handler(struct dpe_hw_ctx *ctx) { void __iomem *base = ctx->base; @@ -991,7 +959,6 @@ static void dpe_update_channel(struct kirin_plane *kplane, dpe_unflow_handler(ctx); dpe_enable_ldi(ctx); - dpe_wait_for_complete(ctx); } static void dpe_plane_atomic_update(struct drm_plane *plane, @@ -1097,11 +1064,6 @@ static irqreturn_t dpe_irq_handler(int irq, void *data) isr_s2 &= ~(readl(base + DPE_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK)); isr_s2_dpp &= ~(readl(base + DPE_DPP_OFFSET + DPP_INT_MSK)); - if (isr_s2 & BIT_VACTIVE0_END) { - ctx->vactive0_end_flag++; - wake_up_interruptible_all(&ctx->vactive0_end_wq); - } - if (isr_s2 & BIT_VSYNC) drm_crtc_handle_vblank(crtc); @@ -1202,9 +1164,6 @@ static void *dpe_hw_ctx_alloc(struct platform_device *pdev, disable_irq(ctx->irq); - ctx->vactive0_end_flag = 0; - init_waitqueue_head(&ctx->vactive0_end_wq); - return ctx; }