[PATCH 4/3] drm: hikey9xx: remove wait for VACTIVE IRQ
From: John Stultz
Date: Wed Aug 19 2020 - 23:56:40 EST
From: Vincent Donnefort <vincent.donnefort@xxxxxxx>
A quick add-on to my earlier fixup series as I realized what the
performance problem was.
This is against Mauro's tree here:
https://gitlab.freedesktop.org/mchehab_kernel/hikey-970/-/commits/master/
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.
Cc: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Manivannan Sadhasivam <mani@xxxxxxxxxx>
Cc: dri-devel <dri-devel@xxxxxxxxxxxxxxxxxxxxx>
Cc: Liwei Cai <cailiwei@xxxxxxxxxxxxx>
Cc: Xinliang Liu <xinliang.liu@xxxxxxxxxx>
Cc: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
Cc: Sam Ravnborg <sam@xxxxxxxxxxxx>
Cc: Sumit Semwal <sumit.semwal@xxxxxxxxxx>
Cc: Chen Feng <puck.chen@xxxxxxxxxxxxx>
Signed-off-by: Vincent Donnefort <vincent.donnefort@xxxxxxx>
[jstultz: hand-ported to Mauro's patch set]
Signed-off-by: John Stultz <john.stultz@xxxxxxxxxx>
---
.../hikey9xx/gpu/kirin9xx_drm_dpe_utils.c | 2 +-
.../staging/hikey9xx/gpu/kirin9xx_drm_dss.c | 5 ---
.../hikey9xx/gpu/kirin9xx_drm_overlay_utils.c | 36 -------------------
3 files changed, 1 insertion(+), 42 deletions(-)
diff --git a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dpe_utils.c b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dpe_utils.c
index 82a0edb95953..cc80689d90c9 100644
--- a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dpe_utils.c
+++ b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dpe_utils.c
@@ -582,7 +582,7 @@ void dpe_interrupt_unmask(struct dss_crtc *acrtc)
writel(unmask, dss_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, dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK);
}
diff --git a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dss.c b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dss.c
index 7adbd924bec2..c99ce7c4d479 100644
--- a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dss.c
+++ b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_dss.c
@@ -440,11 +440,6 @@ static irqreturn_t dss_irq_handler(int irq, void *data)
isr_s1 &= ~(readl(dss_base + GLB_CPU_PDP_INT_MSK));
isr_s2 &= ~(readl(dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_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) {
ctx->vsync_timestamp = ktime_get();
drm_crtc_handle_vblank(crtc);
diff --git a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_overlay_utils.c b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_overlay_utils.c
index 5ac7f4b31d99..932bad2f428e 100644
--- a/drivers/staging/hikey9xx/gpu/kirin9xx_drm_overlay_utils.c
+++ b/drivers/staging/hikey9xx/gpu/kirin9xx_drm_overlay_utils.c
@@ -822,40 +822,6 @@ void hisifb_mctl_sw_clr(struct dss_crtc *acrtc)
DRM_INFO("-.\n");
}
-static int hisi_dss_wait_for_complete(struct dss_crtc *acrtc)
-{
- int ret = 0;
- u32 times = 0;
- u32 prev_vactive0_end = 0;
- struct dss_hw_ctx *ctx = acrtc->ctx;
-
- 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) {
- disable_ldi(acrtc);
- hisifb_mctl_sw_clr(acrtc);
- DRM_ERROR("wait_for vactive0_end_flag timeout! ret=%d.\n", ret);
-
- ret = -ETIMEDOUT;
- } else {
- ret = 0;
- }
-
- return ret;
-}
-
void hisi_fb_pan_display(struct drm_plane *plane)
{
struct drm_plane_state *state = plane->state;
@@ -932,7 +898,6 @@ void hisi_fb_pan_display(struct drm_plane *plane)
hisi_dss_unflow_handler(ctx, true);
enable_ldi(acrtc);
- hisi_dss_wait_for_complete(acrtc);
}
void hisi_dss_online_play(struct kirin_fbdev *fbdev, struct drm_plane *plane,
@@ -1001,5 +966,4 @@ void hisi_dss_online_play(struct kirin_fbdev *fbdev, struct drm_plane *plane,
hisi_dss_unflow_handler(ctx, true);
enable_ldi(acrtc);
- hisi_dss_wait_for_complete(acrtc);
}
--
2.17.1