From d5863057416b123e4d797dd4e8efa0357bf2373b 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. Signed-off-by: Vincent Donnefort Signed-off-by: John Stultz Bug: 146450171 Change-Id: I66e276c08f04257135c3d05483ce70c58d5070b6 --- .../gpu/drm/hisilicon/kirin/kirin_drm_dpe.c | 44 +------------------ 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c index 3a2023962a7c..0c8d1811919a 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dpe.c @@ -74,9 +74,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; @@ -274,7 +271,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); } @@ -765,36 +762,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; @@ -983,7 +950,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, @@ -1088,11 +1054,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); @@ -1193,9 +1154,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; }